summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2022-04-10 06:29:01 +0200
committerWilliam Wilgus <me.theuser@yahoo.com>2022-05-09 09:44:23 -0400
commitf3358eb20a9a07b6788fd9cf9d58cffb0e072342 (patch)
treeb794a89829cabffc1358365997f374925033ecd6
parent4b293285ea04df6c8ca04ec01f1b4729d285d379 (diff)
downloadrockbox-f3358eb20a9a07b6788fd9cf9d58cffb0e072342.tar.gz
rockbox-f3358eb20a9a07b6788fd9cf9d58cffb0e072342.zip
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
-rw-r--r--apps/lang/english.lang118
-rw-r--r--apps/onplay.c12
-rw-r--r--apps/plugin.c3
-rw-r--r--apps/plugin.h7
-rw-r--r--apps/plugins/properties.c236
-rw-r--r--apps/screens.c3
6 files changed, 157 insertions, 222 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 @@
14722</phrase> 14722</phrase>
14723<phrase> 14723<phrase>
14724 id: LANG_PROPERTIES_ARTIST 14724 id: LANG_PROPERTIES_ARTIST
14725 desc: in properties plugin 14725 desc: deprecated
14726 user: core 14726 user: core
14727 <source> 14727 <source>
14728 *: "[Artist]" 14728 *: ""
14729 </source> 14729 </source>
14730 <dest> 14730 <dest>
14731 *: "[Artist]" 14731 *: ""
14732 </dest> 14732 </dest>
14733 <voice> 14733 <voice>
14734 *: "Artist" 14734 *: ""
14735 </voice> 14735 </voice>
14736</phrase> 14736</phrase>
14737<phrase> 14737<phrase>
14738 id: LANG_PROPERTIES_TITLE 14738 id: LANG_PROPERTIES_TITLE
14739 desc: in properties plugin 14739 desc: deprecated
14740 user: core 14740 user: core
14741 <source> 14741 <source>
14742 *: "[Title]" 14742 *: ""
14743 </source> 14743 </source>
14744 <dest> 14744 <dest>
14745 *: "[Title]" 14745 *: ""
14746 </dest> 14746 </dest>
14747 <voice> 14747 <voice>
14748 *: "Title" 14748 *: ""
14749 </voice> 14749 </voice>
14750</phrase> 14750</phrase>
14751<phrase> 14751<phrase>
14752 id: LANG_PROPERTIES_ALBUM 14752 id: LANG_PROPERTIES_ALBUM
14753 desc: in properties plugin 14753 desc: deprecated
14754 user: core 14754 user: core
14755 <source> 14755 <source>
14756 *: "[Album]" 14756 *: ""
14757 </source> 14757 </source>
14758 <dest> 14758 <dest>
14759 *: "[Album]" 14759 *: ""
14760 </dest> 14760 </dest>
14761 <voice> 14761 <voice>
14762 *: "Album" 14762 *: ""
14763 </voice> 14763 </voice>
14764</phrase> 14764</phrase>
14765<phrase> 14765<phrase>
14766 id: LANG_PROPERTIES_DURATION 14766 id: LANG_PROPERTIES_DURATION
14767 desc: in properties plugin 14767 desc: deprecated
14768 user: core 14768 user: core
14769 <source> 14769 <source>
14770 *: "[Duration]" 14770 *: ""
14771 </source> 14771 </source>
14772 <dest> 14772 <dest>
14773 *: "[Duration]" 14773 *: ""
14774 </dest> 14774 </dest>
14775 <voice> 14775 <voice>
14776 *: "Duration" 14776 *: ""
14777 </voice> 14777 </voice>
14778</phrase> 14778</phrase>
14779<phrase> 14779<phrase>
@@ -15947,128 +15947,128 @@
15947</phrase> 15947</phrase>
15948<phrase> 15948<phrase>
15949 id: LANG_PROPERTIES_ALBUMARTIST 15949 id: LANG_PROPERTIES_ALBUMARTIST
15950 desc: in properties plugin 15950 desc: deprecated
15951 user: core 15951 user: core
15952 <source> 15952 <source>
15953 *: "[Album Artist]" 15953 *: ""
15954 </source> 15954 </source>
15955 <dest> 15955 <dest>
15956 *: "[Album Artist]" 15956 *: ""
15957 </dest> 15957 </dest>
15958 <voice> 15958 <voice>
15959 *: "Album Artist" 15959 *: ""
15960 </voice> 15960 </voice>
15961</phrase> 15961</phrase>
15962<phrase> 15962<phrase>
15963 id: LANG_PROPERTIES_GENRE 15963 id: LANG_PROPERTIES_GENRE
15964 desc: in properties plugin 15964 desc: deprecated
15965 user: core 15965 user: core
15966 <source> 15966 <source>
15967 *: "[Genre]" 15967 *: ""
15968 </source> 15968 </source>
15969 <dest> 15969 <dest>
15970 *: "[Genre]" 15970 *: ""
15971 </dest> 15971 </dest>
15972 <voice> 15972 <voice>
15973 *: "Genre" 15973 *: ""
15974 </voice> 15974 </voice>
15975</phrase> 15975</phrase>
15976<phrase> 15976<phrase>
15977 id: LANG_PROPERTIES_COMMENT 15977 id: LANG_PROPERTIES_COMMENT
15978 desc: in properties plugin 15978 desc: deprecated
15979 user: core 15979 user: core
15980 <source> 15980 <source>
15981 *: "[Comment]" 15981 *: ""
15982 </source> 15982 </source>
15983 <dest> 15983 <dest>
15984 *: "[Comment]" 15984 *: ""
15985 </dest> 15985 </dest>
15986 <voice> 15986 <voice>
15987 *: "Comment" 15987 *: ""
15988 </voice> 15988 </voice>
15989</phrase> 15989</phrase>
15990<phrase> 15990<phrase>
15991 id: LANG_PROPERTIES_COMPOSER 15991 id: LANG_PROPERTIES_COMPOSER
15992 desc: in properties plugin 15992 desc: deprecated
15993 user: core 15993 user: core
15994 <source> 15994 <source>
15995 *: "[Composer]" 15995 *: ""
15996 </source> 15996 </source>
15997 <dest> 15997 <dest>
15998 *: "[Composer]" 15998 *: ""
15999 </dest> 15999 </dest>
16000 <voice> 16000 <voice>
16001 *: "Composer" 16001 *: ""
16002 </voice> 16002 </voice>
16003</phrase> 16003</phrase>
16004<phrase> 16004<phrase>
16005 id: LANG_PROPERTIES_YEAR 16005 id: LANG_PROPERTIES_YEAR
16006 desc: in properties plugin 16006 desc: deprecated
16007 user: core 16007 user: core
16008 <source> 16008 <source>
16009 *: "[Year]" 16009 *: ""
16010 </source> 16010 </source>
16011 <dest> 16011 <dest>
16012 *: "[Year]" 16012 *: ""
16013 </dest> 16013 </dest>
16014 <voice> 16014 <voice>
16015 *: "Year" 16015 *: ""
16016 </voice> 16016 </voice>
16017</phrase> 16017</phrase>
16018<phrase> 16018<phrase>
16019 id: LANG_PROPERTIES_TRACKNUM 16019 id: LANG_PROPERTIES_TRACKNUM
16020 desc: in properties plugin 16020 desc: deprecated
16021 user: core 16021 user: core
16022 <source> 16022 <source>
16023 *: "[Tracknum]" 16023 *: ""
16024 </source> 16024 </source>
16025 <dest> 16025 <dest>
16026 *: "[Tracknum]" 16026 *: ""
16027 </dest> 16027 </dest>
16028 <voice> 16028 <voice>
16029 *: "Track number" 16029 *: ""
16030 </voice> 16030 </voice>
16031</phrase> 16031</phrase>
16032<phrase> 16032<phrase>
16033 id: LANG_PROPERTIES_DISCNUM 16033 id: LANG_PROPERTIES_DISCNUM
16034 desc: in properties plugin 16034 desc: deprecated
16035 user: core 16035 user: core
16036 <source> 16036 <source>
16037 *: "[Discnum]" 16037 *: ""
16038 </source> 16038 </source>
16039 <dest> 16039 <dest>
16040 *: "[Discnum]" 16040 *: ""
16041 </dest> 16041 </dest>
16042 <voice> 16042 <voice>
16043 *: "Disc number" 16043 *: ""
16044 </voice> 16044 </voice>
16045</phrase> 16045</phrase>
16046<phrase> 16046<phrase>
16047 id: LANG_PROPERTIES_FREQUENCY 16047 id: LANG_PROPERTIES_FREQUENCY
16048 desc: in properties plugin 16048 desc: deprecated
16049 user: core 16049 user: core
16050 <source> 16050 <source>
16051 *: "[Frequency]" 16051 *: ""
16052 </source> 16052 </source>
16053 <dest> 16053 <dest>
16054 *: "[Frequency]" 16054 *: ""
16055 </dest> 16055 </dest>
16056 <voice> 16056 <voice>
16057 *: "Frequency" 16057 *: ""
16058 </voice> 16058 </voice>
16059</phrase> 16059</phrase>
16060<phrase> 16060<phrase>
16061 id: LANG_PROPERTIES_BITRATE 16061 id: LANG_PROPERTIES_BITRATE
16062 desc: in properties plugin 16062 desc: deprecated
16063 user: core 16063 user: core
16064 <source> 16064 <source>
16065 *: "[Bitrate]" 16065 *: ""
16066 </source> 16066 </source>
16067 <dest> 16067 <dest>
16068 *: "[Bitrate]" 16068 *: ""
16069 </dest> 16069 </dest>
16070 <voice> 16070 <voice>
16071 *: "Bit rate" 16071 *: ""
16072 </voice> 16072 </voice>
16073</phrase> 16073</phrase>
16074<phrase> 16074<phrase>
@@ -16312,3 +16312,17 @@
16312 *: "Cache needs to finish updating first!" 16312 *: "Cache needs to finish updating first!"
16313 </voice> 16313 </voice>
16314</phrase> 16314</phrase>
16315<phrase>
16316 id: LANG_TRACK_INFO
16317 desc: Track Info Title
16318 user: core
16319 <source>
16320 *: "Track Info"
16321 </source>
16322 <dest>
16323 *: "Track Info"
16324 </dest>
16325 <voice>
16326 *: "Track Info"
16327 </voice>
16328</phrase>
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),
1595MENUITEM_FUNCTION(properties_item, MENU_FUNC_USEPARAM, ID2P(LANG_PROPERTIES), 1595MENUITEM_FUNCTION(properties_item, MENU_FUNC_USEPARAM, ID2P(LANG_PROPERTIES),
1596 onplay_load_plugin, (void *)"properties", 1596 onplay_load_plugin, (void *)"properties",
1597 clipboard_callback, Icon_NOICON); 1597 clipboard_callback, Icon_NOICON);
1598MENUITEM_FUNCTION(track_info_item, MENU_FUNC_USEPARAM, ID2P(LANG_MENU_SHOW_ID3_INFO),
1599 onplay_load_plugin, (void *)"properties",
1600 clipboard_callback, Icon_NOICON);
1598#ifdef HAVE_TAGCACHE 1601#ifdef HAVE_TAGCACHE
1599MENUITEM_FUNCTION(pictureflow_item, MENU_FUNC_USEPARAM, ID2P(LANG_ONPLAY_PICTUREFLOW), 1602MENUITEM_FUNCTION(pictureflow_item, MENU_FUNC_USEPARAM, ID2P(LANG_ONPLAY_PICTUREFLOW),
1600 onplay_load_plugin, (void *)"pictureflow", 1603 onplay_load_plugin, (void *)"pictureflow",
@@ -1666,7 +1669,7 @@ static int clipboard_callback(int action,
1666 { 1669 {
1667 if (((selected_file_attr & FILE_ATTR_MASK) == 1670 if (((selected_file_attr & FILE_ATTR_MASK) ==
1668 FILE_ATTR_AUDIO) && 1671 FILE_ATTR_AUDIO) &&
1669 (this_item == &properties_item || 1672 (this_item == &track_info_item ||
1670 this_item == &pictureflow_item)) 1673 this_item == &pictureflow_item))
1671 return action; 1674 return action;
1672 return ACTION_EXIT_MENUITEM; 1675 return ACTION_EXIT_MENUITEM;
@@ -1688,7 +1691,10 @@ static int clipboard_callback(int action,
1688 if (this_item == &rename_file_item || 1691 if (this_item == &rename_file_item ||
1689 this_item == &clipboard_cut_item || 1692 this_item == &clipboard_cut_item ||
1690 this_item == &clipboard_copy_item || 1693 this_item == &clipboard_copy_item ||
1691 this_item == &properties_item || 1694 (this_item == &track_info_item &&
1695 (selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) ||
1696 (this_item == &properties_item &&
1697 (selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) ||
1692 this_item == &add_to_faves_item) 1698 this_item == &add_to_faves_item)
1693 { 1699 {
1694 return action; 1700 return action;
@@ -1765,7 +1771,7 @@ MAKE_ONPLAYMENU( tree_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE),
1765#if LCD_DEPTH > 1 1771#if LCD_DEPTH > 1
1766 &set_backdrop_item, 1772 &set_backdrop_item,
1767#endif 1773#endif
1768 &list_viewers_item, &create_dir_item, &properties_item, 1774 &list_viewers_item, &create_dir_item, &properties_item, &track_info_item,
1769#ifdef HAVE_TAGCACHE 1775#ifdef HAVE_TAGCACHE
1770 &pictureflow_item, 1776 &pictureflow_item,
1771#endif 1777#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 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2002 Björn Stenberg 10 * Copyright (C) 2002 Björn Stenberg
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -815,6 +815,7 @@ static const struct plugin_api rockbox_api = {
815#endif 815#endif
816 sys_poweroff, 816 sys_poweroff,
817 sys_reboot, 817 sys_reboot,
818 browse_id3,
818}; 819};
819 820
820static int plugin_buffer_handle; 821static 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 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2002 Björn Stenberg 10 * Copyright (C) 2002 Björn Stenberg
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -112,6 +112,7 @@ int plugin_open(const char *plugin, const char *parameter);
112#include "core_alloc.h" 112#include "core_alloc.h"
113#include "screen_access.h" 113#include "screen_access.h"
114#include "onplay.h" 114#include "onplay.h"
115#include "screens.h"
115 116
116#ifdef HAVE_ALBUMART 117#ifdef HAVE_ALBUMART
117#include "albumart.h" 118#include "albumart.h"
@@ -156,7 +157,7 @@ int plugin_open(const char *plugin, const char *parameter);
156#define PLUGIN_MAGIC 0x526F634B /* RocK */ 157#define PLUGIN_MAGIC 0x526F634B /* RocK */
157 158
158/* increase this every time the api struct changes */ 159/* increase this every time the api struct changes */
159#define PLUGIN_API_VERSION 250 160#define PLUGIN_API_VERSION 251
160 161
161/* update this to latest version if a change to the api struct breaks 162/* update this to latest version if a change to the api struct breaks
162 backwards compatibility (and please take the opportunity to sort in any 163 backwards compatibility (and please take the opportunity to sort in any
@@ -942,6 +943,8 @@ struct plugin_api {
942#endif 943#endif
943 void (*sys_poweroff)(void); 944 void (*sys_poweroff)(void);
944 void (*sys_reboot)(void); 945 void (*sys_reboot)(void);
946 bool (*browse_id3)(struct mp3entry *id3,
947 int playlist_display_index, int playlist_amount);
945}; 948};
946 949
947/* plugin header */ 950/* 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 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "plugin.h" 21#include "plugin.h"
22 22
23#if !defined(ARRAY_SIZE)
24 #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
25#endif
26
27enum props_types {
28 PROPS_FILE = 0,
29 PROPS_ID3,
30 PROPS_DIR
31};
23 32
33static int props_type = PROPS_FILE;
24 34
25bool its_a_dir = false; 35static struct mp3entry id3;
26 36
27char str_filename[MAX_PATH]; 37char str_filename[MAX_PATH];
28char str_dirname[MAX_PATH]; 38char str_dirname[MAX_PATH];
@@ -32,27 +42,12 @@ char str_filecount[64];
32char str_date[64]; 42char str_date[64];
33char str_time[64]; 43char str_time[64];
34 44
35char str_title[MAX_PATH];
36char str_composer[MAX_PATH];
37char str_artist[MAX_PATH];
38char str_albumartist[MAX_PATH];
39char str_album[MAX_PATH];
40char str_genre[MAX_PATH];
41char str_comment[MAX_PATH];
42char str_year[MAX_PATH];
43char str_discnum[MAX_PATH];
44char str_tracknum[MAX_PATH];
45char str_duration[32];
46char str_bitrate[32];
47char str_frequency[32];
48
49unsigned nseconds; 45unsigned nseconds;
50unsigned long nsize; 46unsigned long nsize;
51int32_t size_unit; 47int32_t size_unit;
52struct tm tm; 48struct tm tm;
53 49
54int num_properties; 50#define NUM_FILE_PROPERTIES 5
55
56static const unsigned char* const props_file[] = 51static const unsigned char* const props_file[] =
57{ 52{
58 ID2P(LANG_PROPERTIES_PATH), str_dirname, 53 ID2P(LANG_PROPERTIES_PATH), str_dirname,
@@ -60,20 +55,9 @@ static const unsigned char* const props_file[] =
60 ID2P(LANG_PROPERTIES_SIZE), str_size, 55 ID2P(LANG_PROPERTIES_SIZE), str_size,
61 ID2P(LANG_PROPERTIES_DATE), str_date, 56 ID2P(LANG_PROPERTIES_DATE), str_date,
62 ID2P(LANG_PROPERTIES_TIME), str_time, 57 ID2P(LANG_PROPERTIES_TIME), str_time,
63 ID2P(LANG_PROPERTIES_COMPOSER), str_composer,
64 ID2P(LANG_PROPERTIES_ARTIST), str_artist,
65 ID2P(LANG_PROPERTIES_ALBUMARTIST), str_albumartist,
66 ID2P(LANG_PROPERTIES_TITLE), str_title,
67 ID2P(LANG_PROPERTIES_ALBUM), str_album,
68 ID2P(LANG_PROPERTIES_GENRE), str_genre,
69 ID2P(LANG_PROPERTIES_COMMENT), str_comment,
70 ID2P(LANG_PROPERTIES_YEAR), str_year,
71 ID2P(LANG_PROPERTIES_DISCNUM), str_discnum,
72 ID2P(LANG_PROPERTIES_TRACKNUM), str_tracknum,
73 ID2P(LANG_PROPERTIES_DURATION), str_duration,
74 ID2P(LANG_PROPERTIES_BITRATE), str_bitrate,
75 ID2P(LANG_PROPERTIES_FREQUENCY), str_frequency,
76}; 58};
59
60#define NUM_DIR_PROPERTIES 4
77static const unsigned char* const props_dir[] = 61static const unsigned char* const props_dir[] =
78{ 62{
79 ID2P(LANG_PROPERTIES_PATH), str_dirname, 63 ID2P(LANG_PROPERTIES_PATH), str_dirname,
@@ -107,7 +91,6 @@ static bool file_properties(const char* selected_file)
107 bool found = false; 91 bool found = false;
108 DIR* dir; 92 DIR* dir;
109 struct dirent* entry; 93 struct dirent* entry;
110 static struct mp3entry id3;
111 94
112 dir = rb->opendir(str_dirname); 95 dir = rb->opendir(str_dirname);
113 if (dir) 96 if (dir)
@@ -128,81 +111,14 @@ static bool file_properties(const char* selected_file)
128 rb->snprintf(str_time, sizeof str_time, "%02d:%02d:%02d", 111 rb->snprintf(str_time, sizeof str_time, "%02d:%02d:%02d",
129 tm.tm_hour, tm.tm_min, tm.tm_sec); 112 tm.tm_hour, tm.tm_min, tm.tm_sec);
130 113
131 num_properties = 5;
132
133 int fd = rb->open(selected_file, O_RDONLY); 114 int fd = rb->open(selected_file, O_RDONLY);
134 if (fd >= 0 && 115 if (fd >= 0)
135 rb->get_metadata(&id3, fd, selected_file))
136 { 116 {
137 long dur = id3.length / 1000; /* seconds */ 117 if (rb->get_metadata(&id3, fd, selected_file))
138 rb->snprintf(str_composer, sizeof str_composer, 118 props_type = PROPS_ID3;
139 "%s", id3.composer ? id3.composer : ""); 119
140 rb->snprintf(str_artist, sizeof str_artist, 120 rb->close(fd);
141 "%s", id3.artist ? id3.artist : "");
142 rb->snprintf(str_albumartist, sizeof str_albumartist,
143 "%s", id3.albumartist ? id3.albumartist : "");
144 rb->snprintf(str_title, sizeof str_title,
145 "%s", id3.title ? id3.title : "");
146 rb->snprintf(str_album, sizeof str_album,
147 "%s", id3.album ? id3.album : "");
148 rb->snprintf(str_genre, sizeof str_genre,
149 "%s", id3.genre_string ? id3.genre_string : "");
150 rb->snprintf(str_comment, sizeof str_comment,
151 "%s", id3.comment ? id3.comment : "");
152
153 if (id3.year_string)
154 rb->snprintf(str_year, sizeof str_year,
155 "%s", id3.year_string);
156 else if (id3.year)
157 rb->snprintf(str_year, sizeof str_year,
158 "%d", id3.year);
159 else
160 rb->snprintf(str_year, sizeof str_year,
161 "%s", "");
162
163 if (id3.disc_string)
164 rb->snprintf(str_discnum, sizeof str_discnum,
165 "%s", id3.disc_string);
166 else if (id3.discnum)
167 rb->snprintf(str_discnum, sizeof str_discnum,
168 "%d", id3.discnum);
169 else
170 rb->snprintf(str_discnum, sizeof str_discnum,
171 "%s", "");
172
173 if (id3.track_string)
174 rb->snprintf(str_tracknum, sizeof str_tracknum,
175 "%s", id3.track_string);
176 else if(id3.tracknum)
177 rb->snprintf(str_tracknum, sizeof str_tracknum,
178 "%d", id3.tracknum);
179 else
180 rb->snprintf(str_tracknum, sizeof str_tracknum,
181 "%s", "");
182
183 rb->snprintf(str_bitrate, sizeof str_bitrate,
184 "%d kbps", id3.bitrate ? : 0);
185 rb->snprintf(str_frequency, sizeof str_frequency,
186 "%ld Hz", id3.frequency ? : 0);
187 num_properties += 12;
188
189 if (dur > 0)
190 {
191 nseconds = dur;
192 if (dur < 3600)
193 rb->snprintf(str_duration, sizeof str_duration,
194 "%d:%02d", (int)(dur / 60),
195 (int)(dur % 60));
196 else
197 rb->snprintf(str_duration, sizeof str_duration,
198 "%d:%02d:%02d",
199 (int)(dur / 3600),
200 (int)(dur % 3600 / 60),
201 (int)(dur % 60));
202 num_properties++;
203 }
204 } 121 }
205 rb->close(fd);
206 found = true; 122 found = true;
207 break; 123 break;
208 } 124 }
@@ -265,7 +181,7 @@ static bool _dir_properties(DPS *dps)
265 rb->lcd_putsf(0,3,"Files: %d", dps->fc); 181 rb->lcd_putsf(0,3,"Files: %d", dps->fc);
266 log = human_size_log(dps->bc); 182 log = human_size_log(dps->bc);
267 rb->lcd_putsf(0,4,"Size: %lu %cB", (unsigned long)(dps->bc >> (10*log)), 183 rb->lcd_putsf(0,4,"Size: %lu %cB", (unsigned long)(dps->bc >> (10*log)),
268 rb->str(units[log])); 184 rb->str(units[log]));
269 rb->lcd_update(); 185 rb->lcd_update();
270 } 186 }
271 187
@@ -314,7 +230,6 @@ static bool dir_properties(const char* selected_file, DPS *dps)
314 nsize = (long) (dps->bc >> (log*10)); 230 nsize = (long) (dps->bc >> (log*10));
315 size_unit = units[log]; 231 size_unit = units[log];
316 rb->snprintf(str_size, sizeof str_size, "%ld %s", nsize, rb->str(size_unit)); 232 rb->snprintf(str_size, sizeof str_size, "%ld %s", nsize, rb->str(size_unit));
317 num_properties = 4;
318 return true; 233 return true;
319} 234}
320 235
@@ -328,35 +243,20 @@ static const char * get_props(int selected_item, void* data,
328 char *buffer, size_t buffer_len) 243 char *buffer, size_t buffer_len)
329{ 244{
330 (void)data; 245 (void)data;
331 if(its_a_dir) 246 if (PROPS_DIR == props_type)
332 { 247 rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_dir)) ? "ERROR" :
333 if(selected_item >= (int)(sizeof(props_dir) / sizeof(props_dir[0]))) 248 (char *) p2str(props_dir[selected_item]), buffer_len);
334 { 249 else if (PROPS_FILE == props_type)
335 rb->strlcpy(buffer, "ERROR", buffer_len); 250 rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_file)) ? "ERROR" :
336 } 251 (char *) p2str(props_file[selected_item]), buffer_len);
337 else 252
338 {
339 rb->strlcpy(buffer, p2str(props_dir[selected_item]), buffer_len);
340 }
341 }
342 else
343 {
344 if(selected_item >= (int)(sizeof(props_file) / sizeof(props_file[0])))
345 {
346 rb->strlcpy(buffer, "ERROR", buffer_len);
347 }
348 else
349 {
350 rb->strlcpy(buffer, p2str(props_file[selected_item]), buffer_len);
351 }
352 }
353 return buffer; 253 return buffer;
354} 254}
355 255
356static int speak_property_selection(int selected_item, void *data) 256static int speak_property_selection(int selected_item, void *data)
357{ 257{
358 DPS *dps = data; 258 DPS *dps = data;
359 int32_t id = P2ID((its_a_dir ? props_dir : props_file)[selected_item]); 259 int32_t id = P2ID((props_type == PROPS_DIR ? props_dir : props_file)[selected_item]);
360 rb->talk_id(id, false); 260 rb->talk_id(id, false);
361 switch (id) 261 switch (id)
362 { 262 {
@@ -394,9 +294,6 @@ static int speak_property_selection(int selected_item, void *data)
394 case LANG_PROPERTIES_TIME: 294 case LANG_PROPERTIES_TIME:
395 rb->talk_time(&tm, true); 295 rb->talk_time(&tm, true);
396 break; 296 break;
397 case LANG_PROPERTIES_DURATION:
398 rb->talk_value_decimal(nseconds, UNIT_TIME, 0, true);
399 break;
400 case LANG_PROPERTIES_SUBDIRS: 297 case LANG_PROPERTIES_SUBDIRS:
401 rb->talk_number(dps->dc, true); 298 rb->talk_number(dps->dc, true);
402 break; 299 break;
@@ -422,10 +319,10 @@ enum plugin_status plugin_start(const void* parameter)
422#endif 319#endif
423 320
424 static DPS dps = { 321 static DPS dps = {
425 .len = MAX_PATH, 322 .len = MAX_PATH,
426 .dc = 0, 323 .dc = 0,
427 .fc = 0, 324 .fc = 0,
428 .bc = 0, 325 .bc = 0,
429 }; 326 };
430 327
431 /* determine if it's a file or a directory */ 328 /* determine if it's a file or a directory */
@@ -446,7 +343,7 @@ enum plugin_status plugin_start(const void* parameter)
446 if(!rb->strcmp(entry->d_name, str_filename)) 343 if(!rb->strcmp(entry->d_name, str_filename))
447 { 344 {
448 struct dirinfo info = rb->dir_get_info(dir, entry); 345 struct dirinfo info = rb->dir_get_info(dir, entry);
449 its_a_dir = info.attribute & ATTR_DIRECTORY ? true : false; 346 props_type = info.attribute & ATTR_DIRECTORY ? PROPS_DIR : PROPS_FILE;
450 found = true; 347 found = true;
451 break; 348 break;
452 } 349 }
@@ -464,7 +361,7 @@ enum plugin_status plugin_start(const void* parameter)
464 } 361 }
465 362
466 /* get the info depending on its_a_dir */ 363 /* get the info depending on its_a_dir */
467 if(!(its_a_dir ? dir_properties(file, &dps) : file_properties(file))) 364 if(!(props_type == PROPS_DIR ? dir_properties(file, &dps) : file_properties(file)))
468 { 365 {
469 /* something went wrong (to do: tell user what it was (nesting,...) */ 366 /* something went wrong (to do: tell user what it was (nesting,...) */
470 rb->splash(0, ID2P(LANG_PROPERTIES_FAIL)); 367 rb->splash(0, ID2P(LANG_PROPERTIES_FAIL));
@@ -475,40 +372,51 @@ enum plugin_status plugin_start(const void* parameter)
475 FOR_NB_SCREENS(i) 372 FOR_NB_SCREENS(i)
476 rb->viewportmanager_theme_enable(i, true, NULL); 373 rb->viewportmanager_theme_enable(i, true, NULL);
477 374
478 rb->gui_synclist_init(&properties_lists, &get_props, &dps, false, 2, NULL); 375 if (props_type == PROPS_ID3)
479 rb->gui_synclist_set_title(&properties_lists, rb->str(its_a_dir ? LANG_PROPERTIES_DIRECTORY_PROPERTIES : LANG_PROPERTIES_FILE_PROPERTIES), NOICON); 376 usb = rb->browse_id3(&id3, 0, 0);
480 rb->gui_synclist_set_icon_callback(&properties_lists, NULL); 377 else
481 if (rb->global_settings->talk_menu)
482 rb->gui_synclist_set_voice_callback(&properties_lists, speak_property_selection);
483 rb->gui_synclist_set_nb_items(&properties_lists, num_properties * 2);
484 rb->gui_synclist_limit_scroll(&properties_lists, true);
485 rb->gui_synclist_select_item(&properties_lists, 0);
486 rb->gui_synclist_draw(&properties_lists);
487 rb->gui_synclist_speak_item(&properties_lists);
488
489 while(!quit)
490 { 378 {
491 button = rb->get_action(CONTEXT_LIST, HZ); 379 rb->gui_synclist_init(&properties_lists, &get_props, &dps, false, 2, NULL);
492 /* HZ so the status bar redraws corectly */ 380 rb->gui_synclist_set_title(&properties_lists,
493 if (rb->gui_synclist_do_button(&properties_lists,&button,LIST_WRAP_UNLESS_HELD)) 381 rb->str(props_type == PROPS_DIR ?
494 continue; 382 LANG_PROPERTIES_DIRECTORY_PROPERTIES :
495 switch(button) 383 LANG_PROPERTIES_FILE_PROPERTIES),
384 NOICON);
385 rb->gui_synclist_set_icon_callback(&properties_lists, NULL);
386 if (rb->global_settings->talk_menu)
387 rb->gui_synclist_set_voice_callback(&properties_lists, speak_property_selection);
388 rb->gui_synclist_set_nb_items(&properties_lists,
389 2 * (props_type == PROPS_FILE ? NUM_FILE_PROPERTIES :
390 NUM_DIR_PROPERTIES));
391 rb->gui_synclist_limit_scroll(&properties_lists, true);
392 rb->gui_synclist_select_item(&properties_lists, 0);
393 rb->gui_synclist_draw(&properties_lists);
394 rb->gui_synclist_speak_item(&properties_lists);
395
396 while(!quit)
496 { 397 {
497 case ACTION_STD_CANCEL: 398 button = rb->get_action(CONTEXT_LIST, HZ);
498 quit = true; 399 /* HZ so the status bar redraws corectly */
499 break; 400 if (rb->gui_synclist_do_button(&properties_lists,&button,LIST_WRAP_UNLESS_HELD))
500 default: 401 continue;
501 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) 402 switch(button)
502 { 403 {
404 case ACTION_STD_CANCEL:
503 quit = true; 405 quit = true;
504 usb = true; 406 break;
505 } 407 default:
506 break; 408 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
409 {
410 quit = true;
411 usb = true;
412 }
413 break;
414 }
507 } 415 }
508 } 416 }
509 417
510 FOR_NB_SCREENS(i) 418 FOR_NB_SCREENS(i)
511 rb->viewportmanager_theme_undo(i, false); 419 rb->viewportmanager_theme_undo(i, false);
512 420
513 return usb? PLUGIN_USB_CONNECTED: PLUGIN_OK; 421 return usb ? PLUGIN_USB_CONNECTED : PLUGIN_OK;
514} 422}
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,
595 talk_value(id3->length /1000, UNIT_TIME, true); 595 talk_value(id3->length /1000, UNIT_TIME, true);
596 break; 596 break;
597 case LANG_ID3_PLAYLIST: 597 case LANG_ID3_PLAYLIST:
598 if (info->playlist_display_index == 0 || info->playlist_amount == 0 )
599 return NULL;
598 snprintf(buffer, buffer_len, "%d/%d", 600 snprintf(buffer, buffer_len, "%d/%d",
599 info->playlist_display_index, info->playlist_amount); 601 info->playlist_display_index, info->playlist_amount);
600 val=buffer; 602 val=buffer;
@@ -708,6 +710,7 @@ bool browse_id3(struct mp3entry *id3, int playlist_display_index, int playlist_a
708 if(global_settings.talk_menu) 710 if(global_settings.talk_menu)
709 gui_synclist_set_voice_callback(&id3_lists, id3_speak_item); 711 gui_synclist_set_voice_callback(&id3_lists, id3_speak_item);
710 gui_synclist_set_nb_items(&id3_lists, info.count*2); 712 gui_synclist_set_nb_items(&id3_lists, info.count*2);
713 gui_synclist_set_title(&id3_lists, str(LANG_TRACK_INFO), NOICON);
711 gui_synclist_draw(&id3_lists); 714 gui_synclist_draw(&id3_lists);
712 gui_synclist_speak_item(&id3_lists); 715 gui_synclist_speak_item(&id3_lists);
713 while (true) { 716 while (true) {