From e61a5c957c2f2cb1f46e40cdbc27f2b9dd32201b Mon Sep 17 00:00:00 2001 From: Christian Soffke Date: Tue, 16 Aug 2022 13:57:14 +0200 Subject: [PATCH] PictureFlow: Add ability to insert into playlists Songs or albums can now be added to new or existing playlists directly from PictureFlow. Change-Id: I6ea27e393fee0d5688385f9e91cf835be1756a7a --- apps/plugin.c | 1 + apps/plugin.h | 4 +- apps/plugins/pictureflow/pictureflow.c | 63 ++++++++++++++++++++++++-- manual/plugins/pictureflow.tex | 4 +- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/apps/plugin.c b/apps/plugin.c index 2bcbc93de6..c28954e9eb 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -824,6 +824,7 @@ static const struct plugin_api rockbox_api = { splash_progress, splash_progress_set_delay, fix_path_part, + onplay_show_playlist_cat_menu, }; static int plugin_buffer_handle; diff --git a/apps/plugin.h b/apps/plugin.h index 474ccc5b82..850e7484d9 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -157,7 +157,7 @@ int plugin_open(const char *plugin, const char *parameter); #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 262 +#define PLUGIN_API_VERSION 263 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -948,6 +948,8 @@ struct plugin_api { void (*splash_progress)(int current, int total, const char *fmt, ...) ATTRIBUTE_PRINTF(3, 4); void (*splash_progress_set_delay)(long delay_ticks); void (*fix_path_part)(char* path, int offset, int count); + void (*onplay_show_playlist_cat_menu)(const char* track_name, int attr, + void (*add_to_pl_cb)); }; /* plugin header */ diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index 61d0b64e94..b2cf467a2f 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c @@ -4198,7 +4198,7 @@ static int show_id3_info(const char *selected_file) } -static bool playlist_insert(int position, bool queue, bool create_new) +static bool pf_current_playlist_insert(int position, bool queue, bool create_new) { if (position == PLAYLIST_REPLACE) { @@ -4229,6 +4229,44 @@ static bool playlist_insert(int position, bool queue, bool create_new) return true; } + +static int pf_add_to_playlist(const char* playlist, bool new_playlist) +{ + int fd; + int result = 0; + + if (new_playlist) + fd = rb->open_utf8(playlist, O_CREAT|O_WRONLY|O_TRUNC); + else + fd = rb->open(playlist, O_CREAT|O_WRONLY|O_APPEND, 0666); + + if(fd < 0) + return -1; + + rb->reload_directory(); + + if (!insert_whole_album) + { + if (rb->fdprintf(fd, "%s\n", get_track_filename(pf_tracks.sel)) <= 0) + result = -1; + } + else + { + int i = 0; + do { + if (rb->fdprintf(fd, "%s\n", get_track_filename(i)) <= 0) + { + result = -1; + break; + } + rb->yield(); + } while(++i < pf_tracks.count); + } + rb->close(fd); + return result; +} + + static bool track_list_ready(void) { if (pf_state != pf_show_tracks) @@ -4291,14 +4329,18 @@ static void context_menu_cleanup(void) static int context_menu(void) { + char album_name[MAX_PATH]; char *file_name = get_track_filename(pf_tracks.sel); + int attr; enum { PF_CURRENT_PLAYLIST = 0, + PF_CATALOG, PF_ID3_INFO }; MENUITEM_STRINGLIST(context_menu, ID2P(LANG_ONPLAY_MENU_TITLE), NULL, ID2P(LANG_PLAYING_NEXT), + ID2P(LANG_ADD_TO_PL), ID2P(LANG_MENU_SHOW_ID3_INFO)); while (1) { @@ -4307,7 +4349,22 @@ static int context_menu(void) case PF_CURRENT_PLAYLIST: rb->onplay_show_playlist_menu(file_name, - &playlist_insert); + &pf_current_playlist_insert); + return 0; + case PF_CATALOG: + if (!insert_whole_album) + attr = FILE_ATTR_AUDIO; + else + { + /* add a leading slash so that catalog_add_to_a_playlist + later prefills the name when creating a new playlist */ + rb->snprintf(album_name, MAX_PATH, "/%s", get_album_name(center_index)); + rb->fix_path_part(album_name, 1, sizeof(album_name)); + file_name = album_name; + attr = ATTR_DIRECTORY; + } + + rb->onplay_show_playlist_cat_menu(file_name, attr, &pf_add_to_playlist); return 0; case PF_ID3_INFO: return show_id3_info(file_name); @@ -4354,7 +4411,7 @@ static bool start_playback(bool return_to_WPS) if (shuffle || center_slide.slide_index != old_playlist || (old_shuffle != shuffle)) { - if (!playlist_insert(PLAYLIST_REPLACE, false, true)) + if (!pf_current_playlist_insert(PLAYLIST_REPLACE, false, true)) { #ifdef USEGSLIB grey_show(true); diff --git a/manual/plugins/pictureflow.tex b/manual/plugins/pictureflow.tex index 5aee31c004..c0b86e34da 100644 --- a/manual/plugins/pictureflow.tex +++ b/manual/plugins/pictureflow.tex @@ -2,8 +2,8 @@ \screenshot{plugins/images/ss-pictureflow}{PictureFlow}{img:pictureflow} PictureFlow is a visual browser for your albums. After you've selected something to play, PictureFlow will continue running by default, or can optionally show the WPS. Using -the context menu, songs can be added to the dynamic playlist directly from PictureFlow -(see \reference{ref:playingnext_submenu}). +the context menu, songs can be added to the dynamic playlist or other playlists directly +from PictureFlow (see \reference{ref:playingnext_submenu}). Various metadata, such as format, length or year of an album or its songs can also be displayed.