diff --git a/apps/filetree.c b/apps/filetree.c index fc5e4d3..6b96d10 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -105,11 +105,12 @@ 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; - + /* maybe save the current playlist */ + if (!playlist_maybe_save_current()) + { + return false; + } + if (playlist_create(dirname, filename) != -1) { if (global_settings.playlist_shuffle) @@ -407,11 +408,13 @@ int ft_enter(struct tree_context* c) splash(0, ID2P(LANG_WAIT)); - /* about to create a new current playlist... - allow user to cancel the operation */ - if (!warn_on_pl_erase()) - break; - + /* about to create a new current + * playlist... allow user to + * cancel the operation + */ + if (!playlist_maybe_save_current()) + break; + if (global_settings.party_mode && audio_status()) { playlist_insert_track(NULL, buf, diff --git a/apps/lang/english.lang b/apps/lang/english.lang index fceb30a..d4fee84 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -6816,6 +6816,34 @@ + id: LANG_SAVE_CURRENT_PLAYLIST_AS + desc: in "delete existing playlist" warning menu. + user: + + *: "Save Current Playlist as %s" + + + *: "Save Current Playlist as %s" + + + *: "Save Current Playlist as %s" + + + + id: LANG_SAVE_CURRENT_PLAYLIST_AS_PROMPT + desc: in "delete existing playlist" warning menu. + user: + + *: "Save Current Playlist as ..." + + + *: "Save Current Playlist as ..." + + + *: "Save Current Playlist as ..." + + + id: LANG_PLAYLIST_SAVE_COUNT desc: splash number of tracks saved user: @@ -6900,6 +6928,20 @@ + id: LANG_WARN_ERASEDYNPLAYLIST_CONTINUE + desc: option to select if we are happy to continue and erase current playlist + user: + + *: "Continue" + + + *: "Continue" + + + *: "Continue" + + + id: LANG_SHUTDOWN desc: in main menu user: diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c index 6345df9..5294c43 100644 --- a/apps/menus/playlist_menu.c +++ b/apps/menus/playlist_menu.c @@ -39,6 +39,11 @@ #include "playlist_viewer.h" #include "talk.h" #include "playlist_catalog.h" +#include "sprintf.h" + +#include "debug.h" + +extern struct playlist_info current_playlist; int save_playlist_screen(struct playlist_info* playlist) { @@ -48,10 +53,13 @@ int save_playlist_screen(struct playlist_info* playlist) playlist_get_name(playlist, temp, sizeof(temp)); len = strlen(temp); + DEBUGF("save_playlist_screen: name %s\n", temp); + + /* Make sure playlist always ends in m3u8 */ if (len > 4 && !strcasecmp(&temp[len-4], ".m3u")) strcat(temp, "8"); - if (len <= 5 || strcasecmp(&temp[len-5], ".m3u8")) + if (len <= 5) /* || strcasecmp(&temp[len-5], ".m3u8"))*/ strcpy(temp, DEFAULT_DYNAMIC_PLAYLIST_NAME); if (!kbd_input(temp, sizeof(temp))) @@ -60,10 +68,14 @@ int save_playlist_screen(struct playlist_info* playlist) /* reload in case playlist was saved to cwd */ reload_directory(); + + /* can exit menu now */ + return 1; } return 0; } + MENUITEM_FUNCTION(create_playlist_item, 0, ID2P(LANG_CREATE_PLAYLIST), (int(*)(void))create_playlist, NULL, NULL, Icon_NOICON); MENUITEM_FUNCTION(view_playlist, 0, ID2P(LANG_VIEW_DYNAMIC_PLAYLIST), @@ -84,3 +96,112 @@ MAKE_MENU(playlist_options, ID2P(LANG_PLAYLISTS), NULL, Icon_Playlist, &create_playlist_item, &view_playlist, &save_playlist, &catalog); + +/* + * Potentially save current dynamic playlist. + * + * Originally we used to warn if the dynamic playlist was going to get + * over-written. Now we offer multiple options for quick save + * + * "Erase dynamic playlist?: + * - Continue + * - Save current as "current name" + * - Save current playlist as ..." + * + * If the user aborts the menu (e.g. going "back") we return false up + * the chain and abort whatever action we were about to do + * + */ + +/* Returns "Save current as " */ +static char* pmsc_get_current_playlist(int selected_item, void * data, char *buffer) +{ + char temp[MAX_PATH],*t; + t = playlist_get_name(NULL, temp, MAX_PATH); + snprintf(buffer, MAX_PATH, str(LANG_SAVE_CURRENT_PLAYLIST_AS), t); + return buffer; +} + +/* Just save the playlist and exit */ +int save_playlist_now(struct playlist_info* playlist) +{ + char temp[MAX_PATH+1]; + int len; + + playlist_get_name(playlist, temp, sizeof(temp)); + len = strlen(temp); + + DEBUGF("save_playlist_now: name %s\n", temp); + + /* Make sure playlist always ends in m3u8 */ + if (len > 4 && !strcasecmp(&temp[len-4], ".m3u")) + strcat(temp, "8"); + + playlist_save(playlist, temp); + /* reload in case playlist was saved to cwd */ + reload_directory(); + + return 1; +} + + + + +/* Define the menu */ +MENUITEM_RETURNVALUE(pmsc_continue, + ID2P(LANG_WARN_ERASEDYNPLAYLIST_CONTINUE), /* Continue */ + 0, /* Returns 0 */ + NULL, Icon_NOICON); + +MENUITEM_FUNCTION_DYNTEXT(pmsc_save_playlist_as, + MENU_FUNC_USEPARAM|MENU_FUNC_CHECK_RETVAL, /* Parameter passed */ + (int(*)(void*))save_playlist_now, /* func */ + (void*)¤t_playlist, /* param */ + pmsc_get_current_playlist, /* txt callback */ + NULL, /* voice callback */ + ¤t_playlist, /* callback data */ + NULL, Icon_NOICON); + +MENUITEM_FUNCTION(pmsc_save_playlist, + MENU_FUNC_USEPARAM|MENU_FUNC_CHECK_RETVAL, + ID2P(LANG_SAVE_DYNAMIC_PLAYLIST), + (int(*)(void*))save_playlist_screen, + ¤t_playlist, + NULL, Icon_NOICON); + +MAKE_MENU(maybe_save_menu, ID2P(LANG_WARN_ERASEDYNPLAYLIST_PROMPT), NULL, + Icon_Playlist, + &pmsc_continue, &pmsc_save_playlist_as, &pmsc_save_playlist); + +bool playlist_maybe_save_current(void) +{ + bool r=true; + + DEBUGF("playlist_maybe_save_current: c:%s pm:%s mod:%s\n", + global_settings.warnon_erase_dynplaylist?"true":"false", + global_settings.party_mode?"true":"false", + playlist_modified(NULL)?"true":"false"); + + /* We only care if the playlist has been modified */ + if (global_settings.warnon_erase_dynplaylist && + !global_settings.party_mode && + playlist_modified(NULL)) + { + int menu_selection = 0; + int menu_r; + menu_r = do_menu(&maybe_save_menu, &menu_selection, NULL, false); + + + DEBUGF("playlist_maybe_save_current: menu_selection=%d menu_r=%d\n", + menu_selection, menu_r); + + /* Did we abort? */ + if (menu_r == GO_TO_PREVIOUS) { + r = false; + } + } + + DEBUGF("playlist_maybe_save_current: %s\n", r?"true":"false"); + return r; +} + diff --git a/apps/misc.c b/apps/misc.c index 11cdee1..82b570d 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -232,6 +232,7 @@ char *create_datetime_filename(char *buffer, const char *path, } #endif /* CONFIG_RTC */ +#if 0 /* Ask the user if they really want to erase the current dynamic playlist * returns true if the playlist should be replaced */ bool warn_on_pl_erase(void) @@ -249,6 +250,7 @@ bool warn_on_pl_erase(void) else return true; } +#endif /* Read (up to) a line of text from fd into buffer and return number of bytes * read (which may be larger than the number of bytes stored in buffer). If diff --git a/apps/playlist.c b/apps/playlist.c index 95e1b82..a6751bc 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -143,7 +143,7 @@ struct directory_search_context { int count; }; -static struct playlist_info current_playlist; +struct playlist_info current_playlist; static char now_playing[MAX_PATH+1]; static void empty_playlist(struct playlist_info* playlist, bool resume); @@ -3467,6 +3467,7 @@ int playlist_save(struct playlist_info* playlist, char *filename) return result; } + /* * Search specified directory for tracks and notify via callback. May be * called recursively. diff --git a/apps/playlist.h b/apps/playlist.h index df3bd62..8fe85fb 100644 --- a/apps/playlist.h +++ b/apps/playlist.h @@ -165,6 +165,7 @@ char *playlist_get_name(const struct playlist_info* playlist, char *buf, int playlist_get_track_info(struct playlist_info* playlist, int index, struct playlist_track_info* info); int playlist_save(struct playlist_info* playlist, char *filename); +bool playlist_maybe_save_current(void); int playlist_directory_tracksearch(const char* dirname, bool recurse, int (*callback)(char*, void*), void* context); diff --git a/apps/tagtree.c b/apps/tagtree.c index 7777a9f..99e9762 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c @@ -1495,10 +1495,10 @@ int tagtree_enter(struct tree_context* c) break; } c->dirlevel--; - /* about to create a new current playlist... - allow user to cancel the operation */ - if (!warn_on_pl_erase()) - break; + + /* maybe save the current playlist */ + if (!playlist_maybe_save_current()) + break; if (tagtree_play_folder(c) >= 0) rc = 2;