summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2023-11-11 01:53:36 +0100
committerChristian Soffke <christian.soffke@gmail.com>2024-04-21 18:28:16 +0200
commitea5ce8034b4a1ead1227114308889511dbfa9539 (patch)
tree398889c4b91ce8781bfbd4f7751d5c0e7bb65e79 /apps
parente5c65a00392f801e39d7e3287c62bd8e4ec17cda (diff)
downloadrockbox-ea5ce8034b4a1ead1227114308889511dbfa9539.tar.gz
rockbox-ea5ce8034b4a1ead1227114308889511dbfa9539.zip
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
Diffstat (limited to 'apps')
-rw-r--r--apps/filetree.c14
-rw-r--r--apps/filetree.h3
-rw-r--r--apps/iap/iap-lingo4.c3
-rw-r--r--apps/lang/english.lang22
-rw-r--r--apps/menus/playlist_menu.c59
-rw-r--r--apps/misc.c7
-rw-r--r--apps/misc.h1
-rw-r--r--apps/playlist.c16
-rw-r--r--apps/settings.h1
-rw-r--r--apps/settings_list.c2
10 files changed, 51 insertions, 77 deletions
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)
129 * avoid allocating yet another path buffer on the stack (and save some 129 * avoid allocating yet another path buffer on the stack (and save some
130 * code; the caller typically needs to create the full pathname anyway)... 130 * code; the caller typically needs to create the full pathname anyway)...
131 */ 131 */
132bool ft_play_playlist(char* pathname, char* dirname, 132bool ft_play_playlist(char* pathname, char* dirname, char* filename)
133 char* filename, bool skip_warn_and_bookmarks)
134{ 133{
135 if (global_settings.party_mode && audio_status()) 134 if (global_settings.party_mode && audio_status())
136 { 135 {
@@ -138,12 +137,9 @@ bool ft_play_playlist(char* pathname, char* dirname,
138 return false; 137 return false;
139 } 138 }
140 139
141 if (!skip_warn_and_bookmarks) 140 int res = bookmark_autoload(pathname);
142 { 141 if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME || !warn_on_pl_erase())
143 int res = bookmark_autoload(pathname); 142 return false;
144 if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME || !warn_on_pl_erase())
145 return false;
146 }
147 143
148 splash(0, ID2P(LANG_WAIT)); 144 splash(0, ID2P(LANG_WAIT));
149 145
@@ -547,7 +543,7 @@ int ft_enter(struct tree_context* c)
547 543
548 switch ( file_attr & FILE_ATTR_MASK ) { 544 switch ( file_attr & FILE_ATTR_MASK ) {
549 case FILE_ATTR_M3U: 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 if (play) 548 if (play)
553 { 549 {
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);
28int ft_assemble_path(char *buf, size_t bufsz, 28int ft_assemble_path(char *buf, size_t bufsz,
29 const char* currdir, const char* filename); 29 const char* currdir, const char* filename);
30int ft_build_playlist(struct tree_context* c, int start_index); 30int ft_build_playlist(struct tree_context* c, int start_index);
31bool ft_play_playlist(char* pathname, char* dirname, 31bool ft_play_playlist(char* pathname, char* dirname, char* filename);
32 char* filename, bool skip_warn_and_bookmarks);
33 32
34#endif 33#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)
109 MAX_PATH); 109 MAX_PATH);
110 ft_play_playlist(selected_playlist, 110 ft_play_playlist(selected_playlist,
111 global_settings.playlist_catalog_dir, 111 global_settings.playlist_catalog_dir,
112 strrchr(selected_playlist, '/') + 1, 112 strrchr(selected_playlist, '/') + 1);
113 false);
114} 113}
115 114
116static 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 1287a26c39..c41033ec81 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -15936,16 +15936,16 @@
15936</phrase> 15936</phrase>
15937<phrase> 15937<phrase>
15938 id: LANG_PLAYLIST_RELOAD_AFTER_SAVE 15938 id: LANG_PLAYLIST_RELOAD_AFTER_SAVE
15939 desc: reload playlist after saving 15939 desc: deprecated
15940 user: core 15940 user: core
15941 <source> 15941 <source>
15942 *: "Reload After Saving" 15942 *: ""
15943 </source> 15943 </source>
15944 <dest> 15944 <dest>
15945 *: "Reload After Saving" 15945 *: ""
15946 </dest> 15946 </dest>
15947 <voice> 15947 <voice>
15948 *: "Reload After Saving" 15948 *: ""
15949 </voice> 15949 </voice>
15950</phrase> 15950</phrase>
15951<phrase> 15951<phrase>
@@ -16655,3 +16655,17 @@
16655 *: "Database Directory" 16655 *: "Database Directory"
16656 </voice> 16656 </voice>
16657</phrase> 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>
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 @@
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"
42#include "general.h" 41#include "general.h"
43 42
44/* load a screen to save the playlist passed in (or current playlist if NULL is passed) */ 43/* 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)
46{ 45{
47 46
48 char directoryonly[MAX_PATH+3]; 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 char temp[MAX_PATH+1], *p; 49 char temp[MAX_PATH+1], *p;
56 int len; 50 int len;
@@ -86,55 +80,8 @@ int save_playlist_screen(struct playlist_info* playlist)
86 80
87 /* reload in case playlist was saved to cwd */ 81 /* reload in case playlist was saved to cwd */
88 reload_directory(); 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 } else { 83 } else {
137 return 1; 84 return 1; /* cancelled out of name selection */
138 } 85 }
139 86
140 return 0; 87 return 0;
@@ -179,14 +126,12 @@ MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL)
179MENUITEM_SETTING(keep_current_track_on_replace, &global_settings.keep_current_track_on_replace_playlist, NULL); 126MENUITEM_SETTING(keep_current_track_on_replace, &global_settings.keep_current_track_on_replace_playlist, NULL);
180MENUITEM_SETTING(show_shuffled_adding_options, &global_settings.show_shuffled_adding_options, NULL); 127MENUITEM_SETTING(show_shuffled_adding_options, &global_settings.show_shuffled_adding_options, NULL);
181MENUITEM_SETTING(show_queue_options, &global_settings.show_queue_options, NULL); 128MENUITEM_SETTING(show_queue_options, &global_settings.show_queue_options, NULL);
182MENUITEM_SETTING(playlist_reload_after_save, &global_settings.playlist_reload_after_save, NULL);
183MAKE_MENU(currentplaylist_settings_menu, ID2P(LANG_CURRENT_PLAYLIST), 129MAKE_MENU(currentplaylist_settings_menu, ID2P(LANG_CURRENT_PLAYLIST),
184 NULL, Icon_Playlist, 130 NULL, Icon_Playlist,
185 &warn_on_erase, 131 &warn_on_erase,
186 &keep_current_track_on_replace, 132 &keep_current_track_on_replace,
187 &show_shuffled_adding_options, 133 &show_shuffled_adding_options,
188 &show_queue_options, 134 &show_queue_options);
189 &playlist_reload_after_save);
190 135
191MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL, 136MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLISTS), NULL,
192 Icon_Playlist, 137 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)
1235 return gui_syncyesno_run(&message, NULL, NULL); 1235 return gui_syncyesno_run(&message, NULL, NULL);
1236} 1236}
1237 1237
1238int 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/* time_split_units() 1245/* time_split_units()
1239 split time values depending on base unit 1246 split time values depending on base unit
1240 unit_idx: UNIT_HOUR, UNIT_MIN, UNIT_SEC, UNIT_MS 1247 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);
160 160
161int confirm_delete_yesno(const char *name); 161int confirm_delete_yesno(const char *name);
162int confirm_overwrite_yesno(void); 162int confirm_overwrite_yesno(void);
163int confirm_remove_queued_yesno(void);
163 164
164char* strrsplt(char* str, int c); 165char* strrsplt(char* str, int c);
165char* skip_whitespace(char* const str); 166char* 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 @@
99#include "filetypes.h" 99#include "filetypes.h"
100#include "icons.h" 100#include "icons.h"
101#include "system.h" 101#include "system.h"
102#include "misc.h"
102 103
103#include "lang.h" 104#include "lang.h"
104#include "talk.h" 105#include "talk.h"
@@ -3977,6 +3978,7 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3977 char tmpbuf[MAX_PATH+1]; 3978 char tmpbuf[MAX_PATH+1];
3978 ssize_t pathlen; 3979 ssize_t pathlen;
3979 int rc = 0; 3980 int rc = 0;
3981 bool reload_tracks = false;
3980 3982
3981 if (!playlist) 3983 if (!playlist)
3982 playlist = &current_playlist; 3984 playlist = &current_playlist;
@@ -3996,6 +3998,17 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3996 goto error; 3998 goto error;
3997 } 3999 }
3998 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 }
4011
3999 rc = pl_save_playlist(playlist, save_path, tmpbuf, sizeof(tmpbuf)); 4012 rc = pl_save_playlist(playlist, save_path, tmpbuf, sizeof(tmpbuf));
4000 if (rc < 0) 4013 if (rc < 0)
4001 { 4014 {
@@ -4030,5 +4043,8 @@ error:
4030 playlist_write_unlock(playlist); 4043 playlist_write_unlock(playlist);
4031 dc_thread_start(playlist, true); 4044 dc_thread_start(playlist, true);
4032 cpu_boost(false); 4045 cpu_boost(false);
4046 if (reload_tracks && playlist->started &&
4047 (audio_status() & AUDIO_STATUS_PLAY))
4048 audio_flush_and_reload_tracks();
4033 return rc; 4049 return rc;
4034} 4050}
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
607 bool constrain_next_folder; /* whether next_folder is constrained to 607 bool constrain_next_folder; /* whether next_folder is constrained to
608 directories within start_directory */ 608 directories within start_directory */
609 int recursive_dir_insert; /* should directories be inserted recursively */ 609 int recursive_dir_insert; /* should directories be inserted recursively */
610 bool playlist_reload_after_save; /* reload and resume playlist after saving */
611 bool fade_on_stop; /* fade on pause/unpause/stop */ 610 bool fade_on_stop; /* fade on pause/unpause/stop */
612 bool playlist_shuffle; 611 bool playlist_shuffle;
613 bool warnon_erase_dynplaylist; /* warn when erasing dynamic playlist */ 612 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[] = {
1412 CHOICE_SETTING(0, recursive_dir_insert, LANG_RECURSE_DIRECTORY , RECURSE_ON, 1412 CHOICE_SETTING(0, recursive_dir_insert, LANG_RECURSE_DIRECTORY , RECURSE_ON,
1413 "recursive directory insert", off_on_ask, NULL , 3 , 1413 "recursive directory insert", off_on_ask, NULL , 3 ,
1414 ID2P(LANG_OFF), ID2P(LANG_ON), ID2P(LANG_ASK)), 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 /* bookmarks */ 1415 /* bookmarks */
1418 CHOICE_SETTING(0, autocreatebookmark, LANG_BOOKMARK_SETTINGS_AUTOCREATE, 1416 CHOICE_SETTING(0, autocreatebookmark, LANG_BOOKMARK_SETTINGS_AUTOCREATE,
1419 BOOKMARK_NO, "autocreate bookmarks", 1417 BOOKMARK_NO, "autocreate bookmarks",