From 223cae66c1ceac124fa47d9ed6d8a61caf8c72bc Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 10 Apr 2020 17:05:23 +0100 Subject: [PATCH] (Playlist Management) Add optional per-playlist alphabetical sorting --- config.def.h | 10 +- configuration.c | 10 +- intl/msg_hash_lbl.h | 4 + intl/msg_hash_us.h | 20 +++ menu/cbs/menu_cbs_deferred_push.c | 2 + menu/cbs/menu_cbs_get_value.c | 39 +++++ menu/cbs/menu_cbs_left.c | 27 ++++ menu/cbs/menu_cbs_ok.c | 124 ++++++++++++---- menu/cbs/menu_cbs_right.c | 27 ++++ menu/cbs/menu_cbs_start.c | 20 +++ menu/cbs/menu_cbs_sublabel.c | 4 + menu/cbs/menu_cbs_title.c | 2 + menu/drivers/materialui.c | 9 +- menu/menu_cbs.h | 1 + menu/menu_displaylist.c | 231 +++++++++++++++++++++--------- menu/menu_displaylist.h | 1 + menu/menu_driver.h | 2 + menu/menu_setting.c | 10 +- msg_hash.h | 7 + playlist.c | 63 +++++++- playlist.h | 9 ++ retroarch.c | 24 +++- tasks/task_manual_content_scan.c | 4 +- 23 files changed, 527 insertions(+), 123 deletions(-) diff --git a/config.def.h b/config.def.h index 2737824b2b..a7b643efec 100644 --- a/config.def.h +++ b/config.def.h @@ -950,22 +950,22 @@ static const unsigned default_content_history_size = 200; static const int default_content_favorites_size = 200; /* Sort all playlists (apart from histories) alphabetically */ -static const bool playlist_sort_alphabetical = true; +#define DEFAULT_PLAYLIST_SORT_ALPHABETICAL true /* File format to use when writing playlists to disk */ -static const bool playlist_use_old_format = false; +#define DEFAULT_PLAYLIST_USE_OLD_FORMAT false #ifdef HAVE_MENU /* Specify when to display 'core name' inline on playlist entries */ -static const unsigned playlist_show_inline_core_name = PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV; +#define DEFAULT_PLAYLIST_SHOW_INLINE_CORE_NAME PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV /* Specifies which runtime record to use on playlist sublabels */ -static const unsigned playlist_sublabel_runtime_type = PLAYLIST_RUNTIME_PER_CORE; +#define DEFAULT_PLAYLIST_SUBLABEL_RUNTIME_TYPE PLAYLIST_RUNTIME_PER_CORE /* Specifies time/date display format for runtime 'last played' data */ #define DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS -static const unsigned playlist_entry_remove_enable = PLAYLIST_ENTRY_REMOVE_ENABLE_ALL; +#define DEFAULT_PLAYLIST_ENTRY_REMOVE_ENABLE PLAYLIST_ENTRY_REMOVE_ENABLE_ALL #endif #define DEFAULT_SCAN_WITHOUT_CORE_MATCH false diff --git a/configuration.c b/configuration.c index fcd8fb4519..d3e5a6585a 100644 --- a/configuration.c +++ b/configuration.c @@ -1648,11 +1648,11 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("video_3ds_lcd_bottom", &settings->bools.video_3ds_lcd_bottom, true, video_3ds_lcd_bottom, false); #endif - SETTING_BOOL("playlist_use_old_format", &settings->bools.playlist_use_old_format, true, playlist_use_old_format, false); + SETTING_BOOL("playlist_use_old_format", &settings->bools.playlist_use_old_format, true, DEFAULT_PLAYLIST_USE_OLD_FORMAT, false); SETTING_BOOL("content_runtime_log", &settings->bools.content_runtime_log, true, DEFAULT_CONTENT_RUNTIME_LOG, false); SETTING_BOOL("content_runtime_log_aggregate", &settings->bools.content_runtime_log_aggregate, true, DEFAULT_CONTENT_RUNTIME_LOG_AGGREGATE, false); SETTING_BOOL("playlist_show_sublabels", &settings->bools.playlist_show_sublabels, true, DEFAULT_PLAYLIST_SHOW_SUBLABELS, false); - SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, playlist_sort_alphabetical, false); + SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, DEFAULT_PLAYLIST_SORT_ALPHABETICAL, false); SETTING_BOOL("playlist_fuzzy_archive_match", &settings->bools.playlist_fuzzy_archive_match, true, DEFAULT_PLAYLIST_FUZZY_ARCHIVE_MATCH, false); SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, DEFAULT_QUIT_PRESS_TWICE, false); @@ -1894,9 +1894,9 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, #endif #ifdef HAVE_MENU - SETTING_UINT("playlist_entry_remove_enable", &settings->uints.playlist_entry_remove_enable, true, playlist_entry_remove_enable, false); - SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, playlist_show_inline_core_name, false); - SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, playlist_sublabel_runtime_type, false); + SETTING_UINT("playlist_entry_remove_enable", &settings->uints.playlist_entry_remove_enable, true, DEFAULT_PLAYLIST_ENTRY_REMOVE_ENABLE, false); + SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, DEFAULT_PLAYLIST_SHOW_INLINE_CORE_NAME, false); + SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, DEFAULT_PLAYLIST_SUBLABEL_RUNTIME_TYPE, false); SETTING_UINT("playlist_sublabel_last_played_style", &settings->uints.playlist_sublabel_last_played_style, true, DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE, false); #endif diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index b3c4f8851c..5f5a46425b 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -300,6 +300,8 @@ MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MOD "deferred_dropdown_box_list_playlist_right_thumbnail_mode") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE, "deferred_dropdown_box_list_playlist_left_thumbnail_mode") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE, + "deferred_dropdown_box_list_playlist_sort_mode") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX, "deferred_dropdown_box_list_disk_index") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST, @@ -978,6 +980,8 @@ MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_MANAGER_RIGHT_THUMBNAIL_MODE, "playlist_manager_right_thumbnail_mode") MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, "playlist_manager_left_thumbnail_mode") +MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE, + "playlist_manager_sort_mode") MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_MANAGER_CLEAN_PLAYLIST, "playlist_manager_clean_playlist") MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SETTINGS_BEGIN, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a4619f7686..0dd655d831 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2552,6 +2552,26 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_THUMBNAIL_MODE_DEFAULT, "System Default" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE, + "Sorting Method" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_SORT_MODE, + "Change how entries are sorted in this playlist." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_DEFAULT, + "System Default" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_ALPHABETICAL, + "Alphabetical" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_OFF, + "None" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_CLEAN_PLAYLIST, "Clean Playlist" diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index fc1d9c4747..46fa637174 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -670,6 +670,7 @@ generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_def generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_label_display_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE) generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_right_thumbnail_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE) generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_left_thumbnail_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE) +generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_sort_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_SORT_MODE) generic_deferred_push_clear_general(deferred_push_dropdown_box_list_manual_content_scan_system_name, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME) generic_deferred_push_clear_general(deferred_push_dropdown_box_list_manual_content_scan_core_name, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME) generic_deferred_push_clear_general(deferred_push_dropdown_box_list_disk_index, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_DISK_INDEX) @@ -699,6 +700,7 @@ static int menu_cbs_init_bind_deferred_push_compare_label( {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE, deferred_push_dropdown_box_list_playlist_label_display_mode}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE, deferred_push_dropdown_box_list_playlist_right_thumbnail_mode}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE, deferred_push_dropdown_box_list_playlist_left_thumbnail_mode}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE, deferred_push_dropdown_box_list_playlist_sort_mode}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX, deferred_push_dropdown_box_list_disk_index}, {MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_LIST, deferred_push_browse_url_list}, {MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_START, deferred_push_browse_url_start}, diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 6a9d3a2194..9c5fcbe5fc 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -1189,6 +1189,41 @@ static void menu_action_setting_disp_set_label_playlist_left_thumbnail_mode( len); } +static void menu_action_setting_disp_set_label_playlist_sort_mode( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *path, + char *s2, size_t len2) +{ + enum playlist_sort_mode sort_mode; + playlist_t *playlist = playlist_get_cached(); + + if (!playlist) + return; + + sort_mode = playlist_get_sort_mode(playlist); + + *w = 19; + + strlcpy(s2, path, len2); + + switch (sort_mode) + { + case PLAYLIST_SORT_MODE_ALPHABETICAL: + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_ALPHABETICAL), len); + break; + case PLAYLIST_SORT_MODE_OFF: + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_OFF), len); + break; + case PLAYLIST_SORT_MODE_DEFAULT: + default: + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_DEFAULT), len); + break; + } +} + static void menu_action_setting_disp_set_label_core_options(file_list_t* list, unsigned *w, unsigned type, unsigned i, const char *label, @@ -1509,6 +1544,10 @@ static int menu_cbs_init_bind_get_string_representation_compare_label( BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_playlist_left_thumbnail_mode); break; + case MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_playlist_sort_mode); + break; case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR: BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_manual_content_scan_dir); diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index b0327df851..93eb732ce0 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -520,6 +520,30 @@ static int playlist_left_thumbnail_mode_left(unsigned type, const char *label, return 0; } +static int playlist_sort_mode_left(unsigned type, const char *label, + bool wraparound) +{ + enum playlist_sort_mode sort_mode; + settings_t *settings = config_get_ptr(); + bool playlist_use_old_format = settings->bools.playlist_use_old_format; + playlist_t *playlist = playlist_get_cached(); + + if (!playlist) + return -1; + + sort_mode = playlist_get_sort_mode(playlist); + + if (sort_mode > PLAYLIST_SORT_MODE_DEFAULT) + sort_mode = (enum playlist_sort_mode)((int)sort_mode - 1); + else if (wraparound) + sort_mode = PLAYLIST_SORT_MODE_OFF; + + playlist_set_sort_mode(playlist, sort_mode); + playlist_write_file(playlist, playlist_use_old_format); + + return 0; +} + static int manual_content_scan_system_name_left( unsigned type, const char *label, bool wraparound) @@ -924,6 +948,9 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE: BIND_ACTION_LEFT(cbs, playlist_left_thumbnail_mode_left); break; + case MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE: + BIND_ACTION_LEFT(cbs, playlist_sort_mode_left); + break; case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME: BIND_ACTION_LEFT(cbs, manual_content_scan_system_name_left); break; diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 2d1384cfd3..eece239717 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -187,6 +187,8 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE; case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE: return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE: + return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE; case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME: return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME; case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME: @@ -524,6 +526,15 @@ int generic_action_ok_displaylist_push(const char *path, info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE; dl_type = DISPLAYLIST_GENERIC; break; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE: + info.type = type; + info.directory_ptr = idx; + info_path = path; + info_label = msg_hash_to_str( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE); + info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE; + dl_type = DISPLAYLIST_GENERIC; + break; case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME: info.type = type; info.directory_ptr = idx; @@ -2018,15 +2029,20 @@ static int action_ok_playlist_entry_collection(const char *path, { char new_path[PATH_MAX_LENGTH]; char new_core_path[PATH_MAX_LENGTH]; - size_t selection_ptr = 0; - bool playlist_initialized = false; - playlist_t *playlist = NULL; - playlist_t *tmp_playlist = NULL; - const struct playlist_entry *entry = NULL; - unsigned i = 0; - menu_handle_t *menu = menu_driver_get_ptr(); - settings_t *settings = config_get_ptr(); - bool playlist_use_old_format = settings->bools.playlist_use_old_format; + size_t selection_ptr = 0; + bool playlist_initialized = false; + playlist_t *playlist = NULL; + playlist_t *tmp_playlist = NULL; + const struct playlist_entry *entry = NULL; + unsigned i = 0; + menu_handle_t *menu = menu_driver_get_ptr(); + settings_t *settings = config_get_ptr(); + bool playlist_use_old_format = settings->bools.playlist_use_old_format; + bool playlist_sort_alphabetical = settings->bools.playlist_sort_alphabetical; + const char *path_content_history = settings->paths.path_content_history; + const char *path_content_music_history = settings->paths.path_content_music_history; + const char *path_content_video_history = settings->paths.path_content_video_history; + const char *path_content_image_history = settings->paths.path_content_image_history; if (!menu) return menu_cbs_exit(); @@ -2037,12 +2053,31 @@ static int action_ok_playlist_entry_collection(const char *path, if (!tmp_playlist) { + /* If playlist is not cached, have to load + * it here + * > Since the menu will always sort playlists + * based on current user config, have to do + * the same here - otherwise entry_idx may + * go out of sync... */ + bool is_content_history = string_is_equal(menu->db_playlist_file, path_content_history) || + string_is_equal(menu->db_playlist_file, path_content_music_history) || + string_is_equal(menu->db_playlist_file, path_content_video_history) || + string_is_equal(menu->db_playlist_file, path_content_image_history); + enum playlist_sort_mode current_sort_mode; + tmp_playlist = playlist_init( menu->db_playlist_file, COLLECTION_SIZE); if (!tmp_playlist) return menu_cbs_exit(); + current_sort_mode = playlist_get_sort_mode(tmp_playlist); + + if (!is_content_history && + ((playlist_sort_alphabetical && (current_sort_mode == PLAYLIST_SORT_MODE_DEFAULT)) || + (current_sort_mode == PLAYLIST_SORT_MODE_ALPHABETICAL))) + playlist_qsort(tmp_playlist); + playlist_initialized = true; } @@ -2065,6 +2100,8 @@ static int action_ok_playlist_entry_collection(const char *path, { RARCH_LOG("[playlist] subsystem not found in implementation\n"); /* TODO: Add OSD message telling users that content can't be loaded */ + if (playlist_initialized) + playlist_free(tmp_playlist); return 0; } @@ -2075,6 +2112,8 @@ static int action_ok_playlist_entry_collection(const char *path, NULL, &content_info, CORE_TYPE_PLAIN, NULL, NULL); /* TODO: update playlist entry? move to first position I guess? */ + if (playlist_initialized) + playlist_free(tmp_playlist); return 1; } @@ -2091,6 +2130,7 @@ static int action_ok_playlist_entry_collection(const char *path, const char *default_core_path = playlist_get_default_core_path(playlist); bool found_associated_core = false; + struct playlist_entry update_entry = {0}; if (!string_is_empty(default_core_path)) { @@ -2116,21 +2156,14 @@ static int action_ok_playlist_entry_collection(const char *path, return ret; } - tmp_playlist = playlist_get_cached(); + update_entry.core_path = (char*)default_core_path; + update_entry.core_name = core_info.inf->display_name; - if (tmp_playlist) - { - struct playlist_entry entry = {0}; - - entry.core_path = (char*)default_core_path; - entry.core_name = core_info.inf->display_name; - - command_playlist_update_write( - tmp_playlist, - selection_ptr, - &entry, - playlist_use_old_format); - } + command_playlist_update_write( + playlist, + selection_ptr, + &update_entry, + playlist_use_old_format); } else { @@ -2153,6 +2186,10 @@ static int action_ok_playlist_entry_collection(const char *path, strlcpy(new_path, entry->path, sizeof(new_path)); playlist_resolve_path(PLAYLIST_LOAD, new_path, sizeof(new_path)); + + if (playlist_initialized) + playlist_free(tmp_playlist); + return default_action_ok_load_content_from_playlist_from_menu( new_core_path, new_path, entry->label); } @@ -2223,7 +2260,6 @@ static int action_ok_playlist_entry(const char *path, &entry, playlist_use_old_format); } - } else { @@ -5921,6 +5957,20 @@ static int action_ok_push_dropdown_item_playlist_left_thumbnail_mode(const char return generic_set_thumbnail_mode(PLAYLIST_THUMBNAIL_LEFT, idx); } +static int action_ok_push_dropdown_item_playlist_sort_mode( + const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + settings_t *settings = config_get_ptr(); + playlist_t *playlist = playlist_get_cached(); + bool playlist_use_old_format = settings->bools.playlist_use_old_format; + + playlist_set_sort_mode(playlist, (enum playlist_sort_mode)idx); + playlist_write_file(playlist, playlist_use_old_format); + + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + static int action_ok_push_dropdown_item_manual_content_scan_system_name(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -6189,6 +6239,20 @@ static int action_ok_playlist_right_thumbnail_mode(const char *path, ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE); } +static int action_ok_playlist_left_thumbnail_mode(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + return generic_dropdown_box_list(idx, + ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE); +} + +static int action_ok_playlist_sort_mode(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + return generic_dropdown_box_list(idx, + ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE); +} + static int action_ok_remappings_port_list(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -6213,13 +6277,6 @@ static int action_ok_shader_preset_parameter_dropdown_box_list(const char *path, ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PRESET_PARAMETER); } -static int action_ok_playlist_left_thumbnail_mode(const char *path, - const char *label, unsigned type, size_t idx, size_t entry_idx) -{ - return generic_dropdown_box_list(idx, - ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE); -} - static int action_ok_manual_content_scan_system_name(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -6767,6 +6824,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE, action_ok_playlist_label_display_mode}, {MENU_ENUM_LABEL_PLAYLIST_MANAGER_RIGHT_THUMBNAIL_MODE,action_ok_playlist_right_thumbnail_mode}, {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE,action_ok_playlist_left_thumbnail_mode}, + {MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE, action_ok_playlist_sort_mode}, {MENU_ENUM_LABEL_UPDATE_ASSETS, action_ok_update_assets}, {MENU_ENUM_LABEL_UPDATE_CORE_INFO_FILES, action_ok_update_core_info_files}, {MENU_ENUM_LABEL_UPDATE_OVERLAYS, action_ok_update_overlays}, @@ -6933,6 +6991,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE, action_ok_playlist_label_display_mode}, {MENU_ENUM_LABEL_PLAYLIST_MANAGER_RIGHT_THUMBNAIL_MODE, action_ok_playlist_right_thumbnail_mode}, {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, action_ok_playlist_left_thumbnail_mode}, + {MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE, action_ok_playlist_sort_mode}, {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME, action_ok_manual_content_scan_system_name}, {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME, action_ok_manual_content_scan_core_name}, {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DAT_FILE, action_ok_manual_content_scan_dat_file}, @@ -7077,6 +7136,9 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LEFT_THUMBNAIL_MODE: BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_left_thumbnail_mode); break; + case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_SORT_MODE: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_sort_mode); + break; case MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME: BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_manual_content_scan_system_name); break; diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index 2d65b48fb4..8982e1dbde 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -617,6 +617,30 @@ static int playlist_left_thumbnail_mode_right(unsigned type, const char *label, return 0; } +static int playlist_sort_mode_right(unsigned type, const char *label, + bool wraparound) +{ + enum playlist_sort_mode sort_mode; + settings_t *settings = config_get_ptr(); + playlist_t *playlist = playlist_get_cached(); + bool playlist_use_old_format = settings->bools.playlist_use_old_format; + + if (!playlist) + return -1; + + sort_mode = playlist_get_sort_mode(playlist); + + if (sort_mode < PLAYLIST_SORT_MODE_OFF) + sort_mode = (enum playlist_sort_mode)((int)sort_mode + 1); + else if (wraparound) + sort_mode = PLAYLIST_SORT_MODE_DEFAULT; + + playlist_set_sort_mode(playlist, sort_mode); + playlist_write_file(playlist, playlist_use_old_format); + + return 0; +} + static int manual_content_scan_system_name_right(unsigned type, const char *label, bool wraparound) { @@ -1037,6 +1061,9 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE: BIND_ACTION_RIGHT(cbs, playlist_left_thumbnail_mode_right); break; + case MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE: + BIND_ACTION_RIGHT(cbs, playlist_sort_mode_right); + break; case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME: BIND_ACTION_RIGHT(cbs, manual_content_scan_system_name_right); break; diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c index 30f26be512..dc216c4493 100644 --- a/menu/cbs/menu_cbs_start.c +++ b/menu/cbs/menu_cbs_start.c @@ -362,6 +362,23 @@ static int action_start_playlist_left_thumbnail_mode( return 0; } +static int action_start_playlist_sort_mode( + const char *path, const char *label, + unsigned type, size_t idx, size_t entry_idx) +{ + settings_t *settings = config_get_ptr(); + playlist_t *playlist = playlist_get_cached(); + + if (!playlist) + return -1; + + /* Set sort mode to the default */ + playlist_set_sort_mode(playlist, PLAYLIST_SORT_MODE_DEFAULT); + playlist_write_file(playlist, settings->bools.playlist_use_old_format); + + return 0; +} + static int action_start_manual_content_scan_dir( const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) @@ -500,6 +517,9 @@ static int menu_cbs_init_bind_start_compare_label(menu_file_list_cbs_t *cbs) case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE: BIND_ACTION_START(cbs, action_start_playlist_left_thumbnail_mode); break; + case MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE: + BIND_ACTION_START(cbs, action_start_playlist_sort_mode); + break; case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR: BIND_ACTION_START(cbs, action_start_manual_content_scan_dir); break; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index becbcec570..82e6cb51f6 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -146,6 +146,7 @@ default_sublabel_macro(action_bind_sublabel_playlist_manager_list, MENU_ default_sublabel_macro(action_bind_sublabel_playlist_manager_default_core, MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_DEFAULT_CORE) default_sublabel_macro(action_bind_sublabel_playlist_manager_reset_cores, MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_RESET_CORES) default_sublabel_macro(action_bind_sublabel_playlist_manager_label_display_mode, MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE) +default_sublabel_macro(action_bind_sublabel_playlist_manager_sort_mode, MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_SORT_MODE) default_sublabel_macro(action_bind_sublabel_playlist_manager_clean_playlist, MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_CLEAN_PLAYLIST) default_sublabel_macro(action_bind_sublabel_delete_playlist, MENU_ENUM_SUBLABEL_DELETE_PLAYLIST) default_sublabel_macro(action_bind_sublabel_network_settings_list, MENU_ENUM_SUBLABEL_NETWORK_SETTINGS) @@ -2928,6 +2929,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_manager_label_display_mode); break; + case MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_manager_sort_mode); + break; case MENU_ENUM_LABEL_PLAYLIST_MANAGER_CLEAN_PLAYLIST: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_manager_clean_playlist); break; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index a9c96dc954..f54fc19096 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -428,6 +428,7 @@ default_title_macro(action_get_title_dropdown_video_shader_parameter_item, MENU default_title_macro(action_get_title_dropdown_video_shader_preset_parameter_item, MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS) default_title_macro(action_get_title_dropdown_playlist_default_core_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_DEFAULT_CORE) default_title_macro(action_get_title_dropdown_playlist_label_display_mode_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE) +default_title_macro(action_get_title_dropdown_playlist_sort_mode_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE) default_title_macro(action_get_title_manual_content_scan_list, MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST) default_title_macro(action_get_title_dropdown_manual_content_scan_system_name_item, MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME) default_title_macro(action_get_title_dropdown_manual_content_scan_core_name_item, MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME) @@ -1367,6 +1368,7 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES, action_get_title_dropdown_video_shader_num_pass_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE, action_get_title_dropdown_playlist_default_core_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE, action_get_title_dropdown_playlist_label_display_mode_item}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE, action_get_title_dropdown_playlist_sort_mode_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE, action_get_title_thumbnails}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE, action_get_title_left_thumbnails}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, action_get_title_dropdown_manual_content_scan_system_name_item}, diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 827e5014be..0813b608eb 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -6436,10 +6436,17 @@ static void materialui_populate_entries( mui->is_dropdown_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PARAMETER)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PRESET_PARAMETER)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE)) || - string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE)); + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX)); } /* If this is a playlist, then cache it */ diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index 373bdc3c92..733077f4da 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -55,6 +55,7 @@ enum ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE, ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE, ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE, + ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE, ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME, ACTION_OK_DL_DROPDOWN_BOX_LIST_DISK_INDEX, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 8a97316ba7..49b3d7c09f 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1729,21 +1729,22 @@ end: } static void menu_displaylist_set_new_playlist( - menu_handle_t *menu, const char *path) + menu_handle_t *menu, const char *path, bool sort_enabled) { - unsigned playlist_size = COLLECTION_SIZE; - const char *playlist_file_name = path_basename(path); - settings_t *settings = config_get_ptr(); - int content_favorites_size = settings->ints.content_favorites_size; - unsigned content_history_size = settings->uints.content_history_size; + unsigned playlist_size = COLLECTION_SIZE; + const char *playlist_file_name = path_basename(path); + settings_t *settings = config_get_ptr(); + int content_favorites_size = settings->ints.content_favorites_size; + unsigned content_history_size = settings->uints.content_history_size; + bool playlist_sort_alphabetical = settings->bools.playlist_sort_alphabetical; - menu->db_playlist_file[0] = '\0'; + menu->db_playlist_file[0] = '\0'; if (playlist_get_cached()) playlist_free_cached(); /* Get proper playlist capacity */ - if (settings && !string_is_empty(playlist_file_name)) + if (!string_is_empty(playlist_file_name)) { if (string_is_equal(playlist_file_name, file_path_str(FILE_PATH_CONTENT_HISTORY)) || string_is_equal(playlist_file_name, file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY)) || @@ -1756,16 +1757,28 @@ static void menu_displaylist_set_new_playlist( } if (playlist_init_cached(path, playlist_size)) + { + playlist_t *playlist = + playlist_get_cached(); + enum playlist_sort_mode current_sort_mode = + playlist_get_sort_mode(playlist); + + /* Sort playlist, if required */ + if (sort_enabled && + ((playlist_sort_alphabetical && (current_sort_mode == PLAYLIST_SORT_MODE_DEFAULT)) || + (current_sort_mode == PLAYLIST_SORT_MODE_ALPHABETICAL))) + playlist_qsort(playlist); + strlcpy( menu->db_playlist_file, path, sizeof(menu->db_playlist_file)); + } } static int menu_displaylist_parse_horizontal_list( menu_handle_t *menu, - menu_displaylist_info_t *info, - bool sort) + menu_displaylist_info_t *info) { menu_ctx_list_t list_info; menu_ctx_list_t list_horiz_info; @@ -1800,7 +1813,10 @@ static int menu_displaylist_parse_horizontal_list( fill_pathname_join(path_playlist, dir_playlist, item->path, sizeof(path_playlist)); - menu_displaylist_set_new_playlist(menu, path_playlist); + + /* Horizontal lists are always 'collections' + * > Enable sorting (if allowed by user config) */ + menu_displaylist_set_new_playlist(menu, path_playlist, true); /* Thumbnail system must be set *after* playlist * is loaded/cached */ @@ -1811,14 +1827,9 @@ static int menu_displaylist_parse_horizontal_list( playlist = playlist_get_cached(); if (playlist) - { - if (sort) - playlist_qsort(playlist); - menu_displaylist_parse_playlist(info, playlist, msg_hash_to_str(MENU_ENUM_LABEL_COLLECTION), true); - } return 0; } @@ -2879,9 +2890,12 @@ static bool menu_displaylist_parse_playlist_manager_settings( { enum msg_hash_enums right_thumbnail_label_value; enum msg_hash_enums left_thumbnail_label_value; - const char *playlist_file = NULL; - playlist_t *playlist = NULL; - const char *menu_driver = menu_driver_ident(); + bool is_content_history; + const char *playlist_file = NULL; + playlist_t *playlist = NULL; + const char *menu_driver = menu_driver_ident(); + settings_t *settings = config_get_ptr(); + bool playlist_use_old_format = settings->bools.playlist_use_old_format; if (string_is_empty(playlist_path)) return false; @@ -2891,20 +2905,29 @@ static bool menu_displaylist_parse_playlist_manager_settings( if (string_is_empty(playlist_file)) return false; - menu_displaylist_set_new_playlist(menu, playlist_path); + /* Note: We are caching the current playlist + * here so we can get its path and/or modify + * its metadata when performing management + * tasks. We *don't* care about entry order + * at this stage, so we can save a few clock + * cycles by disabling sorting */ + menu_displaylist_set_new_playlist(menu, playlist_path, false); playlist = playlist_get_cached(); if (!playlist) return false; + /* Check whether this is a content history playlist */ + is_content_history = string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_HISTORY)) || + string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY)) || + string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_VIDEO_HISTORY)) || + string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_IMAGE_HISTORY)); + /* Default core association * > This is only shown for collection playlists * (i.e. it is not relevant for history/favourites) */ - if (!string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_HISTORY)) && - !string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY)) && - !string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_VIDEO_HISTORY)) && - !string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_IMAGE_HISTORY)) && + if (!is_content_history && !string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_FAVORITES))) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_DEFAULT_CORE), @@ -2967,6 +2990,16 @@ static bool menu_displaylist_parse_playlist_manager_settings( MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, MENU_SETTING_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, 0, 0); + /* Sorting mode + * > Only enabled when using the new playlist format + * > Not relevant for history playlists */ + if (!playlist_use_old_format && !is_content_history) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE), + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE), + MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE, + MENU_SETTING_PLAYLIST_MANAGER_SORT_MODE, 0, 0); + /* Clean playlist */ menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_CLEAN_PLAYLIST), @@ -3595,22 +3628,19 @@ static void menu_displaylist_parse_playlist_generic( const char *playlist_name, const char *playlist_path, bool is_collection, - bool sort, + bool sort_enabled, int *ret) { playlist_t *playlist = NULL; - menu_displaylist_set_new_playlist(menu, playlist_path); + menu_displaylist_set_new_playlist(menu, playlist_path, sort_enabled); playlist = playlist_get_cached(); if (!playlist) return; - if (sort) - playlist_qsort(playlist); - - *ret = menu_displaylist_parse_playlist(info, + *ret = menu_displaylist_parse_playlist(info, playlist, playlist_name, is_collection); } @@ -5375,6 +5405,58 @@ unsigned menu_displaylist_build_list( case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE: count = populate_playlist_thumbnail_mode_dropdown_list(list, PLAYLIST_THUMBNAIL_LEFT); break; + case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_SORT_MODE: + { + playlist_t *playlist = playlist_get_cached(); + + if (playlist) + { + size_t i; + /* Get current sort mode */ + enum playlist_sort_mode current_sort_mode = + playlist_get_sort_mode(playlist); + + /* Loop over all defined sort modes */ + for (i = 0; i <= (unsigned)PLAYLIST_SORT_MODE_OFF; i++) + { + enum msg_hash_enums label_value; + enum playlist_sort_mode sort_mode = + (enum playlist_sort_mode)i; + + /* Get appropriate entry label */ + switch (sort_mode) + { + case PLAYLIST_SORT_MODE_ALPHABETICAL: + label_value = MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_ALPHABETICAL; + break; + case PLAYLIST_SORT_MODE_OFF: + label_value = MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_OFF; + break; + case PLAYLIST_SORT_MODE_DEFAULT: + default: + label_value = MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_DEFAULT; + break; + } + + /* Add entry */ + if (menu_entries_append_enum(list, + msg_hash_to_str(label_value), + "", + MENU_ENUM_LABEL_NO_ITEMS, + MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_SORT_MODE, + 0, 0)) + count++; + + /* Check whether current entry is checked */ + if (current_sort_mode == sort_mode) + { + menu_entries_set_checked(list, i, true); + menu_navigation_set_selection(i); + } + } + } + } + break; case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME: /* Get system name list */ { @@ -8822,7 +8904,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, char path_playlist[PATH_MAX_LENGTH]; playlist_t *playlist = NULL; settings_t *settings = config_get_ptr(); - bool playlist_sort_alphabetical = settings->bools.playlist_sort_alphabetical; const char *dir_playlist = settings->paths.directory_playlist; path_playlist[0] = '\0'; @@ -8833,7 +8914,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, info->path, sizeof(path_playlist)); - menu_displaylist_set_new_playlist(menu, path_playlist); + menu_displaylist_set_new_playlist(menu, path_playlist, true); strlcpy(path_playlist, msg_hash_to_str(MENU_ENUM_LABEL_COLLECTION), @@ -8842,17 +8923,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, playlist = playlist_get_cached(); if (playlist) - { - if (playlist_sort_alphabetical) - playlist_qsort(playlist); - ret = menu_displaylist_parse_playlist(info, playlist, path_playlist, true); - } if (ret == 0) { - info->need_sort = playlist_sort_alphabetical; + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; info->need_refresh = true; info->need_push = true; } @@ -8882,6 +8961,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, } ret = 0; + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; info->need_refresh = true; info->need_push = true; #ifndef IS_SALAMANDER @@ -8894,7 +8977,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, { settings_t *settings = config_get_ptr(); const char *path_content_favorites = settings->paths.path_content_favorites; - bool playlist_sort_alphabetical = settings->bools.playlist_sort_alphabetical; info->count = 0; @@ -8903,7 +8985,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, "favorites", path_content_favorites, false, /* Not a conventional collection */ - playlist_sort_alphabetical, + true, /* Enable sorting (if allowed by user config) */ &ret); if (info->count == 0) @@ -8918,7 +9000,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, } ret = 0; - info->need_sort = playlist_sort_alphabetical; + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; info->need_refresh = true; info->need_push = true; } @@ -8953,6 +9038,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, if (ret == 0) { + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; info->need_refresh = true; info->need_push = true; #ifndef IS_SALAMANDER @@ -8997,6 +9086,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, if (ret == 0) { + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; info->need_refresh = true; info->need_push = true; #if !defined(IS_SALAMANDER) && (defined(HAVE_FFMPEG) || defined(HAVE_MPV)) @@ -9446,6 +9539,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE: case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE: case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE: + case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_SORT_MODE: case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME: case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME: case DISPLAYLIST_DROPDOWN_LIST_DISK_INDEX: @@ -9505,6 +9599,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE: case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE: case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE: + case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_SORT_MODE: case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME: case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME: case DISPLAYLIST_DROPDOWN_LIST_DISK_INDEX: @@ -9558,17 +9653,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, info->need_push = true; break; case DISPLAYLIST_HORIZONTAL: - { - settings_t *settings = config_get_ptr(); - bool playlist_sort_alphabetical = settings->bools.playlist_sort_alphabetical; + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + ret = menu_displaylist_parse_horizontal_list(menu, info); - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - ret = menu_displaylist_parse_horizontal_list(menu, info, playlist_sort_alphabetical); - - info->need_sort = playlist_sort_alphabetical; - info->need_refresh = true; - info->need_push = true; - } + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; + info->need_refresh = true; + info->need_push = true; break; case DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -10190,24 +10283,22 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, use_filebrowser = true; break; case DISPLAYLIST_PLAYLIST: + menu_displaylist_parse_playlist_generic(menu, info, + path_basename(info->path), + info->path, + true, /* Is a collection */ + true, /* Enable sorting (if allowed by user config) */ + &ret); + ret = 0; /* Why do we do this...? */ + + if (ret == 0) { - settings_t *settings = config_get_ptr(); - bool playlist_sort_alphabetical = settings->bools.playlist_sort_alphabetical; - - menu_displaylist_parse_playlist_generic(menu, info, - path_basename(info->path), - info->path, - true, /* Is a collection */ - playlist_sort_alphabetical, - &ret); - ret = 0; /* Why do we do this...? */ - - if (ret == 0) - { - info->need_sort = playlist_sort_alphabetical; - info->need_refresh = true; - info->need_push = true; - } + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; + info->need_refresh = true; + info->need_push = true; } break; case DISPLAYLIST_IMAGES_HISTORY: @@ -10242,6 +10333,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, } ret = 0; + /* Playlists themselves are sorted + * > Display lists generated from playlists + * must never be sorted */ + info->need_sort = false; info->need_refresh = true; info->need_push = true; #if !defined(IS_SALAMANDER) && defined(HAVE_IMAGEVIEWER) diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index f009552225..6ced2b8328 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -63,6 +63,7 @@ enum menu_displaylist_ctl_state DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE, + DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_SORT_MODE, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME, DISPLAYLIST_DROPDOWN_LIST_DISK_INDEX, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index d0b6d98823..5670e5ffe6 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -76,6 +76,7 @@ enum menu_settings_type MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LABEL_DISPLAY_MODE, MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_RIGHT_THUMBNAIL_MODE, MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LEFT_THUMBNAIL_MODE, + MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_SORT_MODE, MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME, MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_CORE_NAME, MENU_SETTING_DROPDOWN_ITEM_DISK_INDEX, @@ -116,6 +117,7 @@ enum menu_settings_type MENU_SETTING_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE, MENU_SETTING_PLAYLIST_MANAGER_RIGHT_THUMBNAIL_MODE, MENU_SETTING_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, + MENU_SETTING_PLAYLIST_MANAGER_SORT_MODE, MENU_WIFI, MENU_ROOM, MENU_ROOM_LAN, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index ad4e11b19b..bc4c099ac9 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -15568,7 +15568,7 @@ static bool setting_append_list( &settings->uints.playlist_entry_remove_enable, MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, - playlist_entry_remove_enable, + DEFAULT_PLAYLIST_ENTRY_REMOVE_ENABLE, &group_info, &subgroup_info, parent_group, @@ -15584,7 +15584,7 @@ static bool setting_append_list( &settings->bools.playlist_sort_alphabetical, MENU_ENUM_LABEL_PLAYLIST_SORT_ALPHABETICAL, MENU_ENUM_LABEL_VALUE_PLAYLIST_SORT_ALPHABETICAL, - playlist_sort_alphabetical, + DEFAULT_PLAYLIST_SORT_ALPHABETICAL, MENU_ENUM_LABEL_VALUE_OFF, MENU_ENUM_LABEL_VALUE_ON, &group_info, @@ -15600,7 +15600,7 @@ static bool setting_append_list( &settings->bools.playlist_use_old_format, MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT, MENU_ENUM_LABEL_VALUE_PLAYLIST_USE_OLD_FORMAT, - playlist_use_old_format, + DEFAULT_PLAYLIST_USE_OLD_FORMAT, MENU_ENUM_LABEL_VALUE_OFF, MENU_ENUM_LABEL_VALUE_ON, &group_info, @@ -15635,7 +15635,7 @@ static bool setting_append_list( &settings->uints.playlist_sublabel_runtime_type, MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE, MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME_TYPE, - playlist_sublabel_runtime_type, + DEFAULT_PLAYLIST_SUBLABEL_RUNTIME_TYPE, &group_info, &subgroup_info, parent_group, @@ -15667,7 +15667,7 @@ static bool setting_append_list( &settings->uints.playlist_show_inline_core_name, MENU_ENUM_LABEL_PLAYLIST_SHOW_INLINE_CORE_NAME, MENU_ENUM_LABEL_VALUE_PLAYLIST_SHOW_INLINE_CORE_NAME, - playlist_show_inline_core_name, + DEFAULT_PLAYLIST_SHOW_INLINE_CORE_NAME, &group_info, &subgroup_info, parent_group, diff --git a/msg_hash.h b/msg_hash.h index cd261207f7..99060cf68c 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1277,6 +1277,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE, + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX, @@ -2040,6 +2041,12 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_THUMBNAIL_MODE_DEFAULT, + MENU_LABEL(PLAYLIST_MANAGER_SORT_MODE), + + MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_DEFAULT, + MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_ALPHABETICAL, + MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_SORT_MODE_OFF, + MENU_LABEL(PLAYLIST_MANAGER_CLEAN_PLAYLIST), MSG_PLAYLIST_MANAGER_CLEANING_PLAYLIST, diff --git a/playlist.c b/playlist.c index 47766e662b..83c6a7bdc0 100644 --- a/playlist.c +++ b/playlist.c @@ -47,6 +47,7 @@ struct content_playlist enum playlist_label_display_mode label_display_mode; enum playlist_thumbnail_mode right_thumbnail_mode; enum playlist_thumbnail_mode left_thumbnail_mode; + enum playlist_sort_mode sort_mode; size_t size; size_t cap; @@ -80,6 +81,7 @@ typedef struct struct string_list **current_entry_string_list_val; enum playlist_label_display_mode *current_meta_label_display_mode_val; enum playlist_thumbnail_mode *current_meta_thumbnail_mode_val; + enum playlist_sort_mode *current_meta_sort_mode_val; } JSONContext; static playlist_t *playlist_cached = NULL; @@ -1299,9 +1301,12 @@ void playlist_write_file(playlist_t *playlist, bool use_old_format) ); /* Add metadata lines - * (we add these at the end of the file to prevent - * breakage if the playlist is loaded with an older - * version of RetroArch */ + * > We add these at the end of the file to prevent + * breakage if the playlist is loaded with an older + * version of RetroArch + * > There is only room for four entries. At present + * the following metadata is excluded: + * - sort_mode */ filestream_printf( file, "default_core_path = \"%s\"\n" @@ -1339,8 +1344,8 @@ void playlist_write_file(playlist_t *playlist, bool use_old_format) STRLEN_CONST("version"), JSON_UTF8); JSON_Writer_WriteColon(context.writer); JSON_Writer_WriteSpace(context.writer, 1); - JSON_Writer_WriteString(context.writer, "1.2", - STRLEN_CONST("1.3"), JSON_UTF8); + JSON_Writer_WriteString(context.writer, "1.4", + STRLEN_CONST("1.4"), JSON_UTF8); JSON_Writer_WriteComma(context.writer); JSON_Writer_WriteNewLine(context.writer); @@ -1415,6 +1420,19 @@ void playlist_write_file(playlist_t *playlist, bool use_old_format) JSON_Writer_WriteComma(context.writer); JSON_Writer_WriteNewLine(context.writer); + uint_str[0] = '\0'; + snprintf(uint_str, sizeof(uint_str), "%u", playlist->sort_mode); + + JSON_Writer_WriteSpace(context.writer, 2); + JSON_Writer_WriteString(context.writer, "sort_mode", + STRLEN_CONST("sort_mode"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteNumber(context.writer, uint_str, + strlen(uint_str), JSON_UTF8); + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + JSON_Writer_WriteSpace(context.writer, 2); JSON_Writer_WriteString(context.writer, "items", STRLEN_CONST("items"), JSON_UTF8); @@ -1904,6 +1922,8 @@ static JSON_Parser_HandlerResult JSONNumberHandler(JSON_Parser parser, char *pVa *pCtx->current_meta_label_display_mode_val = (enum playlist_label_display_mode)strtoul(pValue, NULL, 10); else if (pCtx->current_meta_thumbnail_mode_val) *pCtx->current_meta_thumbnail_mode_val = (enum playlist_thumbnail_mode)strtoul(pValue, NULL, 10); + else if (pCtx->current_meta_sort_mode_val) + *pCtx->current_meta_sort_mode_val = (enum playlist_sort_mode)strtoul(pValue, NULL, 10); else { /* must be a value for an unknown member we aren't tracking, skip it */ @@ -1916,6 +1936,7 @@ static JSON_Parser_HandlerResult JSONNumberHandler(JSON_Parser parser, char *pVa pCtx->current_entry_uint_val = NULL; pCtx->current_meta_label_display_mode_val = NULL; pCtx->current_meta_thumbnail_mode_val = NULL; + pCtx->current_meta_sort_mode_val = NULL; return JSON_Parser_Continue; } @@ -2024,6 +2045,8 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha pCtx->current_meta_thumbnail_mode_val = &pCtx->playlist->right_thumbnail_mode; else if (string_is_equal(pValue, "left_thumbnail_mode")) pCtx->current_meta_thumbnail_mode_val = &pCtx->playlist->left_thumbnail_mode; + else if (string_is_equal(pValue, "sort_mode")) + pCtx->current_meta_sort_mode_val = &pCtx->playlist->sort_mode; else { /* ignore unknown members */ @@ -2316,6 +2339,10 @@ json_cleanup: playlist->default_core_name = strdup(default_core_name); } + /* > Sort mode is excluded from old format + * playlists - just set to default */ + playlist->sort_mode = PLAYLIST_SORT_MODE_DEFAULT; + /* Read playlist entries */ filestream_seek(file, 0, SEEK_SET); if (filestream_error(file)) @@ -2423,6 +2450,7 @@ playlist_t *playlist_init(const char *path, size_t size) playlist->label_display_mode = LABEL_DISPLAY_MODE_DEFAULT; playlist->right_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT; playlist->left_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT; + playlist->sort_mode = PLAYLIST_SORT_MODE_DEFAULT; playlist_read_file(playlist, path); @@ -2510,6 +2538,12 @@ end: void playlist_qsort(playlist_t *playlist) { + /* Avoid inadvertent sorting if 'sort mode' + * has been set explicitly to PLAYLIST_SORT_MODE_OFF */ + if (!playlist || + (playlist->sort_mode == PLAYLIST_SORT_MODE_OFF)) + return; + qsort(playlist->entries, playlist->size, sizeof(struct playlist_entry), (int (*)(const void *, const void *))playlist_qsort_func); @@ -2676,6 +2710,13 @@ enum playlist_thumbnail_mode playlist_get_thumbnail_mode( return PLAYLIST_THUMBNAIL_MODE_DEFAULT; } +enum playlist_sort_mode playlist_get_sort_mode(playlist_t *playlist) +{ + if (!playlist) + return PLAYLIST_SORT_MODE_DEFAULT; + return playlist->sort_mode; +} + void playlist_set_default_core_path(playlist_t *playlist, const char *core_path) { char real_core_path[PATH_MAX_LENGTH]; @@ -2749,3 +2790,15 @@ void playlist_set_thumbnail_mode( break; } } + +void playlist_set_sort_mode(playlist_t *playlist, enum playlist_sort_mode sort_mode) +{ + if (!playlist) + return; + + if (playlist->sort_mode != sort_mode) + { + playlist->sort_mode = sort_mode; + playlist->modified = true; + } +} diff --git a/playlist.h b/playlist.h index 8c98de5769..57e55a2f20 100644 --- a/playlist.h +++ b/playlist.h @@ -64,6 +64,13 @@ enum playlist_thumbnail_mode PLAYLIST_THUMBNAIL_MODE_BOXARTS }; +enum playlist_sort_mode +{ + PLAYLIST_SORT_MODE_DEFAULT = 0, + PLAYLIST_SORT_MODE_ALPHABETICAL, + PLAYLIST_SORT_MODE_OFF +}; + /* TODO/FIXME - since gfx_thumbnail_path.h has now * been divorced from the menu code, perhaps jdgleaver * can refactor this? */ @@ -287,12 +294,14 @@ char *playlist_get_default_core_name(playlist_t *playlist); enum playlist_label_display_mode playlist_get_label_display_mode(playlist_t *playlist); enum playlist_thumbnail_mode playlist_get_thumbnail_mode( playlist_t *playlist, enum playlist_thumbnail_id thumbnail_id); +enum playlist_sort_mode playlist_get_sort_mode(playlist_t *playlist); void playlist_set_default_core_path(playlist_t *playlist, const char *core_path); void playlist_set_default_core_name(playlist_t *playlist, const char *core_name); void playlist_set_label_display_mode(playlist_t *playlist, enum playlist_label_display_mode label_display_mode); void playlist_set_thumbnail_mode( playlist_t *playlist, enum playlist_thumbnail_id thumbnail_id, enum playlist_thumbnail_mode thumbnail_mode); +void playlist_set_sort_mode(playlist_t *playlist, enum playlist_sort_mode sort_mode); RETRO_END_DECLS diff --git a/retroarch.c b/retroarch.c index f19e1cf537..a7ecd685fc 100644 --- a/retroarch.c +++ b/retroarch.c @@ -8672,12 +8672,17 @@ bool command_event(enum event_command cmd, void *data) if (!history_list_enable) return false; + /* Note: Sorting is disabled by default for + * all content history playlists */ + RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), path_content_history); g_defaults.content_history = playlist_init( path_content_history, content_history_size); + playlist_set_sort_mode( + g_defaults.content_history, PLAYLIST_SORT_MODE_OFF); RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), @@ -8685,6 +8690,8 @@ bool command_event(enum event_command cmd, void *data) g_defaults.music_history = playlist_init( path_content_music_history, content_history_size); + playlist_set_sort_mode( + g_defaults.music_history, PLAYLIST_SORT_MODE_OFF); #if defined(HAVE_FFMPEG) || defined(HAVE_MPV) RARCH_LOG("%s: [%s].\n", @@ -8693,6 +8700,8 @@ bool command_event(enum event_command cmd, void *data) g_defaults.video_history = playlist_init( path_content_video_history, content_history_size); + playlist_set_sort_mode( + g_defaults.video_history, PLAYLIST_SORT_MODE_OFF); #endif #ifdef HAVE_IMAGEVIEWER @@ -8702,6 +8711,8 @@ bool command_event(enum event_command cmd, void *data) g_defaults.image_history = playlist_init( path_content_image_history, content_history_size); + playlist_set_sort_mode( + g_defaults.image_history, PLAYLIST_SORT_MODE_OFF); #endif } break; @@ -8858,8 +8869,12 @@ bool command_event(enum event_command cmd, void *data) if (playlist_push(g_defaults.content_favorites, &entry, playlist_fuzzy_archive_match)) { + enum playlist_sort_mode current_sort_mode = + playlist_get_sort_mode(g_defaults.content_favorites); + /* New addition - need to resort if option is enabled */ - if (playlist_sort_alphabetical) + if ((playlist_sort_alphabetical && (current_sort_mode == PLAYLIST_SORT_MODE_DEFAULT)) || + (current_sort_mode == PLAYLIST_SORT_MODE_ALPHABETICAL)) playlist_qsort(g_defaults.content_favorites); playlist_write_file(g_defaults.content_favorites, @@ -30249,6 +30264,7 @@ void rarch_favorites_init(void) int content_favorites_size = settings ? settings->ints.content_favorites_size : 0; const char *path_content_favorites = settings ? settings->paths.path_content_favorites : NULL; bool playlist_sort_alphabetical = settings ? settings->bools.playlist_sort_alphabetical : false; + enum playlist_sort_mode current_sort_mode; if (!settings) return; @@ -30265,9 +30281,13 @@ void rarch_favorites_init(void) path_content_favorites, (unsigned)content_favorites_size); + /* Get current per-playlist sort mode */ + current_sort_mode = playlist_get_sort_mode(g_defaults.content_favorites); + /* Ensure that playlist is sorted alphabetically, * if required */ - if (playlist_sort_alphabetical) + if ((playlist_sort_alphabetical && (current_sort_mode == PLAYLIST_SORT_MODE_DEFAULT)) || + (current_sort_mode == PLAYLIST_SORT_MODE_ALPHABETICAL)) playlist_qsort(g_defaults.content_favorites); } diff --git a/tasks/task_manual_content_scan.c b/tasks/task_manual_content_scan.c index 11affadbfb..496783ffa0 100644 --- a/tasks/task_manual_content_scan.c +++ b/tasks/task_manual_content_scan.c @@ -303,7 +303,9 @@ static void task_manual_content_scan_handler(retro_task_t *task) task_title[0] = '\0'; - /* Ensure playlist is alphabetically sorted */ + /* Ensure playlist is alphabetically sorted + * > Override user settings here */ + playlist_set_sort_mode(manual_scan->playlist, PLAYLIST_SORT_MODE_DEFAULT); playlist_qsort(manual_scan->playlist); /* Save playlist changes to disk */