summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {