summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDana Conrad <dconrad@fastmail.com>2021-04-18 13:00:41 -0500
committerSolomon Peachy <pizza@shaftnet.org>2021-05-03 20:10:27 +0000
commit4f83e66cd4e00bfa225f54b2c314a3d42d09ca7a (patch)
tree186717c39b55272249efc681091912a49e4872f2
parent49edfc237ba9ae27eee5e915e86989d9ee01b1da (diff)
downloadrockbox-4f83e66cd4e00bfa225f54b2c314a3d42d09ca7a.tar.gz
rockbox-4f83e66cd4e00bfa225f54b2c314a3d42d09ca7a.zip
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
-rw-r--r--apps/filetree.c22
-rw-r--r--apps/filetree.h2
-rw-r--r--apps/iap/iap-lingo4.c3
-rw-r--r--apps/lang/english.lang14
-rw-r--r--apps/menus/playlist_menu.c62
-rw-r--r--apps/onplay.c1
-rw-r--r--apps/settings.h1
-rw-r--r--apps/settings_list.c2
-rw-r--r--manual/configure_rockbox/playlist_options.tex7
9 files changed, 102 insertions, 12 deletions
diff --git a/apps/filetree.c b/apps/filetree.c
index f8a1263e7f..5c6443cc34 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -86,12 +86,12 @@ int ft_build_playlist(struct tree_context* c, int start_index)
86 * or started via bookmark autoload, true otherwise. 86 * or started via bookmark autoload, true otherwise.
87 * 87 *
88 * Pointers to both the full pathname and the separated parts needed to 88 * Pointers to both the full pathname and the separated parts needed to
89 * avoid allocating yet another path buffer on the stack (and save some 89 * avoid allocating yet another path buffer on the stack (and save some
90 * code; the caller typically needs to create the full pathname anyway)... 90 * code; the caller typically needs to create the full pathname anyway)...
91 */ 91 */
92bool ft_play_playlist(char* pathname, char* dirname, char* filename) 92bool ft_play_playlist(char* pathname, char* dirname, char* filename, bool skip_dyn_warning)
93{ 93{
94 if (global_settings.party_mode && audio_status()) 94 if (global_settings.party_mode && audio_status())
95 { 95 {
96 splash(HZ, ID2P(LANG_PARTY_MODE)); 96 splash(HZ, ID2P(LANG_PARTY_MODE));
97 return false; 97 return false;
@@ -105,9 +105,13 @@ bool ft_play_playlist(char* pathname, char* dirname, char* filename)
105 splash(0, ID2P(LANG_WAIT)); 105 splash(0, ID2P(LANG_WAIT));
106 106
107 /* about to create a new current playlist... 107 /* about to create a new current playlist...
108 allow user to cancel the operation */ 108 * allow user to cancel the operation.
109 if (!warn_on_pl_erase()) 109 * Do not show if skip_dyn_warning is true */
110 return false; 110 if (!skip_dyn_warning)
111 {
112 if (!warn_on_pl_erase())
113 return false;
114 }
111 115
112 if (playlist_create(dirname, filename) != -1) 116 if (playlist_create(dirname, filename) != -1)
113 { 117 {
@@ -115,11 +119,11 @@ bool ft_play_playlist(char* pathname, char* dirname, char* filename)
115 { 119 {
116 playlist_shuffle(current_tick, -1); 120 playlist_shuffle(current_tick, -1);
117 } 121 }
118 122
119 playlist_start(0, 0, 0); 123 playlist_start(0, 0, 0);
120 return true; 124 return true;
121 } 125 }
122 126
123 return false; 127 return false;
124} 128}
125 129
@@ -465,7 +469,7 @@ int ft_enter(struct tree_context* c)
465 469
466 switch ( file_attr & FILE_ATTR_MASK ) { 470 switch ( file_attr & FILE_ATTR_MASK ) {
467 case FILE_ATTR_M3U: 471 case FILE_ATTR_M3U:
468 play = ft_play_playlist(buf, c->currdir, file->name); 472 play = ft_play_playlist(buf, c->currdir, file->name, false);
469 473
470 if (play) 474 if (play)
471 { 475 {
diff --git a/apps/filetree.h b/apps/filetree.h
index fb329813c1..178ba0e973 100644
--- a/apps/filetree.h
+++ b/apps/filetree.h
@@ -26,6 +26,6 @@ int ft_load(struct tree_context* c, const char* tempdir);
26int ft_enter(struct tree_context* c); 26int ft_enter(struct tree_context* c);
27int ft_exit(struct tree_context* c); 27int ft_exit(struct tree_context* c);
28int ft_build_playlist(struct tree_context* c, int start_index); 28int ft_build_playlist(struct tree_context* c, int start_index);
29bool ft_play_playlist(char* pathname, char* dirname, char* filename); 29bool ft_play_playlist(char* pathname, char* dirname, char* filename, bool skip_dyn_warning);
30 30
31#endif 31#endif
diff --git a/apps/iap/iap-lingo4.c b/apps/iap/iap-lingo4.c
index b601501b3d..4ec5c462a1 100644
--- a/apps/iap/iap-lingo4.c
+++ b/apps/iap/iap-lingo4.c
@@ -108,7 +108,8 @@ static void seek_to_playlist(unsigned long index)
108 MAX_PATH); 108 MAX_PATH);
109 ft_play_playlist(selected_playlist, 109 ft_play_playlist(selected_playlist,
110 global_settings.playlist_catalog_dir, 110 global_settings.playlist_catalog_dir,
111 strrchr(selected_playlist, '/') + 1); 111 strrchr(selected_playlist, '/') + 1,
112 false);
112} 113}
113 114
114static unsigned long nbr_total_playlists(void) 115static unsigned long nbr_total_playlists(void)
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 9cd31363c9..4cbc6f30f6 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -15778,3 +15778,17 @@
15778 *: "Always Autolock" 15778 *: "Always Autolock"
15779 </voice> 15779 </voice>
15780</phrase> 15780</phrase>
15781<phrase>
15782 id: LANG_PLAYLIST_RELOAD_AFTER_SAVE
15783 desc: reload playlist after saving
15784 user: core
15785 <source>
15786 *: "Reload After Saving"
15787 </source>
15788 <dest>
15789 *: "Reload After Saving"
15790 </dest>
15791 <voice>
15792 *: "Reload After Saving"
15793 </voice>
15794</phrase>
diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c
index 3122a4090f..b84abe0b37 100644
--- a/apps/menus/playlist_menu.c
+++ b/apps/menus/playlist_menu.c
@@ -38,9 +38,19 @@
38#include "talk.h" 38#include "talk.h"
39#include "playlist_catalog.h" 39#include "playlist_catalog.h"
40#include "splash.h" 40#include "splash.h"
41#include "filetree.h"
41 42
43/* load a screen to save the playlist passed in (or current playlist if NULL is passed) */
42int save_playlist_screen(struct playlist_info* playlist) 44int save_playlist_screen(struct playlist_info* playlist)
43{ 45{
46
47 char directoryonly[MAX_PATH+3];
48 char *filename;
49
50 int resume_index;
51 uint32_t resume_elapsed;
52 uint32_t resume_offset;
53
44 char temp[MAX_PATH+1], *dot; 54 char temp[MAX_PATH+1], *dot;
45 int len; 55 int len;
46 56
@@ -71,6 +81,55 @@ int save_playlist_screen(struct playlist_info* playlist)
71 81
72 /* reload in case playlist was saved to cwd */ 82 /* reload in case playlist was saved to cwd */
73 reload_directory(); 83 reload_directory();
84
85 /* only reload newly saved playlist if:
86 * playlist is null AND setting is turned on
87 *
88 * if playlist is null, we should be dealing with the current playlist,
89 * and thus we got here from the wps screen. That means we want to reload
90 * the current playlist so the user can make bookmarks. */
91 if ((global_settings.playlist_reload_after_save == true) &&
92 (playlist == NULL))
93 {
94
95 /* at least one slash exists in temp */
96 if (strrchr(temp, '/') != NULL)
97 {
98 filename = strrchr(temp, '/') + 1;
99
100 if (temp[0] == '/') /* most common situation - first char is a slash */
101 {
102 strcpy(directoryonly, temp);
103 directoryonly[filename - temp] = '\0';
104 } else /* there is a slash, but not at the beginning of temp - prepend one */
105 {
106 directoryonly[0] = '/';
107
108 strcpy(directoryonly+1, temp);
109 directoryonly[filename - temp + 1] = '\0';
110 }
111 } else /* temp doesn't contain any slashes, uncommon? */
112 {
113 directoryonly[0] = '/';
114 directoryonly[1] = '\0';
115 filename = temp;
116 }
117
118 /* can't trust index from id3 (don't know why), get it from playlist */
119 resume_index = playlist_get_current()->index;
120
121 struct mp3entry* id3 = audio_current_track();
122
123 /* record elapsed and offset so they don't change when we load new playlist */
124 resume_elapsed = id3->elapsed;
125 resume_offset = id3->offset;
126
127 ft_play_playlist(temp, directoryonly, filename, true);
128 playlist_start(resume_index, resume_elapsed, resume_offset);
129 }
130 /* cancelled out of name selection */
131 } else {
132 return 1;
74 } 133 }
75 134
76 return 0; 135 return 0;
@@ -112,9 +171,10 @@ MAKE_MENU(viewer_settings_menu, ID2P(LANG_PLAYLISTVIEWER_SETTINGS),
112MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL); 171MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL);
113MENUITEM_SETTING(show_shuffled_adding_options, &global_settings.show_shuffled_adding_options, NULL); 172MENUITEM_SETTING(show_shuffled_adding_options, &global_settings.show_shuffled_adding_options, NULL);
114MENUITEM_SETTING(show_queue_options, &global_settings.show_queue_options, NULL); 173MENUITEM_SETTING(show_queue_options, &global_settings.show_queue_options, NULL);
174MENUITEM_SETTING(playlist_reload_after_save, &global_settings.playlist_reload_after_save, NULL);
115MAKE_MENU(currentplaylist_settings_menu, ID2P(LANG_CURRENT_PLAYLIST), 175MAKE_MENU(currentplaylist_settings_menu, ID2P(LANG_CURRENT_PLAYLIST),
116 NULL, Icon_Playlist, 176 NULL, Icon_Playlist,
117 &warn_on_erase, &show_shuffled_adding_options, &show_queue_options); 177 &warn_on_erase, &show_shuffled_adding_options, &show_queue_options, &playlist_reload_after_save);
118 178
119MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL, 179MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL,
120 Icon_Playlist, 180 Icon_Playlist,
diff --git a/apps/onplay.c b/apps/onplay.c
index d72f592f2e..0942d69d3f 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -456,6 +456,7 @@ static bool shuffle_playlist(void)
456} 456}
457static bool save_playlist(void) 457static bool save_playlist(void)
458{ 458{
459 /* save_playlist_screen should load the newly saved playlist and resume */
459 save_playlist_screen(NULL); 460 save_playlist_screen(NULL);
460 return false; 461 return false;
461} 462}
diff --git a/apps/settings.h b/apps/settings.h
index 5d6d4cb717..fedec8e025 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -576,6 +576,7 @@ struct user_settings
576 bool constrain_next_folder; /* whether next_folder is constrained to 576 bool constrain_next_folder; /* whether next_folder is constrained to
577 directories within start_directory */ 577 directories within start_directory */
578 int recursive_dir_insert; /* should directories be inserted recursively */ 578 int recursive_dir_insert; /* should directories be inserted recursively */
579 bool playlist_reload_after_save; /* reload and resume playlist after saving */
579 bool fade_on_stop; /* fade on pause/unpause/stop */ 580 bool fade_on_stop; /* fade on pause/unpause/stop */
580 bool playlist_shuffle; 581 bool playlist_shuffle;
581 bool warnon_erase_dynplaylist; /* warn when erasing dynamic playlist */ 582 bool warnon_erase_dynplaylist; /* warn when erasing dynamic playlist */
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 4a0bf96864..c13df734e6 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1277,6 +1277,8 @@ const struct settings_list settings[] = {
1277 CHOICE_SETTING(0, recursive_dir_insert, LANG_RECURSE_DIRECTORY , RECURSE_ON, 1277 CHOICE_SETTING(0, recursive_dir_insert, LANG_RECURSE_DIRECTORY , RECURSE_ON,
1278 "recursive directory insert", off_on_ask, NULL , 3 , 1278 "recursive directory insert", off_on_ask, NULL , 3 ,
1279 ID2P(LANG_OFF), ID2P(LANG_ON), ID2P(LANG_ASK)), 1279 ID2P(LANG_OFF), ID2P(LANG_ON), ID2P(LANG_ASK)),
1280 OFFON_SETTING(0, playlist_reload_after_save, LANG_PLAYLIST_RELOAD_AFTER_SAVE,
1281 false, "reload after saving playlist", NULL),
1280 /* bookmarks */ 1282 /* bookmarks */
1281 CHOICE_SETTING(0, autocreatebookmark, LANG_BOOKMARK_SETTINGS_AUTOCREATE, 1283 CHOICE_SETTING(0, autocreatebookmark, LANG_BOOKMARK_SETTINGS_AUTOCREATE,
1282 BOOKMARK_NO, "autocreate bookmarks", 1284 BOOKMARK_NO, "autocreate bookmarks",
diff --git a/manual/configure_rockbox/playlist_options.tex b/manual/configure_rockbox/playlist_options.tex
index bd493d6e4b..4f6024127e 100644
--- a/manual/configure_rockbox/playlist_options.tex
+++ b/manual/configure_rockbox/playlist_options.tex
@@ -41,6 +41,13 @@ related to playlists.
41 If set to \setting{In Submenu}, Rockbox will move the options into a 41 If set to \setting{In Submenu}, Rockbox will move the options into a
42 separate submenu. 42 separate submenu.
43 43
44 \item[Reload After Saving.]
45 If set to \setting{Yes}, saving the current playlist from the While Playing Screen's
46 Context Menu will cause Rockbox to load the newly saved playlist and resume it to the
47 current position. This is useful for creating bookmarks after modifying or customizing
48 a playlist. Saving playlists outside of the While Playing Screen's Context Menu will
49 not be affected by this setting.
50
44 \end{description} 51 \end{description}
45 52
46\end{description} 53\end{description}