summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/properties.c146
1 files changed, 111 insertions, 35 deletions
diff --git a/apps/plugins/properties.c b/apps/plugins/properties.c
index 3bddc24d69..686b4d6d1a 100644
--- a/apps/plugins/properties.c
+++ b/apps/plugins/properties.c
@@ -37,32 +37,44 @@ char str_artist[MAX_PATH];
37char str_album[MAX_PATH]; 37char str_album[MAX_PATH];
38char str_duration[32]; 38char str_duration[32];
39 39
40unsigned nseconds;
41unsigned long nsize;
42int32_t size_unit;
43struct tm tm;
44
40int num_properties; 45int num_properties;
41 46
42static const char* props_file[] = 47static const unsigned char* const props_file[] =
43{ 48{
44 "[Path]", str_dirname, 49 ID2P(LANG_PROPERTIES_PATH), str_dirname,
45 "[Filename]", str_filename, 50 ID2P(LANG_PROPERTIES_FILENAME), str_filename,
46 "[Size]", str_size, 51 ID2P(LANG_PROPERTIES_SIZE), str_size,
47 "[Date]", str_date, 52 ID2P(LANG_PROPERTIES_DATE), str_date,
48 "[Time]", str_time, 53 ID2P(LANG_PROPERTIES_TIME), str_time,
49 "[Artist]", str_artist, 54 ID2P(LANG_PROPERTIES_ARTIST), str_artist,
50 "[Title]", str_title, 55 ID2P(LANG_PROPERTIES_TITLE), str_title,
51 "[Album]", str_album, 56 ID2P(LANG_PROPERTIES_ALBUM), str_album,
52 "[Duration]", str_duration, 57 ID2P(LANG_PROPERTIES_DURATION), str_duration,
53}; 58};
54static const char* props_dir[] = 59static const unsigned char* const props_dir[] =
55{ 60{
56 "[Path]", str_dirname, 61 ID2P(LANG_PROPERTIES_PATH), str_dirname,
57 "[Subdirs]", str_dircount, 62 ID2P(LANG_PROPERTIES_SUBDIRS), str_dircount,
58 "[Files]", str_filecount, 63 ID2P(LANG_PROPERTIES_FILES), str_filecount,
59 "[Size]", str_size, 64 ID2P(LANG_PROPERTIES_SIZE), str_size,
65};
66
67static const int32_t units[] =
68{
69 LANG_BYTE,
70 LANG_KIBIBYTE,
71 LANG_MEBIBYTE,
72 LANG_GIBIBYTE
60}; 73};
61 74
62static const char human_size_prefix[4] = { '\0', 'K', 'M', 'G' };
63static unsigned human_size_log(unsigned long long size) 75static unsigned human_size_log(unsigned long long size)
64{ 76{
65 const size_t n = sizeof(human_size_prefix)/sizeof(human_size_prefix[0]); 77 const size_t n = sizeof(units)/sizeof(units[0]);
66 78
67 unsigned i; 79 unsigned i;
68 /* margin set at 10K boundary: 10239 B +1 => 10 KB */ 80 /* margin set at 10K boundary: 10239 B +1 => 10 KB */
@@ -89,9 +101,9 @@ static bool file_properties(const char* selected_file)
89 { 101 {
90 unsigned log; 102 unsigned log;
91 log = human_size_log((unsigned long)info.size); 103 log = human_size_log((unsigned long)info.size);
92 rb->snprintf(str_size, sizeof str_size, "%lu %cB", 104 nsize = ((unsigned long)info.size) >> (log*10);
93 ((unsigned long)info.size) >> (log*10), human_size_prefix[log]); 105 size_unit = units[log];
94 struct tm tm; 106 rb->snprintf(str_size, sizeof str_size, "%lu %s", nsize, rb->str(size_unit));
95 rb->gmtime_r(&info.mtime, &tm); 107 rb->gmtime_r(&info.mtime, &tm);
96 rb->snprintf(str_date, sizeof str_date, "%04d/%02d/%02d", 108 rb->snprintf(str_date, sizeof str_date, "%04d/%02d/%02d",
97 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); 109 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
@@ -119,6 +131,7 @@ static bool file_properties(const char* selected_file)
119 131
120 if (dur > 0) 132 if (dur > 0)
121 { 133 {
134 nseconds = dur;
122 if (dur < 3600) 135 if (dur < 3600)
123 rb->snprintf(str_duration, sizeof str_duration, 136 rb->snprintf(str_duration, sizeof str_duration,
124 "%d:%02d", (int)(dur / 60), 137 "%d:%02d", (int)(dur / 60),
@@ -181,8 +194,6 @@ static bool _dir_properties(DPS *dps)
181 194
182 if (info.attribute & ATTR_DIRECTORY) 195 if (info.attribute & ATTR_DIRECTORY)
183 { 196 {
184 unsigned log;
185
186 if (!rb->strcmp((char *)entry->d_name, ".") || 197 if (!rb->strcmp((char *)entry->d_name, ".") ||
187 !rb->strcmp((char *)entry->d_name, "..")) 198 !rb->strcmp((char *)entry->d_name, ".."))
188 continue; /* skip these */ 199 continue; /* skip these */
@@ -190,16 +201,16 @@ static bool _dir_properties(DPS *dps)
190 dps->dc++; /* new directory */ 201 dps->dc++; /* new directory */
191 if (*rb->current_tick - lasttick > (HZ/8)) 202 if (*rb->current_tick - lasttick > (HZ/8))
192 { 203 {
204 unsigned log = human_size_log(dps->bc);
193 lasttick = *rb->current_tick; 205 lasttick = *rb->current_tick;
194 rb->lcd_clear_display(); 206 rb->lcd_clear_display();
195 rb->lcd_puts(0,0,"SCANNING..."); 207 rb->lcd_puts(0,0,"SCANNING...");
196 rb->lcd_puts(0,1,dps->dirname); 208 rb->lcd_puts(0,1,dps->dirname);
197 rb->lcd_puts(0,2,entry->d_name); 209 rb->lcd_putsf(0,2,"Directories: %d", dps->dc);
198 rb->lcd_putsf(0,3,"Directories: %d", dps->dc); 210 rb->lcd_putsf(0,3,"Files: %d", dps->fc);
199 rb->lcd_putsf(0,4,"Files: %d", dps->fc);
200 log = human_size_log(dps->bc); 211 log = human_size_log(dps->bc);
201 rb->lcd_putsf(0,5,"Size: %lu %cB", (unsigned long)(dps->bc >> (10*log)), 212 rb->lcd_putsf(0,4,"Size: %lu %cB", (unsigned long)(dps->bc >> (10*log)),
202 human_size_prefix[log]); 213 rb->str(units[log]));
203 rb->lcd_update(); 214 rb->lcd_update();
204 } 215 }
205 216
@@ -245,12 +256,19 @@ static bool dir_properties(const char* selected_file, DPS *dps)
245 rb->snprintf(str_dircount, sizeof str_dircount, "%d", dps->dc); 256 rb->snprintf(str_dircount, sizeof str_dircount, "%d", dps->dc);
246 rb->snprintf(str_filecount, sizeof str_filecount, "%d", dps->fc); 257 rb->snprintf(str_filecount, sizeof str_filecount, "%d", dps->fc);
247 log = human_size_log(dps->bc); 258 log = human_size_log(dps->bc);
248 rb->snprintf(str_size, sizeof str_size, "%ld %cB", 259 nsize = (long) (dps->bc >> (log*10));
249 (long) (dps->bc >> (log*10)), human_size_prefix[log]); 260 size_unit = units[log];
261 rb->snprintf(str_size, sizeof str_size, "%ld %s", nsize, rb->str(size_unit));
250 num_properties = 4; 262 num_properties = 4;
251 return true; 263 return true;
252} 264}
253 265
266static const unsigned char* p2str(const unsigned char* p)
267{
268 int id = P2ID(p);
269 return (id != -1) ? rb->str(id) : p;
270}
271
254static const char * get_props(int selected_item, void* data, 272static const char * get_props(int selected_item, void* data,
255 char *buffer, size_t buffer_len) 273 char *buffer, size_t buffer_len)
256{ 274{
@@ -263,7 +281,7 @@ static const char * get_props(int selected_item, void* data,
263 } 281 }
264 else 282 else
265 { 283 {
266 rb->strlcpy(buffer, props_dir[selected_item], buffer_len); 284 rb->strlcpy(buffer, p2str(props_dir[selected_item]), buffer_len);
267 } 285 }
268 } 286 }
269 else 287 else
@@ -274,12 +292,69 @@ static const char * get_props(int selected_item, void* data,
274 } 292 }
275 else 293 else
276 { 294 {
277 rb->strlcpy(buffer, props_file[selected_item], buffer_len); 295 rb->strlcpy(buffer, p2str(props_file[selected_item]), buffer_len);
278 } 296 }
279 } 297 }
280 return buffer; 298 return buffer;
281} 299}
282 300
301static int speak_property_selection(int selected_item, void *data)
302{
303 DPS *dps = data;
304 int32_t id = P2ID((its_a_dir ? props_dir : props_file)[selected_item]);
305 rb->talk_id(id, false);
306 switch (id)
307 {
308 case LANG_PROPERTIES_PATH:
309 if (str_dirname[0] == '/')
310 {
311 char *start = str_dirname;
312 char *ptr;
313 while (0 != (ptr = rb->strchr(start, '/')))
314 {
315 *ptr = '\0';
316 rb->talk_dir_or_spell(str_dirname, NULL, true);
317 *ptr = '/';
318 rb->talk_id(VOICE_CHAR_SLASH, true);
319 start = ptr + 1;
320 }
321 if (*start)
322 rb->talk_dir_or_spell(str_dirname, NULL, true);
323 }
324 else
325 {
326 rb->talk_spell(str_dirname, true);
327 }
328 break;
329 case LANG_PROPERTIES_FILENAME:
330 rb->talk_file_or_spell(str_dirname, str_filename, NULL, true);
331 break;
332 case LANG_PROPERTIES_SIZE:
333 rb->talk_number(nsize, true);
334 rb->talk_id(size_unit, true);
335 break;
336 case LANG_PROPERTIES_DATE:
337 rb->talk_date(&tm, true);
338 break;
339 case LANG_PROPERTIES_TIME:
340 rb->talk_time(&tm, true);
341 break;
342 case LANG_PROPERTIES_DURATION:
343 rb->talk_value(nseconds, UNIT_TIME, true);
344 break;
345 case LANG_PROPERTIES_SUBDIRS:
346 rb->talk_number(dps->dc, true);
347 break;
348 case LANG_PROPERTIES_FILES:
349 rb->talk_number(dps->fc, true);
350 break;
351 default:
352 rb->talk_spell(props_file[selected_item + 1], true);
353 break;
354 }
355 return 0;
356}
357
283enum plugin_status plugin_start(const void* parameter) 358enum plugin_status plugin_start(const void* parameter)
284{ 359{
285 struct gui_synclist properties_lists; 360 struct gui_synclist properties_lists;
@@ -337,7 +412,7 @@ enum plugin_status plugin_start(const void* parameter)
337 if(!(its_a_dir ? dir_properties(file, &dps) : file_properties(file))) 412 if(!(its_a_dir ? dir_properties(file, &dps) : file_properties(file)))
338 { 413 {
339 /* something went wrong (to do: tell user what it was (nesting,...) */ 414 /* something went wrong (to do: tell user what it was (nesting,...) */
340 rb->splash(0, "Failed to gather information"); 415 rb->splash(0, ID2P(LANG_PROPERTIES_FAIL));
341 rb->action_userabort(TIMEOUT_BLOCK); 416 rb->action_userabort(TIMEOUT_BLOCK);
342 return PLUGIN_OK; 417 return PLUGIN_OK;
343 } 418 }
@@ -348,14 +423,15 @@ enum plugin_status plugin_start(const void* parameter)
348#endif 423#endif
349 424
350 rb->gui_synclist_init(&properties_lists, &get_props, &dps, false, 2, NULL); 425 rb->gui_synclist_init(&properties_lists, &get_props, &dps, false, 2, NULL);
351 rb->gui_synclist_set_title(&properties_lists, its_a_dir ? 426 rb->gui_synclist_set_title(&properties_lists, rb->str(its_a_dir ? LANG_PROPERTIES_DIRECTORY_PROPERTIES : LANG_PROPERTIES_FILE_PROPERTIES), NOICON);
352 "Directory properties" :
353 "File properties", NOICON);
354 rb->gui_synclist_set_icon_callback(&properties_lists, NULL); 427 rb->gui_synclist_set_icon_callback(&properties_lists, NULL);
428 if (rb->global_settings->talk_menu)
429 rb->gui_synclist_set_voice_callback(&properties_lists, speak_property_selection);
355 rb->gui_synclist_set_nb_items(&properties_lists, num_properties * 2); 430 rb->gui_synclist_set_nb_items(&properties_lists, num_properties * 2);
356 rb->gui_synclist_limit_scroll(&properties_lists, true); 431 rb->gui_synclist_limit_scroll(&properties_lists, true);
357 rb->gui_synclist_select_item(&properties_lists, 0); 432 rb->gui_synclist_select_item(&properties_lists, 0);
358 rb->gui_synclist_draw(&properties_lists); 433 rb->gui_synclist_draw(&properties_lists);
434 rb->gui_synclist_speak_item(&properties_lists);
359 435
360 while(!quit) 436 while(!quit)
361 { 437 {