Pass file list filter through to multi-file actions.

This commit is contained in:
Steveice10 2018-08-30 11:52:19 -07:00
parent e09bb54fab
commit 58c7dd0d17
6 changed files with 73 additions and 40 deletions

View File

@ -197,6 +197,13 @@ FS_MediaType fs_get_title_destination(u64 titleId) {
} }
bool fs_filter_cias(void* data, const char* name, u32 attributes) { bool fs_filter_cias(void* data, const char* name, u32 attributes) {
if(data != NULL) {
fs_filter_data* filterData = (fs_filter_data*) data;
if(filterData->parentFilter != NULL && !filterData->parentFilter(filterData->parentFilterData, name, attributes)) {
return false;
}
}
if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) { if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) {
return false; return false;
} }
@ -206,6 +213,13 @@ bool fs_filter_cias(void* data, const char* name, u32 attributes) {
} }
bool fs_filter_tickets(void* data, const char* name, u32 attributes) { bool fs_filter_tickets(void* data, const char* name, u32 attributes) {
if(data != NULL) {
fs_filter_data* filterData = (fs_filter_data*) data;
if(filterData->parentFilter != NULL && !filterData->parentFilter(filterData->parentFilterData, name, attributes)) {
return false;
}
}
if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) { if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) {
return false; return false;
} }

View File

@ -3,6 +3,11 @@
#define FILE_NAME_MAX 256 #define FILE_NAME_MAX 256
#define FILE_PATH_MAX 512 #define FILE_PATH_MAX 512
typedef struct fs_filter_data_s {
bool (*parentFilter)(void* data, const char* name, u32 attributes);
void* parentFilterData;
} fs_filter_data;
bool fs_is_dir(FS_Archive archive, const char* path); bool fs_is_dir(FS_Archive archive, const char* path);
Result fs_ensure_dir(FS_Archive archive, const char* path); Result fs_ensure_dir(FS_Archive archive, const char* path);

View File

@ -16,12 +16,12 @@ void action_delete_system_save_data(linked_list* items, list_item* selected);
void action_install_cia(linked_list* items, list_item* selected); void action_install_cia(linked_list* items, list_item* selected);
void action_install_cia_delete(linked_list* items, list_item* selected); void action_install_cia_delete(linked_list* items, list_item* selected);
void action_install_cias(linked_list* items, list_item* selected); void action_install_cias(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData);
void action_install_cias_delete(linked_list* items, list_item* selected); void action_install_cias_delete(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData);
void action_install_ticket(linked_list* items, list_item* selected); void action_install_ticket(linked_list* items, list_item* selected);
void action_install_ticket_delete(linked_list* items, list_item* selected); void action_install_ticket_delete(linked_list* items, list_item* selected);
void action_install_tickets(linked_list* items, list_item* selected); void action_install_tickets(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData);
void action_install_tickets_delete(linked_list* items, list_item* selected); void action_install_tickets_delete(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData);
void action_delete_file(linked_list* items, list_item* selected); void action_delete_file(linked_list* items, list_item* selected);
void action_delete_dir(linked_list* items, list_item* selected); void action_delete_dir(linked_list* items, list_item* selected);
void action_delete_dir_contents(linked_list* items, list_item* selected); void action_delete_dir_contents(linked_list* items, list_item* selected);

View File

@ -262,6 +262,7 @@ typedef struct {
const char* message; const char* message;
fs_filter_data filterData;
populate_files_data popData; populate_files_data popData;
} install_cias_loading_data; } install_cias_loading_data;
@ -298,7 +299,7 @@ static void action_install_cias_loading_update(ui_view* view, void* data, float*
snprintf(text, PROGRESS_TEXT_MAX, "Fetching CIA list..."); snprintf(text, PROGRESS_TEXT_MAX, "Fetching CIA list...");
} }
static void action_install_cias_internal(linked_list* items, list_item* selected, const char* message, bool delete) { static void action_install_cias_internal(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData, const char* message, bool delete) {
install_cias_data* data = (install_cias_data*) calloc(1, sizeof(install_cias_data)); install_cias_data* data = (install_cias_data*) calloc(1, sizeof(install_cias_data));
if(data == NULL) { if(data == NULL) {
error_display(NULL, NULL, "Failed to allocate install CIAs data."); error_display(NULL, NULL, "Failed to allocate install CIAs data.");
@ -365,6 +366,9 @@ static void action_install_cias_internal(linked_list* items, list_item* selected
loadingData->installData = data; loadingData->installData = data;
loadingData->message = message; loadingData->message = message;
loadingData->filterData.parentFilter = filter;
loadingData->filterData.parentFilterData = filterData;
loadingData->popData.items = &data->contents; loadingData->popData.items = &data->contents;
loadingData->popData.archive = data->target->archive; loadingData->popData.archive = data->target->archive;
string_copy(loadingData->popData.path, data->target->path, FILE_PATH_MAX); string_copy(loadingData->popData.path, data->target->path, FILE_PATH_MAX);
@ -372,7 +376,7 @@ static void action_install_cias_internal(linked_list* items, list_item* selected
loadingData->popData.includeBase = !(data->target->attributes & FS_ATTRIBUTE_DIRECTORY); loadingData->popData.includeBase = !(data->target->attributes & FS_ATTRIBUTE_DIRECTORY);
loadingData->popData.meta = true; loadingData->popData.meta = true;
loadingData->popData.filter = fs_filter_cias; loadingData->popData.filter = fs_filter_cias;
loadingData->popData.filterData = NULL; loadingData->popData.filterData = &loadingData->filterData;
Result listRes = task_populate_files(&loadingData->popData); Result listRes = task_populate_files(&loadingData->popData);
if(R_FAILED(listRes)) { if(R_FAILED(listRes)) {
@ -387,17 +391,17 @@ static void action_install_cias_internal(linked_list* items, list_item* selected
} }
void action_install_cia(linked_list* items, list_item* selected) { void action_install_cia(linked_list* items, list_item* selected) {
action_install_cias_internal(items, selected, "Install the selected CIA?", false); action_install_cias_internal(items, selected, NULL, NULL, "Install the selected CIA?", false);
} }
void action_install_cia_delete(linked_list* items, list_item* selected) { void action_install_cia_delete(linked_list* items, list_item* selected) {
action_install_cias_internal(items, selected, "Install and delete the selected CIA?", true); action_install_cias_internal(items, selected, NULL, NULL, "Install and delete the selected CIA?", true);
} }
void action_install_cias(linked_list* items, list_item* selected) { void action_install_cias(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData) {
action_install_cias_internal(items, selected, "Install all CIAs in the current directory?", false); action_install_cias_internal(items, selected, filter, filterData, "Install all CIAs in the current directory?", false);
} }
void action_install_cias_delete(linked_list* items, list_item* selected) { void action_install_cias_delete(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData) {
action_install_cias_internal(items, selected, "Install and delete all CIAs in the current directory?", true); action_install_cias_internal(items, selected, filter, filterData, "Install and delete all CIAs in the current directory?", true);
} }

View File

@ -211,6 +211,7 @@ typedef struct {
const char* message; const char* message;
fs_filter_data filterData;
populate_files_data popData; populate_files_data popData;
} install_tickets_loading_data; } install_tickets_loading_data;
@ -247,7 +248,7 @@ static void action_install_tickets_loading_update(ui_view* view, void* data, flo
snprintf(text, PROGRESS_TEXT_MAX, "Fetching ticket list..."); snprintf(text, PROGRESS_TEXT_MAX, "Fetching ticket list...");
} }
static void action_install_tickets_internal(linked_list* items, list_item* selected, const char* message, bool delete) { static void action_install_tickets_internal(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData, const char* message, bool delete) {
install_tickets_data* data = (install_tickets_data*) calloc(1, sizeof(install_tickets_data)); install_tickets_data* data = (install_tickets_data*) calloc(1, sizeof(install_tickets_data));
if(data == NULL) { if(data == NULL) {
error_display(NULL, NULL, "Failed to allocate install tickets data."); error_display(NULL, NULL, "Failed to allocate install tickets data.");
@ -312,6 +313,9 @@ static void action_install_tickets_internal(linked_list* items, list_item* selec
loadingData->installData = data; loadingData->installData = data;
loadingData->message = message; loadingData->message = message;
loadingData->filterData.parentFilter = filter;
loadingData->filterData.parentFilterData = filterData;
loadingData->popData.items = &data->contents; loadingData->popData.items = &data->contents;
loadingData->popData.archive = data->target->archive; loadingData->popData.archive = data->target->archive;
string_copy(loadingData->popData.path, data->target->path, FILE_PATH_MAX); string_copy(loadingData->popData.path, data->target->path, FILE_PATH_MAX);
@ -319,7 +323,7 @@ static void action_install_tickets_internal(linked_list* items, list_item* selec
loadingData->popData.includeBase = !(data->target->attributes & FS_ATTRIBUTE_DIRECTORY); loadingData->popData.includeBase = !(data->target->attributes & FS_ATTRIBUTE_DIRECTORY);
loadingData->popData.meta = true; loadingData->popData.meta = true;
loadingData->popData.filter = fs_filter_tickets; loadingData->popData.filter = fs_filter_tickets;
loadingData->popData.filterData = NULL; loadingData->popData.filterData = &loadingData->filterData;
Result listRes = task_populate_files(&loadingData->popData); Result listRes = task_populate_files(&loadingData->popData);
if(R_FAILED(listRes)) { if(R_FAILED(listRes)) {
@ -334,17 +338,17 @@ static void action_install_tickets_internal(linked_list* items, list_item* selec
} }
void action_install_ticket(linked_list* items, list_item* selected) { void action_install_ticket(linked_list* items, list_item* selected) {
action_install_tickets_internal(items, selected, "Install the selected ticket?", false); action_install_tickets_internal(items, selected, NULL, NULL, "Install the selected ticket?", false);
} }
void action_install_ticket_delete(linked_list* items, list_item* selected) { void action_install_ticket_delete(linked_list* items, list_item* selected) {
action_install_tickets_internal(items, selected, "Install and delete the selected ticket?", true); action_install_tickets_internal(items, selected, NULL, NULL, "Install and delete the selected ticket?", true);
} }
void action_install_tickets(linked_list* items, list_item* selected) { void action_install_tickets(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData) {
action_install_tickets_internal(items, selected, "Install all tickets in the current directory?", false); action_install_tickets_internal(items, selected, filter, filterData, "Install all tickets in the current directory?", false);
} }
void action_install_tickets_delete(linked_list* items, list_item* selected) { void action_install_tickets_delete(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData) {
action_install_tickets_internal(items, selected, "Install and delete all tickets in the current directory?", true); action_install_tickets_internal(items, selected, filter, filterData, "Install and delete all tickets in the current directory?", true);
} }

View File

@ -62,6 +62,24 @@ typedef struct {
bool containsTickets; bool containsTickets;
} files_action_data; } files_action_data;
static bool files_filter(void* data, const char* name, u32 attributes) {
files_data* listData = (files_data*) data;
if((attributes & FS_ATTRIBUTE_HIDDEN) != 0 && !listData->showHidden) {
return false;
}
if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) {
return listData->showDirectories;
} else {
if((fs_filter_cias(NULL, name, attributes) && !listData->showCias) || (fs_filter_tickets(NULL, name, attributes) && !listData->showTickets)) {
return false;
}
return listData->showFiles;
}
}
static void files_action_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2, list_item* selected) { static void files_action_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2, list_item* selected) {
task_draw_file_info(view, ((files_action_data*) data)->selected->data, x1, y1, x2, y2); task_draw_file_info(view, ((files_action_data*) data)->selected->data, x1, y1, x2, y2);
} }
@ -79,7 +97,7 @@ static void files_action_update(ui_view* view, void* data, linked_list* items, l
} }
if(selected != NULL && (selected->data != NULL || selected == &copy || selected == &copy_all_contents) && (selectedTouched || (hidKeysDown() & KEY_A))) { if(selected != NULL && (selected->data != NULL || selected == &copy || selected == &copy_all_contents) && (selectedTouched || (hidKeysDown() & KEY_A))) {
void(*action)(linked_list*, list_item*) = (void(*)(linked_list*, list_item*)) selected->data; void* action = selected->data;
ui_pop(); ui_pop();
list_destroy(view); list_destroy(view);
@ -93,8 +111,14 @@ static void files_action_update(ui_view* view, void* data, linked_list* items, l
} else { } else {
error_display_res(info, task_draw_file_info, res, "Failed to copy to clipboard."); error_display_res(info, task_draw_file_info, res, "Failed to copy to clipboard.");
} }
} else if(selected == &install_all_cias || selected == &install_and_delete_all_cias || selected == &install_all_tickets || selected == &install_and_delete_all_tickets) {
void (*filteredAction)(linked_list*, list_item*, bool (*)(void*, const char*, u32), void*) = action;
filteredAction(actionData->items, actionData->selected, files_filter, actionData->parent);
} else { } else {
action(actionData->items, actionData->selected); void (*normalAction)(linked_list*, list_item*) = action;
normalAction(actionData->items, actionData->selected);
} }
free(data); free(data);
@ -342,24 +366,6 @@ static void files_update(ui_view* view, void* data, linked_list* items, list_ite
} }
} }
static bool files_filter(void* data, const char* name, u32 attributes) {
files_data* listData = (files_data*) data;
if((attributes & FS_ATTRIBUTE_HIDDEN) != 0 && !listData->showHidden) {
return false;
}
if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) {
return listData->showDirectories;
} else {
if((fs_filter_cias(NULL, name, attributes) && !listData->showCias) || (fs_filter_tickets(NULL, name, attributes) && !listData->showTickets)) {
return false;
}
return listData->showFiles;
}
}
void files_open(FS_ArchiveID archiveId, FS_Path archivePath) { void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
files_data* data = (files_data*) calloc(1, sizeof(files_data)); files_data* data = (files_data*) calloc(1, sizeof(files_data));
if(data == NULL) { if(data == NULL) {