Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Replace "Reload After Saving" with option to remove queued tracks

The "Reload After Saving" setting was added in
g3347 (4f83e66) to solve FS#13287, by allowing
you to bookmark a modified playlist after saving,
without having to manually reload it first.

Since the rewrite of playlist_save in g5192
(90e3571), a modified playlist doesn't have to be
reloaded anymore in order to be bookmarked after
it's been saved, unless it contains queued tracks.

To cover the remaining use cases of the previously
available option, Rockbox will now offer to remove
any queued tracks from a playlist when saving it.

Change-Id: I2d6f12bcce14d8ff41a4d921ce84d628774103ac

+69 -90
+5 -9
apps/filetree.c
··· 129 129 * avoid allocating yet another path buffer on the stack (and save some 130 130 * code; the caller typically needs to create the full pathname anyway)... 131 131 */ 132 - bool ft_play_playlist(char* pathname, char* dirname, 133 - char* filename, bool skip_warn_and_bookmarks) 132 + bool ft_play_playlist(char* pathname, char* dirname, char* filename) 134 133 { 135 134 if (global_settings.party_mode && audio_status()) 136 135 { ··· 138 137 return false; 139 138 } 140 139 141 - if (!skip_warn_and_bookmarks) 142 - { 143 - int res = bookmark_autoload(pathname); 144 - if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME || !warn_on_pl_erase()) 145 - return false; 146 - } 140 + int res = bookmark_autoload(pathname); 141 + if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME || !warn_on_pl_erase()) 142 + return false; 147 143 148 144 splash(0, ID2P(LANG_WAIT)); 149 145 ··· 547 543 548 544 switch ( file_attr & FILE_ATTR_MASK ) { 549 545 case FILE_ATTR_M3U: 550 - play = ft_play_playlist(buf, c->currdir, file->name, false); 546 + play = ft_play_playlist(buf, c->currdir, file->name); 551 547 552 548 if (play) 553 549 {
+1 -2
apps/filetree.h
··· 28 28 int ft_assemble_path(char *buf, size_t bufsz, 29 29 const char* currdir, const char* filename); 30 30 int ft_build_playlist(struct tree_context* c, int start_index); 31 - bool ft_play_playlist(char* pathname, char* dirname, 32 - char* filename, bool skip_warn_and_bookmarks); 31 + bool ft_play_playlist(char* pathname, char* dirname, char* filename); 33 32 34 33 #endif
+1 -2
apps/iap/iap-lingo4.c
··· 109 109 MAX_PATH); 110 110 ft_play_playlist(selected_playlist, 111 111 global_settings.playlist_catalog_dir, 112 - strrchr(selected_playlist, '/') + 1, 113 - false); 112 + strrchr(selected_playlist, '/') + 1); 114 113 } 115 114 116 115 static unsigned long nbr_total_playlists(void)
+18 -4
apps/lang/english.lang
··· 15936 15936 </phrase> 15937 15937 <phrase> 15938 15938 id: LANG_PLAYLIST_RELOAD_AFTER_SAVE 15939 - desc: reload playlist after saving 15939 + desc: deprecated 15940 15940 user: core 15941 15941 <source> 15942 - *: "Reload After Saving" 15942 + *: "" 15943 15943 </source> 15944 15944 <dest> 15945 - *: "Reload After Saving" 15945 + *: "" 15946 15946 </dest> 15947 15947 <voice> 15948 - *: "Reload After Saving" 15948 + *: "" 15949 15949 </voice> 15950 15950 </phrase> 15951 15951 <phrase> ··· 16655 16655 *: "Database Directory" 16656 16656 </voice> 16657 16657 </phrase> 16658 + <phrase> 16659 + id: LANG_REMOVE_QUEUED_TRACKS 16660 + desc: Confirmation dialog 16661 + user: core 16662 + <source> 16663 + *: "Remove Queued Tracks?" 16664 + </source> 16665 + <dest> 16666 + *: "Remove Queued Tracks?" 16667 + </dest> 16668 + <voice> 16669 + *: "Remove Queued Tracks?" 16670 + </voice> 16671 + </phrase>
+2 -57
apps/menus/playlist_menu.c
··· 38 38 #include "talk.h" 39 39 #include "playlist_catalog.h" 40 40 #include "splash.h" 41 - #include "filetree.h" 42 41 #include "general.h" 43 42 44 43 /* load a screen to save the playlist passed in (or current playlist if NULL is passed) */ ··· 46 45 { 47 46 48 47 char directoryonly[MAX_PATH+3]; 49 - char *filename; 50 - 51 - int resume_index; 52 - uint32_t resume_elapsed; 53 - uint32_t resume_offset; 54 48 55 49 char temp[MAX_PATH+1], *p; 56 50 int len; ··· 86 80 87 81 /* reload in case playlist was saved to cwd */ 88 82 reload_directory(); 89 - 90 - /* only reload newly saved playlist if: 91 - * playlist is null AND setting is turned on 92 - * 93 - * if playlist is null, we should be dealing with the current playlist, 94 - * and thus we got here from the wps screen. That means we want to reload 95 - * the current playlist so the user can make bookmarks. */ 96 - if ((global_settings.playlist_reload_after_save == true) && 97 - (playlist == NULL)) 98 - { 99 - 100 - /* at least one slash exists in temp */ 101 - if (strrchr(temp, '/') != NULL) 102 - { 103 - filename = strrchr(temp, '/') + 1; 104 - 105 - if (temp[0] == '/') /* most common situation - first char is a slash */ 106 - { 107 - strcpy(directoryonly, temp); 108 - directoryonly[filename - temp] = '\0'; 109 - } else /* there is a slash, but not at the beginning of temp - prepend one */ 110 - { 111 - directoryonly[0] = '/'; 112 - 113 - strcpy(directoryonly+1, temp); 114 - directoryonly[filename - temp + 1] = '\0'; 115 - } 116 - } else /* temp doesn't contain any slashes, uncommon? */ 117 - { 118 - directoryonly[0] = '/'; 119 - directoryonly[1] = '\0'; 120 - filename = temp; 121 - } 122 - 123 - /* can't trust index from id3 (don't know why), get it from playlist */ 124 - resume_index = playlist_get_display_index() - 1; 125 - 126 - struct mp3entry* id3 = audio_current_track(); 127 - 128 - /* record elapsed and offset so they don't change when we load new playlist */ 129 - resume_elapsed = id3->elapsed; 130 - resume_offset = id3->offset; 131 - 132 - ft_play_playlist(temp, directoryonly, filename, true); 133 - playlist_start(resume_index, resume_elapsed, resume_offset); 134 - } 135 - /* cancelled out of name selection */ 136 83 } else { 137 - return 1; 84 + return 1; /* cancelled out of name selection */ 138 85 } 139 86 140 87 return 0; ··· 179 126 MENUITEM_SETTING(keep_current_track_on_replace, &global_settings.keep_current_track_on_replace_playlist, NULL); 180 127 MENUITEM_SETTING(show_shuffled_adding_options, &global_settings.show_shuffled_adding_options, NULL); 181 128 MENUITEM_SETTING(show_queue_options, &global_settings.show_queue_options, NULL); 182 - MENUITEM_SETTING(playlist_reload_after_save, &global_settings.playlist_reload_after_save, NULL); 183 129 MAKE_MENU(currentplaylist_settings_menu, ID2P(LANG_CURRENT_PLAYLIST), 184 130 NULL, Icon_Playlist, 185 131 &warn_on_erase, 186 132 &keep_current_track_on_replace, 187 133 &show_shuffled_adding_options, 188 - &show_queue_options, 189 - &playlist_reload_after_save); 134 + &show_queue_options); 190 135 191 136 MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL, 192 137 Icon_Playlist,
+7
apps/misc.c
··· 1235 1235 return gui_syncyesno_run(&message, NULL, NULL); 1236 1236 } 1237 1237 1238 + int confirm_remove_queued_yesno(void) 1239 + { 1240 + static const char *lines[] = { ID2P(LANG_REMOVE_QUEUED_TRACKS) }; 1241 + static const struct text_message message = { lines, 1 }; 1242 + return gui_syncyesno_run(&message, NULL, NULL); 1243 + } 1244 + 1238 1245 /* time_split_units() 1239 1246 split time values depending on base unit 1240 1247 unit_idx: UNIT_HOUR, UNIT_MIN, UNIT_SEC, UNIT_MS
+1
apps/misc.h
··· 160 160 161 161 int confirm_delete_yesno(const char *name); 162 162 int confirm_overwrite_yesno(void); 163 + int confirm_remove_queued_yesno(void); 163 164 164 165 char* strrsplt(char* str, int c); 165 166 char* skip_whitespace(char* const str);
+16
apps/playlist.c
··· 99 99 #include "filetypes.h" 100 100 #include "icons.h" 101 101 #include "system.h" 102 + #include "misc.h" 102 103 103 104 #include "lang.h" 104 105 #include "talk.h" ··· 3977 3978 char tmpbuf[MAX_PATH+1]; 3978 3979 ssize_t pathlen; 3979 3980 int rc = 0; 3981 + bool reload_tracks = false; 3980 3982 3981 3983 if (!playlist) 3982 3984 playlist = &current_playlist; ··· 3995 3997 rc = -1; 3996 3998 goto error; 3997 3999 } 4000 + 4001 + /* Ask if queued tracks should be removed, so that 4002 + playlist can be bookmarked after it's been saved */ 4003 + for (int i = playlist->amount - 1; i >= 0; i--) 4004 + if (playlist->indices[i] & PLAYLIST_QUEUED) 4005 + { 4006 + if (reload_tracks || (reload_tracks = (confirm_remove_queued_yesno() == YESNO_YES))) 4007 + remove_track_unlocked(playlist, i, false); 4008 + else 4009 + break; 4010 + } 3998 4011 3999 4012 rc = pl_save_playlist(playlist, save_path, tmpbuf, sizeof(tmpbuf)); 4000 4013 if (rc < 0) ··· 4030 4043 playlist_write_unlock(playlist); 4031 4044 dc_thread_start(playlist, true); 4032 4045 cpu_boost(false); 4046 + if (reload_tracks && playlist->started && 4047 + (audio_status() & AUDIO_STATUS_PLAY)) 4048 + audio_flush_and_reload_tracks(); 4033 4049 return rc; 4034 4050 }
-1
apps/settings.h
··· 607 607 bool constrain_next_folder; /* whether next_folder is constrained to 608 608 directories within start_directory */ 609 609 int recursive_dir_insert; /* should directories be inserted recursively */ 610 - bool playlist_reload_after_save; /* reload and resume playlist after saving */ 611 610 bool fade_on_stop; /* fade on pause/unpause/stop */ 612 611 bool playlist_shuffle; 613 612 bool warnon_erase_dynplaylist; /* warn when erasing dynamic playlist */
-2
apps/settings_list.c
··· 1412 1412 CHOICE_SETTING(0, recursive_dir_insert, LANG_RECURSE_DIRECTORY , RECURSE_ON, 1413 1413 "recursive directory insert", off_on_ask, NULL , 3 , 1414 1414 ID2P(LANG_OFF), ID2P(LANG_ON), ID2P(LANG_ASK)), 1415 - OFFON_SETTING(0, playlist_reload_after_save, LANG_PLAYLIST_RELOAD_AFTER_SAVE, 1416 - false, "reload after saving playlist", NULL), 1417 1415 /* bookmarks */ 1418 1416 CHOICE_SETTING(0, autocreatebookmark, LANG_BOOKMARK_SETTINGS_AUTOCREATE, 1419 1417 BOOKMARK_NO, "autocreate bookmarks",
+4 -1
manual/configure_rockbox/bookmarking.tex
··· 18 18 and does not work for tracks launched via the 19 19 database. In addition, they do not work with dynamic (i.e. modified but not saved) 20 20 playlists. If making a bookmark is not available, saving the playlist 21 - is sufficient to allow a bookmark to be made.} 21 + is sufficient to allow a bookmark to be made. Queued tracks, which are automatically 22 + removed after playback, do not get stored to the playlist file and must 23 + not be part of the current playlist. You need to confirm the removal of such tracks 24 + when saving, or bookmarking will not be possible.} 22 25 23 26 \begin{description} 24 27
-7
manual/configure_rockbox/playlist_options.tex
··· 47 47 If set to \setting{In Submenu}, Rockbox will move the options into a 48 48 separate submenu. 49 49 50 - \item[Reload After Saving.] 51 - If set to \setting{Yes}, saving the current playlist from the While Playing Screen's 52 - Context Menu will cause Rockbox to load the newly saved playlist and resume it to the 53 - current position. This is useful for creating bookmarks after modifying or customizing 54 - a playlist. Saving playlists outside of the While Playing Screen's Context Menu will 55 - not be affected by this setting. 56 - 57 50 \end{description} 58 51 59 52 \end{description}
+4 -2
manual/main_menu/main.tex
··· 178 178 179 179 \item[Save Current Playlist:] 180 180 Saves the current dynamic playlist, excluding queued tracks, to the 181 - specified file. If no path is provided then playlist is saved to the current 182 - directory. 181 + specified file. Asks for confirmation whether to remove queued tracks 182 + from the current playlist, so that bookmarks can be created 183 + (see \reference{ref:createbookmark}). 184 + If no path is provided then playlist is saved to the current directory. 183 185 184 186 \item[Reset Playlist Catalogue Directory:] 185 187 Will reset the default location for playlists to the \fname{/Playlists}
+7 -2
manual/rockbox_interface/wps.tex
··· 223 223 to a track which can be displayed in the WPS and used in the Database 224 224 browser. The value wraps at 10. 225 225 226 - \subsubsection{Bookmarks} 227 - This allows you to create a bookmark in the currently-playing track. 226 + \subsubsection{\label{ref:createbookmark}Bookmarks} 227 + This allows you to create a bookmark in the currently-playing track. Note that bookmarks 228 + can only be created for directories, or for playlists stored on disk. Unsaved or modified 229 + lists must be saved first. Queued tracks, which are automatically removed after playback, 230 + do not get stored to the playlist file. When saving, Rockbox will offer to purge the 231 + current playlist of such tracks, so that you'll be able to create bookmarks afterwards. 232 + See \reference{ref:Bookmarkconfigactual} for more information on bookmarks. 228 233 229 234 \subsubsection{\label{ref:trackinfoviewer}Show Track Info} 230 235 \screenshot{rockbox_interface/images/ss-id3-viewer}{The track info viewer}{}
+3 -1
manual/working_with_playlists/main.tex
··· 173 173 \setting{Save Current Playlist}. 174 174 Either method will bring you to the \setting{Virtual Keyboard} (see 175 175 \reference{sec:virtual_keyboard}), enter a filename for your playlist and 176 - accept it and you are done. 176 + accept it. If the current playlist contains any queued tracks, you will be 177 + asked whether to remove them, as a prerequisiste for creating bookmarks 178 + (see \reference{ref:createbookmark}). 177 179 178 180 \subsection{Loading saved playlists} 179 181 \subsubsection{Through the \setting{File Browser}}