diff --git a/apps/filetree.c b/apps/filetree.c index dff8f49be9..b5f5dece5a 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -129,8 +129,7 @@ int ft_build_playlist(struct tree_context* c, int start_index) * avoid allocating yet another path buffer on the stack (and save some * code; the caller typically needs to create the full pathname anyway)... */ -bool ft_play_playlist(char* pathname, char* dirname, - char* filename, bool skip_warn_and_bookmarks) +bool ft_play_playlist(char* pathname, char* dirname, char* filename) { if (global_settings.party_mode && audio_status()) { @@ -138,12 +137,9 @@ bool ft_play_playlist(char* pathname, char* dirname, return false; } - if (!skip_warn_and_bookmarks) - { - int res = bookmark_autoload(pathname); - if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME || !warn_on_pl_erase()) - return false; - } + int res = bookmark_autoload(pathname); + if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME || !warn_on_pl_erase()) + return false; splash(0, ID2P(LANG_WAIT)); @@ -547,7 +543,7 @@ int ft_enter(struct tree_context* c) switch ( file_attr & FILE_ATTR_MASK ) { case FILE_ATTR_M3U: - play = ft_play_playlist(buf, c->currdir, file->name, false); + play = ft_play_playlist(buf, c->currdir, file->name); if (play) { diff --git a/apps/filetree.h b/apps/filetree.h index 3ec7846d2c..ebd9885ec2 100644 --- a/apps/filetree.h +++ b/apps/filetree.h @@ -28,7 +28,6 @@ int ft_exit(struct tree_context* c); int ft_assemble_path(char *buf, size_t bufsz, const char* currdir, const char* filename); int ft_build_playlist(struct tree_context* c, int start_index); -bool ft_play_playlist(char* pathname, char* dirname, - char* filename, bool skip_warn_and_bookmarks); +bool ft_play_playlist(char* pathname, char* dirname, char* filename); #endif diff --git a/apps/iap/iap-lingo4.c b/apps/iap/iap-lingo4.c index eb629407f2..e1ab150fd9 100644 --- a/apps/iap/iap-lingo4.c +++ b/apps/iap/iap-lingo4.c @@ -109,8 +109,7 @@ static void seek_to_playlist(unsigned long index) MAX_PATH); ft_play_playlist(selected_playlist, global_settings.playlist_catalog_dir, - strrchr(selected_playlist, '/') + 1, - false); + strrchr(selected_playlist, '/') + 1); } static unsigned long nbr_total_playlists(void) diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 1287a26c39..c41033ec81 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -15936,16 +15936,16 @@ id: LANG_PLAYLIST_RELOAD_AFTER_SAVE - desc: reload playlist after saving + desc: deprecated user: core - *: "Reload After Saving" + *: "" - *: "Reload After Saving" + *: "" - *: "Reload After Saving" + *: "" @@ -16655,3 +16655,17 @@ *: "Database Directory" + + id: LANG_REMOVE_QUEUED_TRACKS + desc: Confirmation dialog + user: core + + *: "Remove Queued Tracks?" + + + *: "Remove Queued Tracks?" + + + *: "Remove Queued Tracks?" + + diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c index affe20418d..bfb94ccdad 100644 --- a/apps/menus/playlist_menu.c +++ b/apps/menus/playlist_menu.c @@ -38,7 +38,6 @@ #include "talk.h" #include "playlist_catalog.h" #include "splash.h" -#include "filetree.h" #include "general.h" /* load a screen to save the playlist passed in (or current playlist if NULL is passed) */ @@ -46,11 +45,6 @@ int save_playlist_screen(struct playlist_info* playlist) { char directoryonly[MAX_PATH+3]; - char *filename; - - int resume_index; - uint32_t resume_elapsed; - uint32_t resume_offset; char temp[MAX_PATH+1], *p; int len; @@ -86,55 +80,8 @@ int save_playlist_screen(struct playlist_info* playlist) /* reload in case playlist was saved to cwd */ reload_directory(); - - /* only reload newly saved playlist if: - * playlist is null AND setting is turned on - * - * if playlist is null, we should be dealing with the current playlist, - * and thus we got here from the wps screen. That means we want to reload - * the current playlist so the user can make bookmarks. */ - if ((global_settings.playlist_reload_after_save == true) && - (playlist == NULL)) - { - - /* at least one slash exists in temp */ - if (strrchr(temp, '/') != NULL) - { - filename = strrchr(temp, '/') + 1; - - if (temp[0] == '/') /* most common situation - first char is a slash */ - { - strcpy(directoryonly, temp); - directoryonly[filename - temp] = '\0'; - } else /* there is a slash, but not at the beginning of temp - prepend one */ - { - directoryonly[0] = '/'; - - strcpy(directoryonly+1, temp); - directoryonly[filename - temp + 1] = '\0'; - } - } else /* temp doesn't contain any slashes, uncommon? */ - { - directoryonly[0] = '/'; - directoryonly[1] = '\0'; - filename = temp; - } - - /* can't trust index from id3 (don't know why), get it from playlist */ - resume_index = playlist_get_display_index() - 1; - - struct mp3entry* id3 = audio_current_track(); - - /* record elapsed and offset so they don't change when we load new playlist */ - resume_elapsed = id3->elapsed; - resume_offset = id3->offset; - - ft_play_playlist(temp, directoryonly, filename, true); - playlist_start(resume_index, resume_elapsed, resume_offset); - } - /* cancelled out of name selection */ } else { - return 1; + return 1; /* cancelled out of name selection */ } return 0; @@ -179,14 +126,12 @@ MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL) MENUITEM_SETTING(keep_current_track_on_replace, &global_settings.keep_current_track_on_replace_playlist, NULL); MENUITEM_SETTING(show_shuffled_adding_options, &global_settings.show_shuffled_adding_options, NULL); MENUITEM_SETTING(show_queue_options, &global_settings.show_queue_options, NULL); -MENUITEM_SETTING(playlist_reload_after_save, &global_settings.playlist_reload_after_save, NULL); MAKE_MENU(currentplaylist_settings_menu, ID2P(LANG_CURRENT_PLAYLIST), NULL, Icon_Playlist, &warn_on_erase, &keep_current_track_on_replace, &show_shuffled_adding_options, - &show_queue_options, - &playlist_reload_after_save); + &show_queue_options); MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL, Icon_Playlist, diff --git a/apps/misc.c b/apps/misc.c index cb5f1cea9c..4faadb8130 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -1235,6 +1235,13 @@ int confirm_overwrite_yesno(void) return gui_syncyesno_run(&message, NULL, NULL); } +int confirm_remove_queued_yesno(void) +{ + static const char *lines[] = { ID2P(LANG_REMOVE_QUEUED_TRACKS) }; + static const struct text_message message = { lines, 1 }; + return gui_syncyesno_run(&message, NULL, NULL); +} + /* time_split_units() split time values depending on base unit unit_idx: UNIT_HOUR, UNIT_MIN, UNIT_SEC, UNIT_MS diff --git a/apps/misc.h b/apps/misc.h index 497aa04c78..fd48ccf648 100644 --- a/apps/misc.h +++ b/apps/misc.h @@ -160,6 +160,7 @@ int hex_to_rgb(const char* hex, int* color); int confirm_delete_yesno(const char *name); int confirm_overwrite_yesno(void); +int confirm_remove_queued_yesno(void); char* strrsplt(char* str, int c); char* skip_whitespace(char* const str); diff --git a/apps/playlist.c b/apps/playlist.c index 67d59d1aac..024f98d2f3 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -99,6 +99,7 @@ #include "filetypes.h" #include "icons.h" #include "system.h" +#include "misc.h" #include "lang.h" #include "talk.h" @@ -3977,6 +3978,7 @@ int playlist_save(struct playlist_info* playlist, char *filename) char tmpbuf[MAX_PATH+1]; ssize_t pathlen; int rc = 0; + bool reload_tracks = false; if (!playlist) playlist = ¤t_playlist; @@ -3996,6 +3998,17 @@ int playlist_save(struct playlist_info* playlist, char *filename) goto error; } + /* Ask if queued tracks should be removed, so that + playlist can be bookmarked after it's been saved */ + for (int i = playlist->amount - 1; i >= 0; i--) + if (playlist->indices[i] & PLAYLIST_QUEUED) + { + if (reload_tracks || (reload_tracks = (confirm_remove_queued_yesno() == YESNO_YES))) + remove_track_unlocked(playlist, i, false); + else + break; + } + rc = pl_save_playlist(playlist, save_path, tmpbuf, sizeof(tmpbuf)); if (rc < 0) { @@ -4030,5 +4043,8 @@ error: playlist_write_unlock(playlist); dc_thread_start(playlist, true); cpu_boost(false); + if (reload_tracks && playlist->started && + (audio_status() & AUDIO_STATUS_PLAY)) + audio_flush_and_reload_tracks(); return rc; } diff --git a/apps/settings.h b/apps/settings.h index 13550ffd2a..09a01b40a1 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -607,7 +607,6 @@ struct user_settings bool constrain_next_folder; /* whether next_folder is constrained to directories within start_directory */ int recursive_dir_insert; /* should directories be inserted recursively */ - bool playlist_reload_after_save; /* reload and resume playlist after saving */ bool fade_on_stop; /* fade on pause/unpause/stop */ bool playlist_shuffle; bool warnon_erase_dynplaylist; /* warn when erasing dynamic playlist */ diff --git a/apps/settings_list.c b/apps/settings_list.c index 74db7550bf..bc3708bfba 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -1412,8 +1412,6 @@ const struct settings_list settings[] = { CHOICE_SETTING(0, recursive_dir_insert, LANG_RECURSE_DIRECTORY , RECURSE_ON, "recursive directory insert", off_on_ask, NULL , 3 , ID2P(LANG_OFF), ID2P(LANG_ON), ID2P(LANG_ASK)), - OFFON_SETTING(0, playlist_reload_after_save, LANG_PLAYLIST_RELOAD_AFTER_SAVE, - false, "reload after saving playlist", NULL), /* bookmarks */ CHOICE_SETTING(0, autocreatebookmark, LANG_BOOKMARK_SETTINGS_AUTOCREATE, BOOKMARK_NO, "autocreate bookmarks", diff --git a/manual/configure_rockbox/bookmarking.tex b/manual/configure_rockbox/bookmarking.tex index c1d0f3b8bf..4168545aac 100644 --- a/manual/configure_rockbox/bookmarking.tex +++ b/manual/configure_rockbox/bookmarking.tex @@ -18,7 +18,10 @@ and does not work for tracks launched via the database. In addition, they do not work with dynamic (i.e. modified but not saved) playlists. If making a bookmark is not available, saving the playlist - is sufficient to allow a bookmark to be made.} + is sufficient to allow a bookmark to be made. Queued tracks, which are automatically + removed after playback, do not get stored to the playlist file and must + not be part of the current playlist. You need to confirm the removal of such tracks + when saving, or bookmarking will not be possible.} \begin{description} diff --git a/manual/configure_rockbox/playlist_options.tex b/manual/configure_rockbox/playlist_options.tex index d881ba5b40..a966d4be7e 100644 --- a/manual/configure_rockbox/playlist_options.tex +++ b/manual/configure_rockbox/playlist_options.tex @@ -47,13 +47,6 @@ related to playlists. If set to \setting{In Submenu}, Rockbox will move the options into a separate submenu. - \item[Reload After Saving.] - If set to \setting{Yes}, saving the current playlist from the While Playing Screen's - Context Menu will cause Rockbox to load the newly saved playlist and resume it to the - current position. This is useful for creating bookmarks after modifying or customizing - a playlist. Saving playlists outside of the While Playing Screen's Context Menu will - not be affected by this setting. - \end{description} \end{description} diff --git a/manual/main_menu/main.tex b/manual/main_menu/main.tex index 34868ca759..b017fc4431 100644 --- a/manual/main_menu/main.tex +++ b/manual/main_menu/main.tex @@ -178,8 +178,10 @@ will be saved in the Playlist Catalogue directory. \item[Save Current Playlist:] Saves the current dynamic playlist, excluding queued tracks, to the -specified file. If no path is provided then playlist is saved to the current -directory. +specified file. Asks for confirmation whether to remove queued tracks +from the current playlist, so that bookmarks can be created +(see \reference{ref:createbookmark}). +If no path is provided then playlist is saved to the current directory. \item[Reset Playlist Catalogue Directory:] Will reset the default location for playlists to the \fname{/Playlists} diff --git a/manual/rockbox_interface/wps.tex b/manual/rockbox_interface/wps.tex index 45b3860b0e..5f810261fa 100644 --- a/manual/rockbox_interface/wps.tex +++ b/manual/rockbox_interface/wps.tex @@ -223,8 +223,13 @@ enabled. It allows the assignment of a personal rating value (0 -- 10) to a track which can be displayed in the WPS and used in the Database browser. The value wraps at 10. -\subsubsection{Bookmarks} -This allows you to create a bookmark in the currently-playing track. +\subsubsection{\label{ref:createbookmark}Bookmarks} +This allows you to create a bookmark in the currently-playing track. Note that bookmarks +can only be created for directories, or for playlists stored on disk. Unsaved or modified +lists must be saved first. Queued tracks, which are automatically removed after playback, +do not get stored to the playlist file. When saving, Rockbox will offer to purge the +current playlist of such tracks, so that you'll be able to create bookmarks afterwards. +See \reference{ref:Bookmarkconfigactual} for more information on bookmarks. \subsubsection{\label{ref:trackinfoviewer}Show Track Info} \screenshot{rockbox_interface/images/ss-id3-viewer}{The track info viewer}{} diff --git a/manual/working_with_playlists/main.tex b/manual/working_with_playlists/main.tex index 45c57e34b4..dd25d41c26 100644 --- a/manual/working_with_playlists/main.tex +++ b/manual/working_with_playlists/main.tex @@ -173,7 +173,9 @@ select \setting{Save Current Playlist} or enter the context menu for the \setting{Save Current Playlist}. Either method will bring you to the \setting{Virtual Keyboard} (see \reference{sec:virtual_keyboard}), enter a filename for your playlist and -accept it and you are done. +accept it. If the current playlist contains any queued tracks, you will be +asked whether to remove them, as a prerequisiste for creating bookmarks +(see \reference{ref:createbookmark}). \subsection{Loading saved playlists} \subsubsection{Through the \setting{File Browser}}