summaryrefslogtreecommitdiff
path: root/apps/plugins
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 /apps/plugins
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
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/properties.c236
1 files changed, 72 insertions, 164 deletions
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}