summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--manual/configure_rockbox/bookmarking.tex5
-rw-r--r--manual/configure_rockbox/playlist_options.tex7
-rw-r--r--manual/main_menu/main.tex6
-rw-r--r--manual/rockbox_interface/wps.tex9
-rw-r--r--manual/working_with_playlists/main.tex4
15 files changed, 69 insertions, 90 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",
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 @@
18 and does not work for tracks launched via the 18 and does not work for tracks launched via the
19 database. In addition, they do not work with dynamic (i.e. modified but not saved) 19 database. In addition, they do not work with dynamic (i.e. modified but not saved)
20 playlists. If making a bookmark is not available, saving the playlist 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 \begin{description} 26 \begin{description}
24 27
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.
47 If set to \setting{In Submenu}, Rockbox will move the options into a 47 If set to \setting{In Submenu}, Rockbox will move the options into a
48 separate submenu. 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 \end{description} 50 \end{description}
58 51
59\end{description} 52\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.
178 178
179\item[Save Current Playlist:] 179\item[Save Current Playlist:]
180 Saves the current dynamic playlist, excluding queued tracks, to the 180 Saves the current dynamic playlist, excluding queued tracks, to the
181specified file. If no path is provided then playlist is saved to the current 181specified file. Asks for confirmation whether to remove queued tracks
182directory. 182from the current playlist, so that bookmarks can be created
183(see \reference{ref:createbookmark}).
184If no path is provided then playlist is saved to the current directory.
183 185
184\item[Reset Playlist Catalogue Directory:] 186\item[Reset Playlist Catalogue Directory:]
185 Will reset the default location for playlists to the \fname{/Playlists} 187 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)
223to a track which can be displayed in the WPS and used in the Database 223to a track which can be displayed in the WPS and used in the Database
224browser. The value wraps at 10. 224browser. The value wraps at 10.
225 225
226\subsubsection{Bookmarks} 226\subsubsection{\label{ref:createbookmark}Bookmarks}
227This allows you to create a bookmark in the currently-playing track. 227This allows you to create a bookmark in the currently-playing track. Note that bookmarks
228can only be created for directories, or for playlists stored on disk. Unsaved or modified
229lists must be saved first. Queued tracks, which are automatically removed after playback,
230do not get stored to the playlist file. When saving, Rockbox will offer to purge the
231current playlist of such tracks, so that you'll be able to create bookmarks afterwards.
232See \reference{ref:Bookmarkconfigactual} for more information on bookmarks.
228 233
229\subsubsection{\label{ref:trackinfoviewer}Show Track Info} 234\subsubsection{\label{ref:trackinfoviewer}Show Track Info}
230\screenshot{rockbox_interface/images/ss-id3-viewer}{The track info viewer}{} 235\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
173\setting{Save Current Playlist}. 173\setting{Save Current Playlist}.
174Either method will bring you to the \setting{Virtual Keyboard} (see 174Either method will bring you to the \setting{Virtual Keyboard} (see
175\reference{sec:virtual_keyboard}), enter a filename for your playlist and 175\reference{sec:virtual_keyboard}), enter a filename for your playlist and
176accept it and you are done. 176accept it. If the current playlist contains any queued tracks, you will be
177asked whether to remove them, as a prerequisiste for creating bookmarks
178(see \reference{ref:createbookmark}).
177 179
178\subsection{Loading saved playlists} 180\subsection{Loading saved playlists}
179\subsubsection{Through the \setting{File Browser}} 181\subsubsection{Through the \setting{File Browser}}