diff --git a/source/ui/section/files.c b/source/ui/section/files.c index 261aab3..999e1b0 100644 --- a/source/ui/section/files.c +++ b/source/ui/section/files.c @@ -22,7 +22,9 @@ typedef struct { FS_Archive archive; void* archivePath; - char path[PATH_MAX]; + + file_info currDir; + file_info parentDir; } files_data; #define FILES_ACTION_COUNT 3 @@ -153,22 +155,39 @@ static void files_repopulate(files_data* listData) { listData->cancelEvent = 0; } - if(!util_is_dir(&listData->archive, listData->path)) { + while(!util_is_dir(&listData->archive, listData->currDir.path)) { char parentPath[PATH_MAX]; - util_get_parent_path(parentPath, listData->path, PATH_MAX); - strncpy(listData->path, 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->archive, listData->path); + listData->cancelEvent = task_populate_files(listData->items, &listData->count, FILES_MAX, &listData->currDir); listData->populated = true; } +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 files_update(ui_view* view, void* data, list_item** items, u32** itemCount, list_item* selected, bool selectedTouched) { files_data* listData = (files_data*) data; if(hidKeysDown() & KEY_B) { - if(strcmp(listData->path, "/") == 0) { + if(strcmp(listData->currDir.path, "/") == 0) { if(listData->archive.handle != 0) { FSUSER_CloseArchive(&listData->archive); listData->archive.handle = 0; @@ -192,36 +211,24 @@ static void files_update(ui_view* view, void* data, list_item** items, u32** ite free(listData); list_destroy(view); return; - } else if(*items != NULL && *itemCount != NULL) { - for(u32 i = 0; i < **itemCount; i++) { - char* name = (*items)[i].name; - file_info* fileInfo = (*items)[i].data; - if(fileInfo != NULL && strcmp(name, "..") == 0) { - strncpy(listData->path, fileInfo->path, PATH_MAX); - files_repopulate(listData); - break; - } - } + } else { + files_navigate(listData, listData->parentDir.path); } } + if(hidKeysDown() & KEY_Y) { + ui_push(files_action_create(&listData->currDir, &listData->populated)); + return; + } + if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) { file_info* fileInfo = (file_info*) selected->data; - if(strcmp(selected->name, ".") == 0) { + if(util_is_dir(&listData->archive, fileInfo->path)) { + files_navigate(listData, fileInfo->path); + } else { ui_push(files_action_create(fileInfo, &listData->populated)); return; - } else if(strcmp(selected->name, "..") == 0) { - strncpy(listData->path, fileInfo->path, PATH_MAX); - files_repopulate(listData); - } else { - if(util_is_dir(&listData->archive, fileInfo->path)) { - strncpy(listData->path, fileInfo->path, PATH_MAX); - files_repopulate(listData); - } else { - ui_push(files_action_create(fileInfo, &listData->populated)); - return; - } } } @@ -238,7 +245,6 @@ static void files_update(ui_view* view, void* data, list_item** items, u32** ite void files_open(FS_Archive archive) { files_data* data = (files_data*) calloc(1, sizeof(files_data)); data->archive = archive; - snprintf(data->path, PATH_MAX, "/"); if(data->archive.lowPath.size > 0) { data->archivePath = calloc(1, data->archive.lowPath.size); @@ -260,7 +266,17 @@ void files_open(FS_Archive archive) { return; } - ui_push(list_create("Files", "A: Select, B: Back/Return, X: Refresh", data, files_update, files_draw_top)); + data->currDir.archive = &data->archive; + snprintf(data->currDir.path, PATH_MAX, "/"); + util_get_path_file(data->currDir.name, data->currDir.path, NAME_MAX); + data->currDir.isDirectory = true; + data->currDir.containsCias = false; + data->currDir.size = 0; + data->currDir.isCia = false; + + memcpy(&data->parentDir, &data->currDir, sizeof(data->parentDir)); + + ui_push(list_create("Files", "A: Select, B: Back, X: Refresh, Y: Directory Action", data, files_update, files_draw_top)); } void files_open_sd() { diff --git a/source/ui/section/task/listfiles.c b/source/ui/section/task/listfiles.c index ed3a468..1b2d647 100644 --- a/source/ui/section/task/listfiles.c +++ b/source/ui/section/task/listfiles.c @@ -19,62 +19,19 @@ typedef struct { Handle cancelEvent; - FS_Archive* archive; - const char* path; + file_info* dir; } populate_files_data; static void task_populate_files_thread(void* arg) { populate_files_data* data = (populate_files_data*) arg; + data->dir->containsCias = false; + Result res = 0; if(data->max > *data->count) { - file_info* dotFileInfo = (file_info*) calloc(1, sizeof(file_info)); - if(dotFileInfo != NULL) { - dotFileInfo->archive = data->archive; - strncpy(dotFileInfo->path, data->path, PATH_MAX); - util_get_path_file(dotFileInfo->name, dotFileInfo->path, NAME_MAX); - dotFileInfo->isDirectory = true; - dotFileInfo->containsCias = false; - dotFileInfo->size = 0; - dotFileInfo->isCia = false; - - list_item* dotItem = &data->items[*data->count]; - strncpy(dotItem->name, ".", NAME_MAX); - dotItem->rgba = COLOR_DIRECTORY; - dotItem->data = dotFileInfo; - - (*data->count)++; - } else { - res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY); - } - } - - if(R_SUCCEEDED(res) && data->max > *data->count) { - file_info* dotDotFileInfo = (file_info*) calloc(1, sizeof(file_info)); - if(dotDotFileInfo != NULL) { - dotDotFileInfo->archive = data->archive; - util_get_parent_path(dotDotFileInfo->path, data->path, PATH_MAX); - util_get_path_file(dotDotFileInfo->name, dotDotFileInfo->path, NAME_MAX); - dotDotFileInfo->isDirectory = true; - dotDotFileInfo->containsCias = false; - dotDotFileInfo->size = 0; - dotDotFileInfo->isCia = false; - - list_item* dotDotItem = &data->items[*data->count]; - strncpy(dotDotItem->name, "..", NAME_MAX); - dotDotItem->rgba = COLOR_DIRECTORY; - dotDotItem->data = dotDotFileInfo; - - (*data->count)++; - } else { - res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY); - } - } - - if(R_SUCCEEDED(res) && data->max > *data->count) { Handle dirHandle = 0; - if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, *data->archive, fsMakePath(PATH_ASCII, data->path)))) { + if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, *data->dir->archive, fsMakePath(PATH_ASCII, data->dir->path)))) { u32 entryCount = 0; FS_DirectoryEntry* entries = (FS_DirectoryEntry*) calloc(data->max, sizeof(FS_DirectoryEntry)); if(entries != NULL) { @@ -96,7 +53,7 @@ static void task_populate_files_thread(void* arg) { char entryName[0x213] = {'\0'}; utf16_to_utf8((uint8_t*) entryName, entries[i].name, sizeof(entryName) - 1); - fileInfo->archive = data->archive; + fileInfo->archive = data->dir->archive; strncpy(fileInfo->name, entryName, NAME_MAX); list_item* item = &data->items[*data->count]; @@ -104,7 +61,7 @@ static void task_populate_files_thread(void* arg) { if(entries[i].attributes & FS_ATTRIBUTE_DIRECTORY) { item->rgba = COLOR_DIRECTORY; - snprintf(fileInfo->path, PATH_MAX, "%s%s/", data->path, entryName); + snprintf(fileInfo->path, PATH_MAX, "%s%s/", data->dir->path, entryName); fileInfo->isDirectory = true; fileInfo->containsCias = false; fileInfo->size = 0; @@ -112,19 +69,19 @@ static void task_populate_files_thread(void* arg) { } else { item->rgba = COLOR_TEXT; - snprintf(fileInfo->path, PATH_MAX, "%s%s", data->path, entryName); + snprintf(fileInfo->path, PATH_MAX, "%s%s", data->dir->path, entryName); fileInfo->isDirectory = false; fileInfo->containsCias = false; fileInfo->size = 0; fileInfo->isCia = false; Handle fileHandle; - if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, *data->archive, fsMakePath(PATH_ASCII, fileInfo->path), FS_OPEN_READ, 0))) { + if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, *data->dir->archive, fsMakePath(PATH_ASCII, fileInfo->path), FS_OPEN_READ, 0))) { FSFILE_GetSize(fileHandle, &fileInfo->size); AM_TitleEntry titleEntry; if(R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_SD, &titleEntry, fileHandle))) { - fileInfo->containsCias = true; + data->dir->containsCias = true; fileInfo->isCia = true; fileInfo->ciaInfo.titleId = titleEntry.titleID; @@ -207,8 +164,8 @@ static void task_clear_files(list_item* items, u32* count) { } } -Handle task_populate_files(list_item* items, u32* count, u32 max, FS_Archive* archive, const char* path) { - if(items == NULL || count == NULL || max == 0 || archive == NULL || path == NULL) { +Handle task_populate_files(list_item* items, u32* count, u32 max, file_info* dir) { + if(items == NULL || count == NULL || max == 0 || dir == NULL) { return 0; } @@ -218,8 +175,7 @@ Handle task_populate_files(list_item* items, u32* count, u32 max, FS_Archive* ar data->items = items; data->count = count; data->max = max; - data->archive = archive; - data->path = path; + data->dir = dir; Result eventRes = svcCreateEvent(&data->cancelEvent, 1); if(R_FAILED(eventRes)) { diff --git a/source/ui/section/task/task.h b/source/ui/section/task/task.h index 81bd8e1..652e10c 100644 --- a/source/ui/section/task/task.h +++ b/source/ui/section/task/task.h @@ -79,7 +79,7 @@ bool task_is_quit_all(); void task_quit_all(); Handle task_populate_ext_save_data(list_item* items, u32* count, u32 max); -Handle task_populate_files(list_item* items, u32* count, u32 max, FS_Archive* archive, const char* path); +Handle task_populate_files(list_item* items, u32* count, u32 max, file_info* dir); Handle task_populate_pending_titles(list_item* items, u32* count, u32 max); Handle task_populate_system_save_data(list_item* items, u32* count, u32 max); Handle task_populate_tickets(list_item* items, u32* count, u32 max);