FS#13287 - Load a newly saved playlist and resume where it was

Works from any playlist saving operation accessed from the
While Playing Screen, all other playlist saving operations
are unchanged.

Now a user-selectable setting! Located in
General Settings -> Playlists -> Current Playlist ->
Reload After Saving (Yes/No)

Change-Id: I5085c3f4c56c518a812d5ee015d15cc4dca19a28
This commit is contained in:
Dana Conrad 2021-04-18 13:00:41 -05:00 committed by Solomon Peachy
parent 49edfc237b
commit 4f83e66cd4
9 changed files with 102 additions and 12 deletions

View File

@ -86,12 +86,12 @@ int ft_build_playlist(struct tree_context* c, int start_index)
* or started via bookmark autoload, true otherwise.
*
* Pointers to both the full pathname and the separated parts needed to
* avoid allocating yet another path buffer on the stack (and save some
* 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 ft_play_playlist(char* pathname, char* dirname, char* filename, bool skip_dyn_warning)
{
if (global_settings.party_mode && audio_status())
if (global_settings.party_mode && audio_status())
{
splash(HZ, ID2P(LANG_PARTY_MODE));
return false;
@ -105,9 +105,13 @@ bool ft_play_playlist(char* pathname, char* dirname, char* filename)
splash(0, ID2P(LANG_WAIT));
/* about to create a new current playlist...
allow user to cancel the operation */
if (!warn_on_pl_erase())
return false;
* allow user to cancel the operation.
* Do not show if skip_dyn_warning is true */
if (!skip_dyn_warning)
{
if (!warn_on_pl_erase())
return false;
}
if (playlist_create(dirname, filename) != -1)
{
@ -115,11 +119,11 @@ bool ft_play_playlist(char* pathname, char* dirname, char* filename)
{
playlist_shuffle(current_tick, -1);
}
playlist_start(0, 0, 0);
return true;
}
return false;
}
@ -465,7 +469,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);
play = ft_play_playlist(buf, c->currdir, file->name, false);
if (play)
{

View File

@ -26,6 +26,6 @@ int ft_load(struct tree_context* c, const char* tempdir);
int ft_enter(struct tree_context* c);
int ft_exit(struct tree_context* c);
int ft_build_playlist(struct tree_context* c, int start_index);
bool ft_play_playlist(char* pathname, char* dirname, char* filename);
bool ft_play_playlist(char* pathname, char* dirname, char* filename, bool skip_dyn_warning);
#endif

View File

@ -108,7 +108,8 @@ static void seek_to_playlist(unsigned long index)
MAX_PATH);
ft_play_playlist(selected_playlist,
global_settings.playlist_catalog_dir,
strrchr(selected_playlist, '/') + 1);
strrchr(selected_playlist, '/') + 1,
false);
}
static unsigned long nbr_total_playlists(void)

View File

@ -15778,3 +15778,17 @@
*: "Always Autolock"
</voice>
</phrase>
<phrase>
id: LANG_PLAYLIST_RELOAD_AFTER_SAVE
desc: reload playlist after saving
user: core
<source>
*: "Reload After Saving"
</source>
<dest>
*: "Reload After Saving"
</dest>
<voice>
*: "Reload After Saving"
</voice>
</phrase>

View File

@ -38,9 +38,19 @@
#include "talk.h"
#include "playlist_catalog.h"
#include "splash.h"
#include "filetree.h"
/* load a screen to save the playlist passed in (or current playlist if NULL is passed) */
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], *dot;
int len;
@ -71,6 +81,55 @@ 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_current()->index;
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 0;
@ -112,9 +171,10 @@ MAKE_MENU(viewer_settings_menu, ID2P(LANG_PLAYLISTVIEWER_SETTINGS),
MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, 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, &show_shuffled_adding_options, &show_queue_options);
&warn_on_erase, &show_shuffled_adding_options, &show_queue_options, &playlist_reload_after_save);
MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL,
Icon_Playlist,

View File

@ -456,6 +456,7 @@ static bool shuffle_playlist(void)
}
static bool save_playlist(void)
{
/* save_playlist_screen should load the newly saved playlist and resume */
save_playlist_screen(NULL);
return false;
}

View File

@ -576,6 +576,7 @@ 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 */

View File

@ -1277,6 +1277,8 @@ 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",

View File

@ -41,6 +41,13 @@ 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}