From f3358eb20a9a07b6788fd9cf9d58cffb0e072342 Mon Sep 17 00:00:00 2001 From: Christian Soffke Date: Sun, 10 Apr 2022 06:29:01 +0200 Subject: [PATCH] Properties plugin: Eliminate redundant Track Info code When opening an audio file from the file browser or database using the Properties plugin, it will now use existing code from the Show Track Info screen for displaying metadata. The menu option has been renamed accordingly. Change-Id: I5a824865b9f980151b91aff3c3c18ec45830a12c --- apps/lang/english.lang | 118 ++++++++++--------- apps/onplay.c | 12 +- apps/plugin.c | 3 +- apps/plugin.h | 7 +- apps/plugins/properties.c | 234 ++++++++++++-------------------------- apps/screens.c | 3 + 6 files changed, 156 insertions(+), 221 deletions(-) diff --git a/apps/lang/english.lang b/apps/lang/english.lang index e7264d65ea..c843471831 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -14722,58 +14722,58 @@ id: LANG_PROPERTIES_ARTIST - desc: in properties plugin + desc: deprecated user: core - *: "[Artist]" + *: "" - *: "[Artist]" + *: "" - *: "Artist" + *: "" id: LANG_PROPERTIES_TITLE - desc: in properties plugin + desc: deprecated user: core - *: "[Title]" + *: "" - *: "[Title]" + *: "" - *: "Title" + *: "" id: LANG_PROPERTIES_ALBUM - desc: in properties plugin + desc: deprecated user: core - *: "[Album]" + *: "" - *: "[Album]" + *: "" - *: "Album" + *: "" id: LANG_PROPERTIES_DURATION - desc: in properties plugin + desc: deprecated user: core - *: "[Duration]" + *: "" - *: "[Duration]" + *: "" - *: "Duration" + *: "" @@ -15947,128 +15947,128 @@ id: LANG_PROPERTIES_ALBUMARTIST - desc: in properties plugin + desc: deprecated user: core - *: "[Album Artist]" + *: "" - *: "[Album Artist]" + *: "" - *: "Album Artist" + *: "" id: LANG_PROPERTIES_GENRE - desc: in properties plugin + desc: deprecated user: core - *: "[Genre]" + *: "" - *: "[Genre]" + *: "" - *: "Genre" + *: "" id: LANG_PROPERTIES_COMMENT - desc: in properties plugin + desc: deprecated user: core - *: "[Comment]" + *: "" - *: "[Comment]" + *: "" - *: "Comment" + *: "" id: LANG_PROPERTIES_COMPOSER - desc: in properties plugin + desc: deprecated user: core - *: "[Composer]" + *: "" - *: "[Composer]" + *: "" - *: "Composer" + *: "" id: LANG_PROPERTIES_YEAR - desc: in properties plugin + desc: deprecated user: core - *: "[Year]" + *: "" - *: "[Year]" + *: "" - *: "Year" + *: "" id: LANG_PROPERTIES_TRACKNUM - desc: in properties plugin + desc: deprecated user: core - *: "[Tracknum]" + *: "" - *: "[Tracknum]" + *: "" - *: "Track number" + *: "" id: LANG_PROPERTIES_DISCNUM - desc: in properties plugin + desc: deprecated user: core - *: "[Discnum]" + *: "" - *: "[Discnum]" + *: "" - *: "Disc number" + *: "" id: LANG_PROPERTIES_FREQUENCY - desc: in properties plugin + desc: deprecated user: core - *: "[Frequency]" + *: "" - *: "[Frequency]" + *: "" - *: "Frequency" + *: "" id: LANG_PROPERTIES_BITRATE - desc: in properties plugin + desc: deprecated user: core - *: "[Bitrate]" + *: "" - *: "[Bitrate]" + *: "" - *: "Bit rate" + *: "" @@ -16312,3 +16312,17 @@ *: "Cache needs to finish updating first!" + + id: LANG_TRACK_INFO + desc: Track Info Title + user: core + + *: "Track Info" + + + *: "Track Info" + + + *: "Track Info" + + diff --git a/apps/onplay.c b/apps/onplay.c index 7245ac2016..a78cf7ceac 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -1595,6 +1595,9 @@ MENUITEM_FUNCTION(list_viewers_item, 0, ID2P(LANG_ONPLAY_OPEN_WITH), MENUITEM_FUNCTION(properties_item, MENU_FUNC_USEPARAM, ID2P(LANG_PROPERTIES), onplay_load_plugin, (void *)"properties", clipboard_callback, Icon_NOICON); +MENUITEM_FUNCTION(track_info_item, MENU_FUNC_USEPARAM, ID2P(LANG_MENU_SHOW_ID3_INFO), + onplay_load_plugin, (void *)"properties", + clipboard_callback, Icon_NOICON); #ifdef HAVE_TAGCACHE MENUITEM_FUNCTION(pictureflow_item, MENU_FUNC_USEPARAM, ID2P(LANG_ONPLAY_PICTUREFLOW), onplay_load_plugin, (void *)"pictureflow", @@ -1666,7 +1669,7 @@ static int clipboard_callback(int action, { if (((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) && - (this_item == &properties_item || + (this_item == &track_info_item || this_item == &pictureflow_item)) return action; return ACTION_EXIT_MENUITEM; @@ -1688,7 +1691,10 @@ static int clipboard_callback(int action, if (this_item == &rename_file_item || this_item == &clipboard_cut_item || this_item == &clipboard_copy_item || - this_item == &properties_item || + (this_item == &track_info_item && + (selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) || + (this_item == &properties_item && + (selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) || this_item == &add_to_faves_item) { return action; @@ -1765,7 +1771,7 @@ MAKE_ONPLAYMENU( tree_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE), #if LCD_DEPTH > 1 &set_backdrop_item, #endif - &list_viewers_item, &create_dir_item, &properties_item, + &list_viewers_item, &create_dir_item, &properties_item, &track_info_item, #ifdef HAVE_TAGCACHE &pictureflow_item, #endif diff --git a/apps/plugin.c b/apps/plugin.c index 17b3c0214a..eb76eb7753 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -7,7 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * - * Copyright (C) 2002 Björn Stenberg + * Copyright (C) 2002 Björn Stenberg * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -815,6 +815,7 @@ static const struct plugin_api rockbox_api = { #endif sys_poweroff, sys_reboot, + browse_id3, }; static int plugin_buffer_handle; diff --git a/apps/plugin.h b/apps/plugin.h index 89b8782cc7..a487f64168 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -7,7 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * - * Copyright (C) 2002 Björn Stenberg + * Copyright (C) 2002 Björn Stenberg * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -112,6 +112,7 @@ int plugin_open(const char *plugin, const char *parameter); #include "core_alloc.h" #include "screen_access.h" #include "onplay.h" +#include "screens.h" #ifdef HAVE_ALBUMART #include "albumart.h" @@ -156,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 250 +#define PLUGIN_API_VERSION 251 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -942,6 +943,8 @@ struct plugin_api { #endif void (*sys_poweroff)(void); void (*sys_reboot)(void); + bool (*browse_id3)(struct mp3entry *id3, + int playlist_display_index, int playlist_amount); }; /* plugin header */ diff --git a/apps/plugins/properties.c b/apps/plugins/properties.c index fa3517726a..e5f00e307b 100644 --- a/apps/plugins/properties.c +++ b/apps/plugins/properties.c @@ -20,9 +20,19 @@ ****************************************************************************/ #include "plugin.h" +#if !defined(ARRAY_SIZE) + #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) +#endif +enum props_types { + PROPS_FILE = 0, + PROPS_ID3, + PROPS_DIR +}; -bool its_a_dir = false; +static int props_type = PROPS_FILE; + +static struct mp3entry id3; char str_filename[MAX_PATH]; char str_dirname[MAX_PATH]; @@ -32,27 +42,12 @@ char str_filecount[64]; char str_date[64]; char str_time[64]; -char str_title[MAX_PATH]; -char str_composer[MAX_PATH]; -char str_artist[MAX_PATH]; -char str_albumartist[MAX_PATH]; -char str_album[MAX_PATH]; -char str_genre[MAX_PATH]; -char str_comment[MAX_PATH]; -char str_year[MAX_PATH]; -char str_discnum[MAX_PATH]; -char str_tracknum[MAX_PATH]; -char str_duration[32]; -char str_bitrate[32]; -char str_frequency[32]; - unsigned nseconds; unsigned long nsize; int32_t size_unit; struct tm tm; -int num_properties; - +#define NUM_FILE_PROPERTIES 5 static const unsigned char* const props_file[] = { ID2P(LANG_PROPERTIES_PATH), str_dirname, @@ -60,20 +55,9 @@ static const unsigned char* const props_file[] = ID2P(LANG_PROPERTIES_SIZE), str_size, ID2P(LANG_PROPERTIES_DATE), str_date, ID2P(LANG_PROPERTIES_TIME), str_time, - ID2P(LANG_PROPERTIES_COMPOSER), str_composer, - ID2P(LANG_PROPERTIES_ARTIST), str_artist, - ID2P(LANG_PROPERTIES_ALBUMARTIST), str_albumartist, - ID2P(LANG_PROPERTIES_TITLE), str_title, - ID2P(LANG_PROPERTIES_ALBUM), str_album, - ID2P(LANG_PROPERTIES_GENRE), str_genre, - ID2P(LANG_PROPERTIES_COMMENT), str_comment, - ID2P(LANG_PROPERTIES_YEAR), str_year, - ID2P(LANG_PROPERTIES_DISCNUM), str_discnum, - ID2P(LANG_PROPERTIES_TRACKNUM), str_tracknum, - ID2P(LANG_PROPERTIES_DURATION), str_duration, - ID2P(LANG_PROPERTIES_BITRATE), str_bitrate, - ID2P(LANG_PROPERTIES_FREQUENCY), str_frequency, }; + +#define NUM_DIR_PROPERTIES 4 static const unsigned char* const props_dir[] = { ID2P(LANG_PROPERTIES_PATH), str_dirname, @@ -107,7 +91,6 @@ static bool file_properties(const char* selected_file) bool found = false; DIR* dir; struct dirent* entry; - static struct mp3entry id3; dir = rb->opendir(str_dirname); if (dir) @@ -128,81 +111,14 @@ static bool file_properties(const char* selected_file) rb->snprintf(str_time, sizeof str_time, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); - num_properties = 5; - int fd = rb->open(selected_file, O_RDONLY); - if (fd >= 0 && - rb->get_metadata(&id3, fd, selected_file)) + if (fd >= 0) { - long dur = id3.length / 1000; /* seconds */ - rb->snprintf(str_composer, sizeof str_composer, - "%s", id3.composer ? id3.composer : ""); - rb->snprintf(str_artist, sizeof str_artist, - "%s", id3.artist ? id3.artist : ""); - rb->snprintf(str_albumartist, sizeof str_albumartist, - "%s", id3.albumartist ? id3.albumartist : ""); - rb->snprintf(str_title, sizeof str_title, - "%s", id3.title ? id3.title : ""); - rb->snprintf(str_album, sizeof str_album, - "%s", id3.album ? id3.album : ""); - rb->snprintf(str_genre, sizeof str_genre, - "%s", id3.genre_string ? id3.genre_string : ""); - rb->snprintf(str_comment, sizeof str_comment, - "%s", id3.comment ? id3.comment : ""); + if (rb->get_metadata(&id3, fd, selected_file)) + props_type = PROPS_ID3; - if (id3.year_string) - rb->snprintf(str_year, sizeof str_year, - "%s", id3.year_string); - else if (id3.year) - rb->snprintf(str_year, sizeof str_year, - "%d", id3.year); - else - rb->snprintf(str_year, sizeof str_year, - "%s", ""); - - if (id3.disc_string) - rb->snprintf(str_discnum, sizeof str_discnum, - "%s", id3.disc_string); - else if (id3.discnum) - rb->snprintf(str_discnum, sizeof str_discnum, - "%d", id3.discnum); - else - rb->snprintf(str_discnum, sizeof str_discnum, - "%s", ""); - - if (id3.track_string) - rb->snprintf(str_tracknum, sizeof str_tracknum, - "%s", id3.track_string); - else if(id3.tracknum) - rb->snprintf(str_tracknum, sizeof str_tracknum, - "%d", id3.tracknum); - else - rb->snprintf(str_tracknum, sizeof str_tracknum, - "%s", ""); - - rb->snprintf(str_bitrate, sizeof str_bitrate, - "%d kbps", id3.bitrate ? : 0); - rb->snprintf(str_frequency, sizeof str_frequency, - "%ld Hz", id3.frequency ? : 0); - num_properties += 12; - - if (dur > 0) - { - nseconds = dur; - if (dur < 3600) - rb->snprintf(str_duration, sizeof str_duration, - "%d:%02d", (int)(dur / 60), - (int)(dur % 60)); - else - rb->snprintf(str_duration, sizeof str_duration, - "%d:%02d:%02d", - (int)(dur / 3600), - (int)(dur % 3600 / 60), - (int)(dur % 60)); - num_properties++; - } + rb->close(fd); } - rb->close(fd); found = true; break; } @@ -265,7 +181,7 @@ static bool _dir_properties(DPS *dps) rb->lcd_putsf(0,3,"Files: %d", dps->fc); log = human_size_log(dps->bc); rb->lcd_putsf(0,4,"Size: %lu %cB", (unsigned long)(dps->bc >> (10*log)), - rb->str(units[log])); + rb->str(units[log])); rb->lcd_update(); } @@ -314,7 +230,6 @@ static bool dir_properties(const char* selected_file, DPS *dps) nsize = (long) (dps->bc >> (log*10)); size_unit = units[log]; rb->snprintf(str_size, sizeof str_size, "%ld %s", nsize, rb->str(size_unit)); - num_properties = 4; return true; } @@ -328,35 +243,20 @@ static const char * get_props(int selected_item, void* data, char *buffer, size_t buffer_len) { (void)data; - if(its_a_dir) - { - if(selected_item >= (int)(sizeof(props_dir) / sizeof(props_dir[0]))) - { - rb->strlcpy(buffer, "ERROR", buffer_len); - } - else - { - rb->strlcpy(buffer, p2str(props_dir[selected_item]), buffer_len); - } - } - else - { - if(selected_item >= (int)(sizeof(props_file) / sizeof(props_file[0]))) - { - rb->strlcpy(buffer, "ERROR", buffer_len); - } - else - { - rb->strlcpy(buffer, p2str(props_file[selected_item]), buffer_len); - } - } + if (PROPS_DIR == props_type) + rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_dir)) ? "ERROR" : + (char *) p2str(props_dir[selected_item]), buffer_len); + else if (PROPS_FILE == props_type) + rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_file)) ? "ERROR" : + (char *) p2str(props_file[selected_item]), buffer_len); + return buffer; } static int speak_property_selection(int selected_item, void *data) { DPS *dps = data; - int32_t id = P2ID((its_a_dir ? props_dir : props_file)[selected_item]); + int32_t id = P2ID((props_type == PROPS_DIR ? props_dir : props_file)[selected_item]); rb->talk_id(id, false); switch (id) { @@ -394,9 +294,6 @@ static int speak_property_selection(int selected_item, void *data) case LANG_PROPERTIES_TIME: rb->talk_time(&tm, true); break; - case LANG_PROPERTIES_DURATION: - rb->talk_value_decimal(nseconds, UNIT_TIME, 0, true); - break; case LANG_PROPERTIES_SUBDIRS: rb->talk_number(dps->dc, true); break; @@ -422,10 +319,10 @@ enum plugin_status plugin_start(const void* parameter) #endif static DPS dps = { - .len = MAX_PATH, - .dc = 0, - .fc = 0, - .bc = 0, + .len = MAX_PATH, + .dc = 0, + .fc = 0, + .bc = 0, }; /* determine if it's a file or a directory */ @@ -446,7 +343,7 @@ enum plugin_status plugin_start(const void* parameter) if(!rb->strcmp(entry->d_name, str_filename)) { struct dirinfo info = rb->dir_get_info(dir, entry); - its_a_dir = info.attribute & ATTR_DIRECTORY ? true : false; + props_type = info.attribute & ATTR_DIRECTORY ? PROPS_DIR : PROPS_FILE; found = true; break; } @@ -464,7 +361,7 @@ enum plugin_status plugin_start(const void* parameter) } /* get the info depending on its_a_dir */ - if(!(its_a_dir ? dir_properties(file, &dps) : file_properties(file))) + if(!(props_type == PROPS_DIR ? dir_properties(file, &dps) : file_properties(file))) { /* something went wrong (to do: tell user what it was (nesting,...) */ rb->splash(0, ID2P(LANG_PROPERTIES_FAIL)); @@ -475,40 +372,51 @@ enum plugin_status plugin_start(const void* parameter) FOR_NB_SCREENS(i) rb->viewportmanager_theme_enable(i, true, NULL); - rb->gui_synclist_init(&properties_lists, &get_props, &dps, false, 2, NULL); - rb->gui_synclist_set_title(&properties_lists, rb->str(its_a_dir ? LANG_PROPERTIES_DIRECTORY_PROPERTIES : LANG_PROPERTIES_FILE_PROPERTIES), NOICON); - rb->gui_synclist_set_icon_callback(&properties_lists, NULL); - if (rb->global_settings->talk_menu) - rb->gui_synclist_set_voice_callback(&properties_lists, speak_property_selection); - rb->gui_synclist_set_nb_items(&properties_lists, num_properties * 2); - rb->gui_synclist_limit_scroll(&properties_lists, true); - rb->gui_synclist_select_item(&properties_lists, 0); - rb->gui_synclist_draw(&properties_lists); - rb->gui_synclist_speak_item(&properties_lists); - - while(!quit) + if (props_type == PROPS_ID3) + usb = rb->browse_id3(&id3, 0, 0); + else { - button = rb->get_action(CONTEXT_LIST, HZ); - /* HZ so the status bar redraws corectly */ - if (rb->gui_synclist_do_button(&properties_lists,&button,LIST_WRAP_UNLESS_HELD)) - continue; - switch(button) + rb->gui_synclist_init(&properties_lists, &get_props, &dps, false, 2, NULL); + rb->gui_synclist_set_title(&properties_lists, + rb->str(props_type == PROPS_DIR ? + LANG_PROPERTIES_DIRECTORY_PROPERTIES : + LANG_PROPERTIES_FILE_PROPERTIES), + NOICON); + rb->gui_synclist_set_icon_callback(&properties_lists, NULL); + if (rb->global_settings->talk_menu) + rb->gui_synclist_set_voice_callback(&properties_lists, speak_property_selection); + rb->gui_synclist_set_nb_items(&properties_lists, + 2 * (props_type == PROPS_FILE ? NUM_FILE_PROPERTIES : + NUM_DIR_PROPERTIES)); + rb->gui_synclist_limit_scroll(&properties_lists, true); + rb->gui_synclist_select_item(&properties_lists, 0); + rb->gui_synclist_draw(&properties_lists); + rb->gui_synclist_speak_item(&properties_lists); + + while(!quit) { - case ACTION_STD_CANCEL: - quit = true; - break; - default: - if (rb->default_event_handler(button) == SYS_USB_CONNECTED) - { + button = rb->get_action(CONTEXT_LIST, HZ); + /* HZ so the status bar redraws corectly */ + if (rb->gui_synclist_do_button(&properties_lists,&button,LIST_WRAP_UNLESS_HELD)) + continue; + switch(button) + { + case ACTION_STD_CANCEL: quit = true; - usb = true; - } - break; + break; + default: + if (rb->default_event_handler(button) == SYS_USB_CONNECTED) + { + quit = true; + usb = true; + } + break; + } } } FOR_NB_SCREENS(i) rb->viewportmanager_theme_undo(i, false); - return usb? PLUGIN_USB_CONNECTED: PLUGIN_OK; + return usb ? PLUGIN_USB_CONNECTED : PLUGIN_OK; } diff --git a/apps/screens.c b/apps/screens.c index 5d56906b90..24d1fed915 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -595,6 +595,8 @@ static const char * id3_get_or_speak_info(int selected_item, void* data, talk_value(id3->length /1000, UNIT_TIME, true); break; case LANG_ID3_PLAYLIST: + if (info->playlist_display_index == 0 || info->playlist_amount == 0 ) + return NULL; snprintf(buffer, buffer_len, "%d/%d", info->playlist_display_index, info->playlist_amount); val=buffer; @@ -708,6 +710,7 @@ bool browse_id3(struct mp3entry *id3, int playlist_display_index, int playlist_a if(global_settings.talk_menu) gui_synclist_set_voice_callback(&id3_lists, id3_speak_item); gui_synclist_set_nb_items(&id3_lists, info.count*2); + gui_synclist_set_title(&id3_lists, str(LANG_TRACK_INFO), NOICON); gui_synclist_draw(&id3_lists); gui_synclist_speak_item(&id3_lists); while (true) {