diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index bcf97a351a..c203627376 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -4472,6 +4472,10 @@ MSG_HASH( MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS, "manual_content_scan_file_exts" ) +MSG_HASH( + MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, + "manual_content_scan_search_recursively" + ) MSG_HASH( MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES, "manual_content_scan_search_archives" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 1a0229a33f..e0b2ebeeea 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -5277,6 +5277,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_FILE_EXTS, "List of file types to include in the scan, separated by spaces. If empty, includes all file types, or if a core is specified, all files supported by the core." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, + "Scan Recursively" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, + "When enabled, all subdirectories of the specified 'Content Directory' will be included in the scan." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES, "Scan Inside Archives" diff --git a/manual_content_scan.c b/manual_content_scan.c index 728bb6a438..03bb4ab26c 100644 --- a/manual_content_scan.c +++ b/manual_content_scan.c @@ -39,6 +39,7 @@ * with a manual content scan */ typedef struct { + bool search_recursively; bool search_archives; bool filter_dat_content; bool overwrite_playlist; @@ -68,6 +69,7 @@ typedef struct * are not thread safe, but we only access them when pushing a * task, not in the task thread itself, so all is well) */ static scan_settings_t scan_settings = { + true, /* search_recursively */ false, /* search_archives */ false, /* filter_dat_content */ false, /* overwrite_playlist */ @@ -132,6 +134,13 @@ size_t manual_content_scan_get_dat_file_path_size(void) return sizeof(scan_settings.dat_file_path); } +/* Returns a pointer to the internal + * 'search_recursively' bool */ +bool *manual_content_scan_get_search_recursively_ptr(void) +{ + return &scan_settings.search_recursively; +} + /* Returns a pointer to the internal * 'search_archives' bool */ bool *manual_content_scan_get_search_archives_ptr(void) @@ -866,6 +875,9 @@ bool manual_content_scan_get_task_config( sizeof(task_config->dat_file_path)); } + /* Copy 'search recursively' setting */ + task_config->search_recursively = scan_settings.search_recursively; + /* Copy 'search inside archives' setting */ task_config->search_archives = scan_settings.search_archives; @@ -911,15 +923,14 @@ struct string_list *manual_content_scan_get_content_list(manual_content_scan_tas include_compressed = (!filter_exts || task_config->search_archives); /* Get directory listing - * > Exclude directories and hidden files - * > Scan recursively */ + * > Exclude directories and hidden files */ dir_list = dir_list_new( task_config->content_dir, filter_exts ? task_config->file_exts : NULL, false, /* include_dirs */ false, /* include_hidden */ include_compressed, - true /* recursive */ + task_config->search_recursively ); /* Sanity check */ diff --git a/manual_content_scan.h b/manual_content_scan.h index cd09c712aa..d04d8da07f 100644 --- a/manual_content_scan.h +++ b/manual_content_scan.h @@ -78,6 +78,7 @@ typedef struct char file_exts[PATH_MAX_LENGTH]; char dat_file_path[PATH_MAX_LENGTH]; bool core_set; + bool search_recursively; bool search_archives; bool filter_dat_content; bool overwrite_playlist; @@ -117,6 +118,10 @@ char *manual_content_scan_get_dat_file_path_ptr(void); * 'dat_file_path' string */ size_t manual_content_scan_get_dat_file_path_size(void); +/* Returns a pointer to the internal + * 'search_recursively' bool */ +bool *manual_content_scan_get_search_recursively_ptr(void); + /* Returns a pointer to the internal * 'search_archives' bool */ bool *manual_content_scan_get_search_archives_ptr(void); diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 9c8df33713..bf1614e479 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -829,6 +829,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_system_name, DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_system_name_custom, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_core_name, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_CORE_NAME) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_file_exts, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_FILE_EXTS) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_search_recursively, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_search_archives, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_dat_file, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_DAT_FILE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_manual_content_scan_dat_file_filter, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_DAT_FILE_FILTER) @@ -3639,6 +3640,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_file_exts); break; + case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_search_recursively); + break; case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_search_archives); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 4133cc5fa3..675408f2f7 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4190,6 +4190,12 @@ static bool menu_displaylist_parse_manual_content_scan_list( false) == 0) count++; + /* Search recursively */ + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info->list, + MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, PARSE_ONLY_BOOL, + false) == 0) + count++; + /* Search inside archive files */ if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(info->list, MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES, PARSE_ONLY_BOOL, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 4cf1769c7c..533f946182 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -17523,6 +17523,21 @@ static bool setting_append_list( SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT); (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; + CONFIG_BOOL( + list, list_info, + manual_content_scan_get_search_recursively_ptr(), + MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, + MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + CONFIG_BOOL( list, list_info, manual_content_scan_get_search_archives_ptr(), diff --git a/msg_hash.h b/msg_hash.h index 5937fef032..050816e4fd 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2866,6 +2866,7 @@ enum msg_hash_enums MENU_LABEL(MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM), MENU_LABEL(MANUAL_CONTENT_SCAN_CORE_NAME), MENU_LABEL(MANUAL_CONTENT_SCAN_FILE_EXTS), + MENU_LABEL(MANUAL_CONTENT_SCAN_SEARCH_RECURSIVELY), MENU_LABEL(MANUAL_CONTENT_SCAN_SEARCH_ARCHIVES), MENU_LABEL(MANUAL_CONTENT_SCAN_DAT_FILE), MENU_LABEL(MANUAL_CONTENT_SCAN_DAT_FILE_FILTER), diff --git a/tasks/task_manual_content_scan.c b/tasks/task_manual_content_scan.c index ded2991499..f423dffb75 100644 --- a/tasks/task_manual_content_scan.c +++ b/tasks/task_manual_content_scan.c @@ -106,6 +106,64 @@ static void free_manual_content_scan_handle(manual_scan_handle_t *manual_scan) manual_scan = NULL; } +static void cb_task_manual_content_scan( + retro_task_t *task, void *task_data, + void *user_data, const char *err) +{ + manual_scan_handle_t *manual_scan = NULL; + playlist_t *cached_playlist = playlist_get_cached(); +#if defined(RARCH_INTERNAL) && defined(HAVE_MENU) + menu_ctx_environment_t menu_environ; +#endif + + if (!task) + goto end; + + manual_scan = (manual_scan_handle_t*)task->state; + + if (!manual_scan) + goto end; + + /* If the manual content scan task has modified the + * currently cached playlist, then it must be re-cached + * (otherwise changes will be lost if the currently + * cached playlist is saved to disk for any reason...) */ + if (cached_playlist) + { + if (string_is_equal( + manual_scan->task_config->playlist_file, + playlist_get_conf_path(cached_playlist))) + { + playlist_free_cached(); + playlist_init_cached( + manual_scan->task_config->playlist_file, COLLECTION_SIZE, + manual_scan->use_old_format, manual_scan->compress); + } + } + +end: + /* When creating playlists, the playlist tabs of + * any active menu driver must be refreshed */ +#if defined(RARCH_INTERNAL) && defined(HAVE_MENU) + menu_environ.type = MENU_ENVIRON_RESET_HORIZONTAL_LIST; + menu_environ.data = NULL; + + menu_driver_ctl(RARCH_MENU_CTL_ENVIRONMENT, &menu_environ); +#endif +} + +static void task_manual_content_scan_free(retro_task_t *task) +{ + manual_scan_handle_t *manual_scan = NULL; + + if (!task) + return; + + manual_scan = (manual_scan_handle_t*)task->state; + + free_manual_content_scan_handle(manual_scan); +} + static void task_manual_content_scan_handler(retro_task_t *task) { manual_scan_handle_t *manual_scan = NULL; @@ -299,7 +357,6 @@ static void task_manual_content_scan_handler(retro_task_t *task) break; case MANUAL_SCAN_END: { - playlist_t *cached_playlist = playlist_get_cached(); char task_title[PATH_MAX_LENGTH]; task_title[0] = '\0'; @@ -315,23 +372,6 @@ static void task_manual_content_scan_handler(retro_task_t *task) manual_scan->use_old_format, manual_scan->compress); - /* If this is the currently cached playlist, then - * it must be re-cached (otherwise changes will be - * lost if the currently cached playlist is saved - * to disk for any reason...) */ - if (cached_playlist) - { - if (string_is_equal( - manual_scan->task_config->playlist_file, - playlist_get_conf_path(cached_playlist))) - { - playlist_free_cached(); - playlist_init_cached( - manual_scan->task_config->playlist_file, COLLECTION_SIZE, - manual_scan->use_old_format, manual_scan->compress); - } - } - /* Update progress display */ task_free_title(task); @@ -355,8 +395,6 @@ task_finished: if (task) task_set_finished(task, true); - - free_manual_content_scan_handle(manual_scan); } static bool task_manual_content_scan_finder(retro_task_t *task, void *user_data) @@ -377,19 +415,6 @@ static bool task_manual_content_scan_finder(retro_task_t *task, void *user_data) (const char*)user_data, manual_scan->task_config->playlist_file); } -static void cb_task_manual_content_scan_refresh_menu( - retro_task_t *task, void *task_data, - void *user_data, const char *err) -{ -#if defined(RARCH_INTERNAL) && defined(HAVE_MENU) - menu_ctx_environment_t menu_environ; - menu_environ.type = MENU_ENVIRON_RESET_HORIZONTAL_LIST; - menu_environ.data = NULL; - - menu_driver_ctl(RARCH_MENU_CTL_ENVIRONMENT, &menu_environ); -#endif -} - bool task_push_manual_content_scan(void) { task_finder_data_t find_data; @@ -468,7 +493,8 @@ bool task_push_manual_content_scan(void) task->title = strdup(task_title); task->alternative_look = true; task->progress = 0; - task->callback = cb_task_manual_content_scan_refresh_menu; + task->callback = cb_task_manual_content_scan; + task->cleanup = task_manual_content_scan_free; /* > Push task */ task_queue_push(task);