static Result action_paste_files_make_dst_directory(void* data, u32 index) { paste_files_data* pasteData = (paste_files_data*) data; Result res = 0; char dstPath[FILE_PATH_MAX]; action_paste_files_get_dst_path(pasteData, index, dstPath); if(R_SUCCEEDED(res = util_ensure_dir(pasteData->target->archive, dstPath))) { char parentPath[FILE_PATH_MAX]; util_get_parent_path(parentPath, dstPath, FILE_PATH_MAX); char baseDstPath[FILE_PATH_MAX]; if(pasteData->target->attributes & FS_ATTRIBUTE_DIRECTORY) { strncpy(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } else { util_get_parent_path(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } if(strncmp(parentPath, baseDstPath, FILE_PATH_MAX) == 0) { list_item* dstItem = NULL; if(R_SUCCEEDED(res) && R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath))) { linked_list_add(pasteData->items, dstItem); } } } return res; }
static Result action_paste_files_close_dst(void* data, u32 index, bool succeeded, u32 handle) { paste_files_data* pasteData = (paste_files_data*) data; Result res = 0; if(R_SUCCEEDED(res = FSFILE_Close(handle))) { char dstPath[FILE_PATH_MAX]; action_paste_files_get_dst_path(pasteData, index, dstPath); char parentPath[FILE_PATH_MAX]; util_get_parent_path(parentPath, dstPath, FILE_PATH_MAX); char baseDstPath[FILE_PATH_MAX]; if(pasteData->target->attributes & FS_ATTRIBUTE_DIRECTORY) { strncpy(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } else { util_get_parent_path(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } if(strncmp(parentPath, baseDstPath, FILE_PATH_MAX) == 0) { list_item* dstItem = NULL; if(R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath, ((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->attributes & ~FS_ATTRIBUTE_READ_ONLY))) { linked_list_add(pasteData->items, dstItem); } } } return res; }
static void files_repopulate(files_data* listData) { if(listData->cancelEvent != 0) { svcSignalEvent(listData->cancelEvent); while(svcWaitSynchronization(listData->cancelEvent, 0) == 0) { svcSleepThread(1000000); } listData->cancelEvent = 0; } while(!util_is_dir(&listData->archive, listData->currDir.path)) { char parentPath[PATH_MAX]; util_get_parent_path(parentPath, listData->currDir.path, PATH_MAX); strncpy(listData->currDir.path, parentPath, PATH_MAX); util_get_path_file(listData->currDir.name, listData->currDir.path, NAME_MAX); util_get_parent_path(parentPath, listData->currDir.path, PATH_MAX); strncpy(listData->parentDir.path, parentPath, PATH_MAX); util_get_path_file(listData->parentDir.name, listData->parentDir.path, NAME_MAX); } listData->cancelEvent = task_populate_files(listData->items, &listData->count, FILES_MAX, &listData->currDir); listData->populated = true; }
static void files_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { files_data* listData = (files_data*) data; while(!util_is_dir(listData->archive, listData->currDir)) { char parentDir[FILE_PATH_MAX] = {'\0'}; util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX); files_navigate(listData, items, parentDir); } if(hidKeysDown() & KEY_B) { if(strncmp(listData->currDir, "/", FILE_PATH_MAX) == 0) { ui_pop(); files_free_data(listData); task_clear_files(items); list_destroy(view); return; } else { char parentDir[FILE_PATH_MAX] = {'\0'}; util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX); files_navigate(listData, items, parentDir); } } if(hidKeysDown() & KEY_SELECT) { files_filters_open(listData); return; } if((hidKeysDown() & KEY_Y) && listData->dirItem != NULL) { files_action_open(items, listData->dirItem, listData); return; } if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { file_info* fileInfo = (file_info*) selected->data; if(fileInfo->isDirectory) { files_navigate(listData, items, fileInfo->path); } else { files_action_open(items, selected, listData); return; } } if(!listData->populated || (hidKeysDown() & KEY_X)) { files_repopulate(listData, items); } if(listData->populateData.finished && R_FAILED(listData->populateData.result)) { error_display_res(NULL, NULL, NULL, listData->populateData.result, "Failed to populate file list."); listData->populateData.result = 0; } }
static void action_paste_files_get_dst_path(paste_files_data* data, u32 index, char* dstPath) { char baseSrcPath[FILE_PATH_MAX]; if(clipboard_is_contents_only()) { strncpy(baseSrcPath, clipboard_get_path(), FILE_PATH_MAX); } else { util_get_parent_path(baseSrcPath, clipboard_get_path(), FILE_PATH_MAX); } char baseDstPath[FILE_PATH_MAX]; if(data->target->attributes & FS_ATTRIBUTE_DIRECTORY) { strncpy(baseDstPath, data->target->path, FILE_PATH_MAX); } else { util_get_parent_path(baseDstPath, data->target->path, FILE_PATH_MAX); } snprintf(dstPath, FILE_PATH_MAX, "%s%s", baseDstPath, ((file_info*) ((list_item*) linked_list_get(&data->contents, index))->data)->path + strlen(baseSrcPath)); }
static Result action_paste_files_make_dst_directory(void* data, u32 index) { paste_files_data* pasteData = (paste_files_data*) data; Result res = 0; u32 attributes = ((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->attributes; char dstPath[FILE_PATH_MAX]; action_paste_files_get_dst_path(pasteData, index, dstPath); FS_Path* fsPath = util_make_path_utf8(dstPath); if(fsPath != NULL) { Handle dirHandle = 0; if(R_SUCCEEDED(FSUSER_OpenDirectory(&dirHandle, pasteData->target->archive, *fsPath))) { FSDIR_Close(dirHandle); } else { res = FSUSER_CreateDirectory(pasteData->target->archive, *fsPath, attributes); } util_free_path_utf8(fsPath); } else { res = R_FBI_OUT_OF_MEMORY; } if(R_SUCCEEDED(res)) { char parentPath[FILE_PATH_MAX]; util_get_parent_path(parentPath, dstPath, FILE_PATH_MAX); char baseDstPath[FILE_PATH_MAX]; if(pasteData->target->attributes & FS_ATTRIBUTE_DIRECTORY) { strncpy(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } else { util_get_parent_path(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } if(strncmp(parentPath, baseDstPath, FILE_PATH_MAX) == 0) { list_item* dstItem = NULL; if(R_SUCCEEDED(res) && R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath, attributes))) { linked_list_add(pasteData->items, dstItem); } } } return res; }
static void files_navigate(files_data* listData, const char* path) { strncpy(listData->currDir.path, path, PATH_MAX); util_get_path_file(listData->currDir.name, listData->currDir.path, NAME_MAX); char parentPath[PATH_MAX]; util_get_parent_path(parentPath, listData->currDir.path, PATH_MAX); strncpy(listData->parentDir.path, parentPath, PATH_MAX); util_get_path_file(listData->parentDir.name, listData->parentDir.path, NAME_MAX); files_repopulate(listData); }
static void action_rename_kbd_finished(void* data, char* input) { rename_data* renameData = (rename_data*) data; if(strlen(input) == 0) { error_display(NULL, NULL, NULL, "No name specified."); } file_info* targetInfo = (file_info*) renameData->target->data; Result res = 0; char parentPath[FILE_PATH_MAX] = {'\0'}; util_get_parent_path(parentPath, targetInfo->path, FILE_PATH_MAX); char dstPath[FILE_PATH_MAX] = {'\0'}; snprintf(dstPath, FILE_PATH_MAX, "%s%s", parentPath, input); FS_Path* srcFsPath = util_make_path_utf8(targetInfo->path); if(srcFsPath != NULL) { FS_Path* dstFsPath = util_make_path_utf8(dstPath); if(dstFsPath != NULL) { if(targetInfo->isDirectory) { res = FSUSER_RenameDirectory(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath); } else { res = FSUSER_RenameFile(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath); } util_free_path_utf8(dstFsPath); } else { res = R_FBI_OUT_OF_MEMORY; } util_free_path_utf8(srcFsPath); } else { res = R_FBI_OUT_OF_MEMORY; } if(R_SUCCEEDED(res)) { if(strncmp(renameData->target->name, "<current directory>", LIST_ITEM_NAME_MAX) != 0 && strncmp(renameData->target->name, "<current file>", LIST_ITEM_NAME_MAX) != 0) { strncpy(renameData->target->name, input, LIST_ITEM_NAME_MAX); } strncpy(targetInfo->name, input, FILE_NAME_MAX); strncpy(targetInfo->path, dstPath, FILE_PATH_MAX); linked_list_sort(renameData->items, util_compare_file_infos); prompt_display("Success", "Renamed.", COLOR_TEXT, false, NULL, NULL, NULL); } else { error_display_res(NULL, NULL, NULL, res, "Failed to perform rename."); } free(data); }
static void files_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) { files_data* listData = (files_data*) data; if(listData->populated) { // Detect whether the current directory was renamed by an action. list_item* currDirItem = linked_list_get(items, 0); if(currDirItem != NULL && strncmp(listData->currDir, ((file_info*) currDirItem->data)->path, FILE_PATH_MAX) != 0) { strncpy(listData->currDir, ((file_info*) currDirItem->data)->path, FILE_PATH_MAX); } } while(!util_is_dir(listData->archive, listData->currDir)) { char parentDir[FILE_PATH_MAX] = {'\0'}; util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX); files_navigate(listData, items, parentDir); } if(hidKeysDown() & KEY_B) { if(strncmp(listData->currDir, "/", FILE_PATH_MAX) == 0) { ui_pop(); files_free_data(listData); task_clear_files(items); list_destroy(view); return; } else { char parentDir[FILE_PATH_MAX] = {'\0'}; util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX); files_navigate(listData, items, parentDir); } } if(hidKeysDown() & KEY_SELECT) { files_filters_open(listData); return; } if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { file_info* fileInfo = (file_info*) selected->data; if((fileInfo->attributes & FS_ATTRIBUTE_DIRECTORY) && strncmp(selected->name, "<current directory>", LIST_ITEM_NAME_MAX) != 0) { files_navigate(listData, items, fileInfo->path); } else { files_action_open(items, selected, listData); return; } } if(!listData->populated || (hidKeysDown() & KEY_X)) { files_repopulate(listData, items); } if(listData->populateData.finished && R_FAILED(listData->populateData.result)) { error_display_res(NULL, NULL, listData->populateData.result, "Failed to populate file list."); listData->populateData.result = 0; } }