From 6696b675aea299dfcbeba793cfae25a02a57975a Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Sun, 10 Jul 2016 11:55:29 -0700 Subject: [PATCH] Display all file attributes. --- source/core/util.c | 4 +- source/ui/error.c | 2 + source/ui/section/action/installcias.c | 2 +- source/ui/section/action/installtickets.c | 2 +- source/ui/section/action/pastefiles.c | 24 +++--------- source/ui/section/action/rename.c | 2 +- source/ui/section/files.c | 8 ++-- source/ui/section/task/listfiles.c | 13 ++++--- source/ui/section/task/task.h | 2 +- source/ui/ui.c | 46 +++++++++++++++++++++-- 10 files changed, 69 insertions(+), 36 deletions(-) diff --git a/source/core/util.c b/source/core/util.c index 9dfa48f..bd9d44d 100644 --- a/source/core/util.c +++ b/source/core/util.c @@ -406,9 +406,9 @@ int util_compare_file_infos(const void** p1, const void** p2) { file_info* f1 = (file_info*) info1->data; file_info* f2 = (file_info*) info2->data; - if(f1->isDirectory && !f2->isDirectory) { + if((f1->attributes & FS_ATTRIBUTE_DIRECTORY) && !(f2->attributes & FS_ATTRIBUTE_DIRECTORY)) { return -1; - } else if(!f1->isDirectory && f2->isDirectory) { + } else if(!(f1->attributes & FS_ATTRIBUTE_DIRECTORY) && (f2->attributes & FS_ATTRIBUTE_DIRECTORY)) { return 1; } else { return strncasecmp(f1->name, f2->name, FILE_NAME_MAX); diff --git a/source/ui/error.c b/source/ui/error.c index 057caa6..9d9968d 100644 --- a/source/ui/error.c +++ b/source/ui/error.c @@ -323,6 +323,8 @@ static const char* description_to_string(Result res) { return "Illegal operation / File in use"; case 231: return "Resource locked"; + case 250: + return "FAT operation denied"; case 265: return "Bus: Timeout"; case 331: diff --git a/source/ui/section/action/installcias.c b/source/ui/section/action/installcias.c index 538d9e7..639ed0d 100644 --- a/source/ui/section/action/installcias.c +++ b/source/ui/section/action/installcias.c @@ -312,7 +312,7 @@ static void action_install_cias_internal(linked_list* items, list_item* selected popData.archive = data->target->archive; strncpy(popData.path, data->target->path, FILE_PATH_MAX); popData.recursive = false; - popData.includeBase = !data->target->isDirectory; + popData.includeBase = !(data->target->attributes & FS_ATTRIBUTE_DIRECTORY); popData.filter = util_filter_cias; popData.filterData = NULL; diff --git a/source/ui/section/action/installtickets.c b/source/ui/section/action/installtickets.c index 810347c..46376c1 100644 --- a/source/ui/section/action/installtickets.c +++ b/source/ui/section/action/installtickets.c @@ -275,7 +275,7 @@ static void action_install_tickets_internal(linked_list* items, list_item* selec popData.archive = data->target->archive; strncpy(popData.path, data->target->path, FILE_PATH_MAX); popData.recursive = false; - popData.includeBase = !data->target->isDirectory; + popData.includeBase = !(data->target->attributes & FS_ATTRIBUTE_DIRECTORY); popData.filter = util_filter_tickets; popData.filterData = NULL; diff --git a/source/ui/section/action/pastefiles.c b/source/ui/section/action/pastefiles.c index 9770a24..0b1ce26 100644 --- a/source/ui/section/action/pastefiles.c +++ b/source/ui/section/action/pastefiles.c @@ -46,7 +46,7 @@ static void action_paste_files_get_dst_path(paste_files_data* data, u32 index, c } char baseDstPath[FILE_PATH_MAX]; - if(data->target->isDirectory) { + 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); @@ -58,7 +58,7 @@ static void action_paste_files_get_dst_path(paste_files_data* data, u32 index, c static Result action_paste_files_is_src_directory(void* data, u32 index, bool* isDirectory) { paste_files_data* pasteData = (paste_files_data*) data; - *isDirectory = ((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->isDirectory; + *isDirectory = (bool) (((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->attributes & FS_ATTRIBUTE_DIRECTORY); return 0; } @@ -75,7 +75,7 @@ static Result action_paste_files_make_dst_directory(void* data, u32 index) { util_get_parent_path(parentPath, dstPath, FILE_PATH_MAX); char baseDstPath[FILE_PATH_MAX]; - if(pasteData->target->isDirectory) { + 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); @@ -164,7 +164,7 @@ static Result action_paste_files_close_dst(void* data, u32 index, bool succeeded util_get_parent_path(parentPath, dstPath, FILE_PATH_MAX); char baseDstPath[FILE_PATH_MAX]; - if(pasteData->target->isDirectory) { + 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); @@ -312,21 +312,12 @@ void action_paste_contents(linked_list* items, list_item* selected) { data->pasteInfo.finished = true; - list_item* clipboardItem = NULL; - Result createRes = 0; - if(R_FAILED(createRes = task_create_file_item(&clipboardItem, clipboard_get_archive(), clipboard_get_path()))) { - error_display_res(NULL, NULL, createRes, "Failed to retrieve clipboard content info."); - - action_paste_files_free_data(data); - return; - } - linked_list_init(&data->contents); populate_files_data popData; popData.items = &data->contents; - popData.archive = ((file_info*) clipboardItem->data)->archive; - strncpy(popData.path, ((file_info*) clipboardItem->data)->path, FILE_PATH_MAX); + popData.archive = clipboard_get_archive(); + strncpy(popData.path, clipboard_get_path(), FILE_PATH_MAX); popData.recursive = true; popData.includeBase = !clipboard_is_contents_only() || !util_is_dir(clipboard_get_archive(), clipboard_get_path()); popData.filter = NULL; @@ -336,7 +327,6 @@ void action_paste_contents(linked_list* items, list_item* selected) { if(R_FAILED(listRes)) { error_display_res(NULL, NULL, listRes, "Failed to initiate clipboard content list population."); - task_free_file(clipboardItem); action_paste_files_free_data(data); return; } @@ -345,8 +335,6 @@ void action_paste_contents(linked_list* items, list_item* selected) { svcSleepThread(1000000); } - task_free_file(clipboardItem); - if(R_FAILED(popData.result)) { error_display_res(NULL, NULL, popData.result, "Failed to populate clipboard content list."); diff --git a/source/ui/section/action/rename.c b/source/ui/section/action/rename.c index cd62f1f..afbf371 100644 --- a/source/ui/section/action/rename.c +++ b/source/ui/section/action/rename.c @@ -38,7 +38,7 @@ void action_rename(linked_list* items, list_item* selected) { if(srcFsPath != NULL) { FS_Path* dstFsPath = util_make_path_utf8(dstPath); if(dstFsPath != NULL) { - if(targetInfo->isDirectory) { + if(targetInfo->attributes & FS_ATTRIBUTE_DIRECTORY) { res = FSUSER_RenameDirectory(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath); } else { res = FSUSER_RenameFile(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath); diff --git a/source/ui/section/files.c b/source/ui/section/files.c index 9e6d236..4c423b8 100644 --- a/source/ui/section/files.c +++ b/source/ui/section/files.c @@ -95,7 +95,7 @@ static void files_action_update(ui_view* view, void* data, linked_list* items, l Result res = 0; if(R_SUCCEEDED(res = clipboard_set_contents(actionData->parent->archive, info->path, selected == ©_all_contents))) { - prompt_display("Success", selected == ©_all_contents ? "Current directory contents copied to clipboard." : info->isDirectory ? "Current directory copied to clipboard." : "File copied to clipboard.", COLOR_TEXT, false, info, ui_draw_file_info, NULL); + prompt_display("Success", selected == ©_all_contents ? "Current directory contents copied to clipboard." : (info->attributes & FS_ATTRIBUTE_DIRECTORY) ? "Current directory copied to clipboard." : "File copied to clipboard.", COLOR_TEXT, false, info, ui_draw_file_info, NULL); } else { error_display_res(info, ui_draw_file_info, res, "Failed to copy to clipboard."); } @@ -111,7 +111,7 @@ static void files_action_update(ui_view* view, void* data, linked_list* items, l if(linked_list_size(items) == 0) { file_info* info = (file_info*) actionData->selected->data; - if(info->isDirectory) { + if(info->attributes & FS_ATTRIBUTE_DIRECTORY) { if(actionData->containsCias) { linked_list_add(items, &install_all_cias); linked_list_add(items, &install_and_delete_all_cias); @@ -178,7 +178,7 @@ static void files_action_open(linked_list* items, list_item* selected, files_dat } } - list_display(((file_info*) selected->data)->isDirectory ? "Directory Action" : "File Action", "A: Select, B: Return", data, files_action_update, files_action_draw_top); + list_display((((file_info*) selected->data)->attributes & FS_ATTRIBUTE_DIRECTORY) ? "Directory Action" : "File Action", "A: Select, B: Return", data, files_action_update, files_action_draw_top); } static void files_filters_add_entry(linked_list* items, const char* name, bool* val) { @@ -329,7 +329,7 @@ static void files_update(ui_view* view, void* data, linked_list* items, list_ite if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { file_info* fileInfo = (file_info*) selected->data; - if(fileInfo->isDirectory && strncmp(selected->name, "", LIST_ITEM_NAME_MAX) != 0) { + if((fileInfo->attributes & FS_ATTRIBUTE_DIRECTORY) && strncmp(selected->name, "", LIST_ITEM_NAME_MAX) != 0) { files_navigate(listData, items, fileInfo->path); } else { files_action_open(items, selected, listData); diff --git a/source/ui/section/task/listfiles.c b/source/ui/section/task/listfiles.c index 05e91b6..58e9462 100644 --- a/source/ui/section/task/listfiles.c +++ b/source/ui/section/task/listfiles.c @@ -23,8 +23,11 @@ Result task_create_file_item(list_item** out, FS_Archive archive, const char* pa if(fileInfo != NULL) { fileInfo->archive = archive; util_get_path_file(fileInfo->name, path, FILE_NAME_MAX); + fileInfo->attributes = 0; + fileInfo->size = 0; fileInfo->isCia = false; + fileInfo->isTicket = false; if(util_is_dir(archive, path)) { item->color = COLOR_DIRECTORY; @@ -36,17 +39,17 @@ Result task_create_file_item(list_item** out, FS_Archive archive, const char* pa strncpy(fileInfo->path, path, FILE_PATH_MAX); } - fileInfo->isDirectory = true; + fileInfo->attributes = FS_ATTRIBUTE_DIRECTORY; } else { item->color = COLOR_FILE; strncpy(fileInfo->path, path, FILE_PATH_MAX); - fileInfo->isDirectory = false; FS_Path* fileFsPath = util_make_path_utf8(fileInfo->path); if(fileFsPath != NULL) { Handle fileHandle; if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, archive, *fileFsPath, FS_OPEN_READ, 0))) { + FSFILE_GetAttributes(fileHandle, &fileInfo->attributes); FSFILE_GetSize(fileHandle, &fileInfo->size); size_t len = strlen(fileInfo->path); @@ -149,7 +152,7 @@ static void task_populate_files_thread(void* arg) { list_item* baseItem = NULL; if(R_SUCCEEDED(res = task_create_file_item(&baseItem, data->archive, data->path))) { file_info* baseInfo = (file_info*) baseItem->data; - if(baseInfo->isDirectory) { + if(baseInfo->attributes & FS_ATTRIBUTE_DIRECTORY) { strncpy(baseItem->name, "", LIST_ITEM_NAME_MAX); } else { strncpy(baseItem->name, "", LIST_ITEM_NAME_MAX); @@ -171,7 +174,7 @@ static void task_populate_files_thread(void* arg) { linked_list_add(data->items, currItem); } - if(curr->isDirectory) { + if(curr->attributes & FS_ATTRIBUTE_DIRECTORY) { FS_Path* fsPath = util_make_path_utf8(curr->path); if(fsPath != NULL) { Handle dirHandle = 0; @@ -198,7 +201,7 @@ static void task_populate_files_thread(void* arg) { list_item* item = NULL; if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path))) { - if(data->recursive && ((file_info*) item->data)->isDirectory) { + if(data->recursive && (((file_info*) item->data)->attributes & FS_ATTRIBUTE_DIRECTORY)) { linked_list_add(&queue, item); } else { linked_list_add(data->items, item); diff --git a/source/ui/section/task/task.h b/source/ui/section/task/task.h index ab949e3..6a23a77 100644 --- a/source/ui/section/task/task.h +++ b/source/ui/section/task/task.h @@ -58,7 +58,7 @@ typedef struct file_info_s { FS_Archive archive; char name[FILE_NAME_MAX]; char path[FILE_PATH_MAX]; - bool isDirectory; + u32 attributes; // Files only u64 size; diff --git a/source/ui/ui.c b/source/ui/ui.c index c9c92a4..22a45d0 100644 --- a/source/ui/ui.c +++ b/source/ui/ui.c @@ -400,7 +400,49 @@ void ui_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2, infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Name: %.48s\n", info->name); } - if(!info->isDirectory) { + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Attributes: "); + + if(info->attributes & (FS_ATTRIBUTE_DIRECTORY | FS_ATTRIBUTE_HIDDEN | FS_ATTRIBUTE_ARCHIVE | FS_ATTRIBUTE_READ_ONLY)) { + bool needsSeparator = false; + + if(info->attributes & FS_ATTRIBUTE_DIRECTORY) { + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Directory"); + needsSeparator = true; + } + + if(info->attributes & FS_ATTRIBUTE_HIDDEN) { + if(needsSeparator) { + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, ", "); + } + + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Hidden"); + needsSeparator = true; + } + + if(info->attributes & FS_ATTRIBUTE_ARCHIVE) { + if(needsSeparator) { + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, ", "); + } + + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Archive"); + needsSeparator = true; + } + + if(info->attributes & FS_ATTRIBUTE_READ_ONLY) { + if(needsSeparator) { + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, ", "); + } + + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Read Only"); + needsSeparator = true; + } + } else { + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "None"); + } + + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "\n"); + + if(!(info->attributes & FS_ATTRIBUTE_DIRECTORY)) { infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Size: %.2f %s\n", util_get_display_size(info->size), util_get_display_size_units(info->size)); if(info->isCia) { @@ -460,8 +502,6 @@ void ui_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2, } else if(info->isTicket) { infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Ticket ID: %016llX", info->ticketInfo.titleId); } - } else { - infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Directory"); } float infoWidth;