summaryrefslogtreecommitdiff
path: root/apps/plugins/properties.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/properties.c')
-rw-r--r--apps/plugins/properties.c433
1 files changed, 143 insertions, 290 deletions
diff --git a/apps/plugins/properties.c b/apps/plugins/properties.c
index 32bc8b9150..dcd3d89edf 100644
--- a/apps/plugins/properties.c
+++ b/apps/plugins/properties.c
@@ -25,14 +25,6 @@
25 #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) 25 #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
26#endif 26#endif
27 27
28struct dir_stats {
29 char dirname[MAX_PATH];
30 int len;
31 unsigned int dir_count;
32 unsigned int file_count;
33 unsigned long long byte_count;
34};
35
36enum props_types { 28enum props_types {
37 PROPS_FILE = 0, 29 PROPS_FILE = 0,
38 PROPS_PLAYLIST, 30 PROPS_PLAYLIST,
@@ -41,26 +33,20 @@ enum props_types {
41 PROPS_DIR 33 PROPS_DIR
42}; 34};
43 35
44static int props_type = PROPS_FILE; 36static struct gui_synclist properties_lists;
45
46static struct mp3entry id3; 37static struct mp3entry id3;
47static int mul_id3_count; 38static struct tm tm;
48static int skipped_count; 39static unsigned long display_size;
40static int32_t lang_size_unit;
41static int props_type, mul_id3_count, skipped_count;
49 42
50static char str_filename[MAX_PATH]; 43static char str_filename[MAX_PATH], str_dirname[MAX_PATH],
51static char str_dirname[MAX_PATH]; 44 str_size[64], str_dircount[64], str_filecount[64],
52static char str_size[64]; 45 str_audio_filecount[64], str_date[64], str_time[64];
53static char str_dircount[64];
54static char str_filecount[64];
55static char str_date[64];
56static char str_time[64];
57 46
58static unsigned long nsize;
59static int32_t size_unit;
60static struct tm tm;
61 47
62#define NUM_FILE_PROPERTIES 5 48#define NUM_FILE_PROPERTIES 5
63#define NUM_PLAYLIST_PROPERTIES 1 + NUM_FILE_PROPERTIES 49#define NUM_PLAYLIST_PROPERTIES (1 + NUM_FILE_PROPERTIES)
64static const unsigned char* const props_file[] = 50static const unsigned char* const props_file[] =
65{ 51{
66 ID2P(LANG_PROPERTIES_PATH), str_dirname, 52 ID2P(LANG_PROPERTIES_PATH), str_dirname,
@@ -68,170 +54,44 @@ static const unsigned char* const props_file[] =
68 ID2P(LANG_PROPERTIES_SIZE), str_size, 54 ID2P(LANG_PROPERTIES_SIZE), str_size,
69 ID2P(LANG_PROPERTIES_DATE), str_date, 55 ID2P(LANG_PROPERTIES_DATE), str_date,
70 ID2P(LANG_PROPERTIES_TIME), str_time, 56 ID2P(LANG_PROPERTIES_TIME), str_time,
57
71 ID2P(LANG_MENU_SHOW_ID3_INFO), "...", 58 ID2P(LANG_MENU_SHOW_ID3_INFO), "...",
72}; 59};
73 60
74#define NUM_DIR_PROPERTIES 4 61#define NUM_DIR_PROPERTIES 4
62#define NUM_AUDIODIR_PROPERTIES (1 + NUM_DIR_PROPERTIES)
75static const unsigned char* const props_dir[] = 63static const unsigned char* const props_dir[] =
76{ 64{
77 ID2P(LANG_PROPERTIES_PATH), str_dirname, 65 ID2P(LANG_PROPERTIES_PATH), str_dirname,
78 ID2P(LANG_PROPERTIES_SUBDIRS), str_dircount, 66 ID2P(LANG_PROPERTIES_SUBDIRS), str_dircount,
79 ID2P(LANG_PROPERTIES_FILES), str_filecount, 67 ID2P(LANG_PROPERTIES_FILES), str_filecount,
80 ID2P(LANG_PROPERTIES_SIZE), str_size, 68 ID2P(LANG_PROPERTIES_SIZE), str_size,
81};
82 69
83static const int32_t units[] = 70 ID2P(LANG_MENU_SHOW_ID3_INFO), str_audio_filecount,
84{
85 LANG_BYTE,
86 LANG_KIBIBYTE,
87 LANG_MEBIBYTE,
88 LANG_GIBIBYTE
89}; 71};
90 72
91static unsigned human_size_log(unsigned long long size)
92{
93 const size_t n = sizeof(units)/sizeof(units[0]);
94
95 unsigned i;
96 /* margin set at 10K boundary: 10239 B +1 => 10 KB */
97 for(i=0; i < n-1 && size >= 10*1024; i++)
98 size >>= 10; /* div by 1024 */
99
100 return i;
101}
102
103static bool file_properties(const char* selected_file)
104{
105 bool found = false;
106 DIR* dir;
107 struct dirent* entry;
108
109 dir = rb->opendir(str_dirname);
110 if (dir)
111 {
112 while(0 != (entry = rb->readdir(dir)))
113 {
114 struct dirinfo info = rb->dir_get_info(dir, entry);
115 if(!rb->strcmp(entry->d_name, str_filename))
116 {
117 unsigned log;
118 log = human_size_log((unsigned long)info.size);
119 nsize = ((unsigned long)info.size) >> (log*10);
120 size_unit = units[log];
121 rb->snprintf(str_size, sizeof str_size, "%lu %s",
122 nsize, rb->str(size_unit));
123 rb->gmtime_r(&info.mtime, &tm);
124 rb->snprintf(str_date, sizeof str_date, "%04d/%02d/%02d",
125 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
126 rb->snprintf(str_time, sizeof str_time, "%02d:%02d:%02d",
127 tm.tm_hour, tm.tm_min, tm.tm_sec);
128
129 if (!rb->mp3info(&id3, selected_file))
130 props_type = PROPS_ID3;
131 found = true;
132 break;
133 }
134 }
135 rb->closedir(dir);
136 }
137 return found;
138}
139
140static bool _dir_properties(struct dir_stats *stats)
141{
142 /* recursively scan directories in search of files
143 and informs the user of the progress */
144 bool result;
145 static long lasttick=0;
146 int dirlen;
147 DIR* dir;
148 struct dirent* entry;
149
150 result = true;
151 dirlen = rb->strlen(stats->dirname);
152 dir = rb->opendir(stats->dirname);
153 if (!dir)
154 {
155 rb->splashf(HZ*2, "%s", stats->dirname);
156 return false; /* open error */
157 }
158
159 /* walk through the directory content */
160 while(result && (0 != (entry = rb->readdir(dir))))
161 {
162 struct dirinfo info = rb->dir_get_info(dir, entry);
163 /* append name to current directory */
164 rb->snprintf(stats->dirname+dirlen, stats->len-dirlen, "/%s",
165 entry->d_name);
166
167 if (info.attribute & ATTR_DIRECTORY)
168 {
169 if (!rb->strcmp((char *)entry->d_name, ".") ||
170 !rb->strcmp((char *)entry->d_name, ".."))
171 continue; /* skip these */
172
173 stats->dir_count++; /* new directory */
174 if (*rb->current_tick - lasttick > (HZ/8))
175 {
176 unsigned log;
177 lasttick = *rb->current_tick;
178 rb->lcd_clear_display();
179 rb->lcd_puts(0,0,"SCANNING...");
180 rb->lcd_puts(0,1,stats->dirname);
181 rb->lcd_putsf(0,2,"Directories: %d", stats->dir_count);
182 rb->lcd_putsf(0,3,"Files: %d", stats->file_count);
183 log = human_size_log(stats->byte_count);
184 rb->lcd_putsf(0,4,"Size: %lu %s",
185 (unsigned long)(stats->byte_count >> (10*log)),
186 rb->str(units[log]));
187 rb->lcd_update();
188 }
189
190 /* recursion */
191 result = _dir_properties(stats);
192 }
193 else
194 {
195 stats->file_count++; /* new file */
196 stats->byte_count += info.size;
197 }
198 if(ACTION_STD_CANCEL == rb->get_action(CONTEXT_STD,TIMEOUT_NOBLOCK))
199 result = false;
200 rb->yield();
201 }
202 rb->closedir(dir);
203 return result;
204}
205
206static bool dir_properties(const char* selected_file, struct dir_stats *stats) 73static bool dir_properties(const char* selected_file, struct dir_stats *stats)
207{ 74{
208 unsigned log; 75 rb->strlcpy(stats->dirname, selected_file, sizeof(stats->dirname));
209
210 rb->strlcpy(stats->dirname, selected_file, MAX_PATH);
211 76
212#ifdef HAVE_ADJUSTABLE_CPU_FREQ 77#ifdef HAVE_ADJUSTABLE_CPU_FREQ
213 rb->cpu_boost(true); 78 rb->cpu_boost(true);
214#endif 79#endif
215 80 bool success = collect_dir_stats(stats, NULL);
216 if (!_dir_properties(stats))
217 {
218#ifdef HAVE_ADJUSTABLE_CPU_FREQ 81#ifdef HAVE_ADJUSTABLE_CPU_FREQ
219 rb->cpu_boost(false); 82 rb->cpu_boost(false);
220#endif 83#endif
84 if (!success)
221 return false; 85 return false;
222 }
223 86
224#ifdef HAVE_ADJUSTABLE_CPU_FREQ 87 rb->strlcpy(str_dirname, selected_file, sizeof(str_dirname));
225 rb->cpu_boost(false);
226#endif
227
228 rb->strlcpy(str_dirname, selected_file, MAX_PATH);
229 rb->snprintf(str_dircount, sizeof str_dircount, "%d", stats->dir_count); 88 rb->snprintf(str_dircount, sizeof str_dircount, "%d", stats->dir_count);
230 rb->snprintf(str_filecount, sizeof str_filecount, "%d", stats->file_count); 89 rb->snprintf(str_filecount, sizeof str_filecount, "%d", stats->file_count);
231 log = human_size_log(stats->byte_count); 90 rb->snprintf(str_audio_filecount, sizeof str_filecount, "%d",
232 nsize = (long) (stats->byte_count >> (log*10)); 91 stats->audio_file_count);
233 size_unit = units[log]; 92 display_size = human_size(stats->byte_count, &lang_size_unit);
234 rb->snprintf(str_size, sizeof str_size, "%ld %s", nsize, rb->str(size_unit)); 93 rb->snprintf(str_size, sizeof str_size, "%lu %s", display_size,
94 rb->str(lang_size_unit));
235 return true; 95 return true;
236} 96}
237 97
@@ -246,12 +106,11 @@ static const char * get_props(int selected_item, void* data,
246{ 106{
247 (void)data; 107 (void)data;
248 if (PROPS_DIR == props_type) 108 if (PROPS_DIR == props_type)
249 rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_dir)) ? "ERROR" : 109 rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_dir)) ?
250 (char *) p2str(props_dir[selected_item]), buffer_len); 110 "ERROR" : (char *) p2str(props_dir[selected_item]), buffer_len);
251 else 111 else
252 rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_file)) ? "ERROR" : 112 rb->strlcpy(buffer, selected_item >= (int)(ARRAY_SIZE(props_file)) ?
253 (char *) p2str(props_file[selected_item]), buffer_len); 113 "ERROR" : (char *) p2str(props_file[selected_item]), buffer_len);
254
255 return buffer; 114 return buffer;
256} 115}
257 116
@@ -264,32 +123,14 @@ static int speak_property_selection(int selected_item, void *data)
264 switch (id) 123 switch (id)
265 { 124 {
266 case LANG_PROPERTIES_PATH: 125 case LANG_PROPERTIES_PATH:
267 if (str_dirname[0] == '/') 126 rb->talk_fullpath(str_dirname, true);
268 {
269 char *start = str_dirname;
270 char *ptr;
271 while (0 != (ptr = rb->strchr(start, '/')))
272 {
273 *ptr = '\0';
274 rb->talk_dir_or_spell(str_dirname, NULL, true);
275 *ptr = '/';
276 rb->talk_id(VOICE_CHAR_SLASH, true);
277 start = ptr + 1;
278 }
279 if (*start)
280 rb->talk_dir_or_spell(str_dirname, NULL, true);
281 }
282 else
283 {
284 rb->talk_spell(str_dirname, true);
285 }
286 break; 127 break;
287 case LANG_PROPERTIES_FILENAME: 128 case LANG_PROPERTIES_FILENAME:
288 rb->talk_file_or_spell(str_dirname, str_filename, NULL, true); 129 rb->talk_file_or_spell(str_dirname, str_filename, NULL, true);
289 break; 130 break;
290 case LANG_PROPERTIES_SIZE: 131 case LANG_PROPERTIES_SIZE:
291 rb->talk_number(nsize, true); 132 rb->talk_number(display_size, true);
292 rb->talk_id(size_unit, true); 133 rb->talk_id(lang_size_unit, true);
293 break; 134 break;
294 case LANG_PROPERTIES_DATE: 135 case LANG_PROPERTIES_DATE:
295 rb->talk_date(&tm, true); 136 rb->talk_date(&tm, true);
@@ -310,40 +151,46 @@ static int speak_property_selection(int selected_item, void *data)
310 return 0; 151 return 0;
311} 152}
312 153
313static int browse_file_or_dir(struct dir_stats *stats) 154static void setup_properties_list(struct dir_stats *stats)
314{ 155{
315 struct gui_synclist properties_lists; 156 int nb_props;
316 int button; 157 if (props_type == PROPS_FILE)
158 nb_props = NUM_FILE_PROPERTIES;
159 else if (props_type == PROPS_PLAYLIST)
160 nb_props = NUM_PLAYLIST_PROPERTIES;
161 else
162 nb_props = NUM_DIR_PROPERTIES;
317 163
318 rb->gui_synclist_init(&properties_lists, &get_props, stats, false, 2, NULL); 164 rb->gui_synclist_init(&properties_lists, &get_props, stats, false, 2, NULL);
319 rb->gui_synclist_set_title(&properties_lists, 165 rb->gui_synclist_set_title(&properties_lists,
320 rb->str(props_type == PROPS_DIR ? 166 rb->str(props_type == PROPS_DIR ?
321 LANG_PROPERTIES_DIRECTORY_PROPERTIES : 167 LANG_PROPERTIES_DIRECTORY_PROPERTIES :
322 LANG_PROPERTIES_FILE_PROPERTIES), 168 LANG_PROPERTIES_FILE_PROPERTIES),
323 NOICON); 169 NOICON);
324 rb->gui_synclist_set_icon_callback(&properties_lists, NULL);
325 if (rb->global_settings->talk_menu) 170 if (rb->global_settings->talk_menu)
326 rb->gui_synclist_set_voice_callback(&properties_lists, speak_property_selection); 171 rb->gui_synclist_set_voice_callback(&properties_lists, speak_property_selection);
327 rb->gui_synclist_set_nb_items(&properties_lists, 172 rb->gui_synclist_set_nb_items(&properties_lists, nb_props*2);
328 2 * (props_type == PROPS_FILE ? NUM_FILE_PROPERTIES : 173}
329 props_type == PROPS_PLAYLIST ? 174
330 NUM_PLAYLIST_PROPERTIES : NUM_DIR_PROPERTIES)); 175static int browse_file_or_dir(struct dir_stats *stats)
331 rb->gui_synclist_select_item(&properties_lists, 0); 176{
177 if (props_type == PROPS_DIR && stats->audio_file_count)
178 rb->gui_synclist_set_nb_items(&properties_lists, NUM_AUDIODIR_PROPERTIES*2);
332 rb->gui_synclist_draw(&properties_lists); 179 rb->gui_synclist_draw(&properties_lists);
333 rb->gui_synclist_speak_item(&properties_lists); 180 rb->gui_synclist_speak_item(&properties_lists);
334
335 while(true) 181 while(true)
336 { 182 {
337 button = rb->get_action(CONTEXT_LIST, HZ); 183 int button = rb->get_action(CONTEXT_LIST, HZ);
338 /* HZ so the status bar redraws corectly */ 184 /* HZ so the status bar redraws corectly */
339 if (rb->gui_synclist_do_button(&properties_lists,&button)) 185 if (rb->gui_synclist_do_button(&properties_lists, &button))
340 continue; 186 continue;
341 switch(button) 187 switch(button)
342 { 188 {
343 case ACTION_STD_OK: 189 case ACTION_STD_OK:
344 if (props_type == PROPS_PLAYLIST && 190 if ((props_type == PROPS_PLAYLIST || props_type == PROPS_DIR) &&
345 rb->gui_synclist_get_sel_pos(&properties_lists) 191 rb->gui_synclist_get_sel_pos(&properties_lists)
346 == ARRAY_SIZE(props_file) - 2) 192 == (props_type == PROPS_DIR ?
193 ARRAY_SIZE(props_dir) : ARRAY_SIZE(props_file)) - 2)
347 return -1; 194 return -1;
348 break; 195 break;
349 case ACTION_STD_CANCEL: 196 case ACTION_STD_CANCEL:
@@ -356,60 +203,101 @@ static int browse_file_or_dir(struct dir_stats *stats)
356 } 203 }
357} 204}
358 205
359static bool determine_file_or_dir(void) 206static bool determine_props_type(const char *file)
360{ 207{
361 DIR* dir; 208 if (file[0] == PATH_SEPCH)
362 struct dirent* entry;
363
364 dir = rb->opendir(str_dirname);
365 if (dir)
366 { 209 {
210 const char* basename = rb->strrchr(file, PATH_SEPCH) + 1;
211 const int dir_len = (basename - file);
212 if ((int) sizeof(str_dirname) <= dir_len)
213 return false;
214 rb->strlcpy(str_dirname, file, dir_len + 1);
215 rb->strlcpy(str_filename, basename, sizeof str_filename);
216 struct dirent* entry;
217 DIR* dir = rb->opendir(str_dirname);
218 if (!dir)
219 return false;
367 while(0 != (entry = rb->readdir(dir))) 220 while(0 != (entry = rb->readdir(dir)))
368 { 221 {
369 if(!rb->strcmp(entry->d_name, str_filename)) 222 if(rb->strcmp(entry->d_name, str_filename))
223 continue;
224
225 struct dirinfo info = rb->dir_get_info(dir, entry);
226 if (info.attribute & ATTR_DIRECTORY)
227 props_type = PROPS_DIR;
228 else
370 { 229 {
371 struct dirinfo info = rb->dir_get_info(dir, entry); 230 display_size = human_size(info.size, &lang_size_unit);
372 props_type = info.attribute & ATTR_DIRECTORY ? PROPS_DIR : PROPS_FILE; 231 rb->snprintf(str_size, sizeof str_size, "%lu %s",
373 rb->closedir(dir); 232 display_size, rb->str(lang_size_unit));
374 return true; 233 rb->gmtime_r(&info.mtime, &tm);
234 rb->snprintf(str_date, sizeof str_date, "%04d/%02d/%02d",
235 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
236 rb->snprintf(str_time, sizeof str_time, "%02d:%02d:%02d",
237 tm.tm_hour, tm.tm_min, tm.tm_sec);
238
239 if (rb->filetype_get_attr(entry->d_name) == FILE_ATTR_M3U)
240 props_type = PROPS_PLAYLIST;
241 else
242 props_type = rb->get_metadata(&id3, -1, file) ?
243 PROPS_ID3 : PROPS_FILE;
375 } 244 }
245 rb->closedir(dir);
246 return true;
376 } 247 }
377 rb->closedir(dir); 248 rb->closedir(dir);
378 } 249 }
250 else if (!rb->strcmp(file, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER)))
251 {
252 props_type = PROPS_MUL_ID3;
253 return true;
254 }
379 return false; 255 return false;
380} 256}
381 257
382bool mul_id3_add(const char *file_name) 258bool mul_id3_add(const char *file_name)
383{ 259{
384 if (!file_name || rb->mp3info(&id3, file_name)) 260 if (!file_name || !rb->get_metadata(&id3, -1, file_name))
385 skipped_count++; 261 skipped_count++;
386 else 262 else
387 { 263 {
388 collect_id3(&id3, mul_id3_count == 0); 264 collect_id3(&id3, mul_id3_count == 0);
389 mul_id3_count++; 265 mul_id3_count++;
390 } 266 }
391
392 return true; 267 return true;
393} 268}
394 269
395static bool has_pl_extension(const char* filename) 270/* Assemble track info from a dir, a playlist, or a database table */
396{ 271static bool assemble_track_info(const char *filename, struct dir_stats *stats)
397 char *dot = rb->strrchr(filename, '.');
398 return (dot && (!rb->strcasecmp(dot, ".m3u") || !rb->strcasecmp(dot, ".m3u8")));
399}
400
401/* Assemble track info from a database table or the contents of a playlist file */
402static bool assemble_track_info(const char *filename)
403{ 272{
404 props_type = PROPS_MUL_ID3; 273 if (props_type == PROPS_DIR)
405 mul_id3_count = skipped_count = 0; 274 {
406 275#ifdef HAVE_ADJUSTABLE_CPU_FREQ
407 if ( (filename && !rb->playlist_entries_iterate(filename, NULL, &mul_id3_add)) 276 rb->cpu_boost(true);
277#endif
278 rb->strlcpy(stats->dirname, filename, sizeof(stats->dirname));
279 rb->splash_progress_set_delay(HZ/2); /* hide progress bar for 0.5s */
280 bool success = collect_dir_stats(stats, &mul_id3_add);
281#ifdef HAVE_ADJUSTABLE_CPU_FREQ
282 rb->cpu_boost(false);
283#endif
284 if (!success)
285 return false;
286 }
287 else if(props_type == PROPS_PLAYLIST &&
288 !rb->playlist_entries_iterate(filename, NULL, &mul_id3_add))
289 return false;
408#ifdef HAVE_TAGCACHE 290#ifdef HAVE_TAGCACHE
409 || (!filename && !rb->tagtree_subentries_do_action(&mul_id3_add)) 291 else if (props_type == PROPS_MUL_ID3 &&
292 !rb->tagtree_subentries_do_action(&mul_id3_add))
293 return false;
410#endif 294#endif
411 || mul_id3_count == 0) 295
296 if (mul_id3_count == 0)
297 {
298 rb->splashf(HZ*2, "None found");
412 return false; 299 return false;
300 }
413 else if (mul_id3_count > 1) /* otherwise, the retrieved id3 can be used as-is */ 301 else if (mul_id3_count > 1) /* otherwise, the retrieved id3 can be used as-is */
414 finalize_id3(&id3); 302 finalize_id3(&id3);
415 303
@@ -421,78 +309,43 @@ static bool assemble_track_info(const char *filename)
421 309
422enum plugin_status plugin_start(const void* parameter) 310enum plugin_status plugin_start(const void* parameter)
423{ 311{
424 int ret; 312 static struct dir_stats stats;
425 static struct dir_stats stats =
426 {
427 .len = MAX_PATH,
428 .dir_count = 0,
429 .file_count = 0,
430 .byte_count = 0,
431 };
432
433 const char *file = parameter; 313 const char *file = parameter;
434 if(!parameter)
435 return PLUGIN_ERROR;
436
437#ifdef HAVE_TOUCHSCREEN 314#ifdef HAVE_TOUCHSCREEN
438 rb->touchscreen_set_mode(rb->global_settings->touch_mode); 315 rb->touchscreen_set_mode(rb->global_settings->touch_mode);
439#endif 316#endif
440 317 int ret = file && determine_props_type(file);
441 if (file[0] == '/') /* single file selected */ 318 if (!ret)
442 { 319 {
443 const char* file_name = rb->strrchr(file, '/') + 1; 320 rb->splashf(0, "Could not find: %s", file ?: "(NULL)");
444 int dirlen = (file_name - file); 321 rb->action_userabort(TIMEOUT_BLOCK);
445 322 return PLUGIN_OK;
446 rb->strlcpy(str_dirname, file, dirlen + 1); 323 }
447 rb->snprintf(str_filename, sizeof str_filename, "%s", file+dirlen);
448
449 if(!determine_file_or_dir())
450 {
451 /* weird: we couldn't find the entry. This Should Never Happen (TM) */
452 rb->splashf(0, "File/Dir not found: %s", file);
453 rb->action_userabort(TIMEOUT_BLOCK);
454 return PLUGIN_OK;
455 }
456
457 if (props_type == PROPS_FILE && has_pl_extension(file))
458 props_type = PROPS_PLAYLIST;
459 324
460 /* get the info depending on its_a_dir */ 325 if (props_type == PROPS_MUL_ID3)
461 if(!(props_type == PROPS_DIR ? 326 ret = assemble_track_info(NULL, NULL);
462 dir_properties(file, &stats) : file_properties(file))) 327 else if (props_type != PROPS_ID3)
328 {
329 setup_properties_list(&stats); /* Show title during dir scan */
330 if (props_type == PROPS_DIR)
331 ret = dir_properties(file, &stats);
332 }
333 if (!ret)
334 {
335 if (!stats.canceled)
463 { 336 {
464 /* something went wrong (to do: tell user what it was (nesting,...) */ 337 rb->splash(0, ID2P(LANG_PROPERTIES_FAIL)); /* TODO: describe error */
465 rb->splash(0, ID2P(LANG_PROPERTIES_FAIL));
466 rb->action_userabort(TIMEOUT_BLOCK); 338 rb->action_userabort(TIMEOUT_BLOCK);
467 return PLUGIN_OK;
468 } 339 }
469 } 340 }
470 /* database table selected */ 341 else if (props_type == PROPS_ID3)
471 else if (rb->strcmp(file, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER))
472 || !assemble_track_info(NULL))
473 return PLUGIN_ERROR;
474
475 FOR_NB_SCREENS(i)
476 rb->viewportmanager_theme_enable(i, true, NULL);
477
478 if (props_type == PROPS_ID3)
479 ret = rb->browse_id3(&id3, 0, 0, &tm, 1); /* Track Info for single file */ 342 ret = rb->browse_id3(&id3, 0, 0, &tm, 1); /* Track Info for single file */
480 else if (props_type == PROPS_MUL_ID3) 343 else if (props_type == PROPS_MUL_ID3)
481 ret = rb->browse_id3(&id3, 0, 0, NULL, mul_id3_count); /* database tracks */ 344 ret = rb->browse_id3(&id3, 0, 0, NULL, mul_id3_count); /* database tracks */
482 else if ((ret = browse_file_or_dir(&stats)) < 0) 345 else if ((ret = browse_file_or_dir(&stats)) < 0)
483 ret = assemble_track_info(file) ? /* playlist tracks */ 346 ret = assemble_track_info(file, &stats) ? /* playlist or folder tracks */
484 rb->browse_id3(&id3, 0, 0, NULL, mul_id3_count) : -1; 347 rb->browse_id3(&id3, 0, 0, NULL, mul_id3_count) :
348 (stats.canceled ? 0 : -1);
485 349
486 FOR_NB_SCREENS(i) 350 return ret == -1 ? PLUGIN_ERROR : ret == 1 ? PLUGIN_USB_CONNECTED : PLUGIN_OK;
487 rb->viewportmanager_theme_undo(i, false);
488
489 switch (ret)
490 {
491 case 1:
492 return PLUGIN_USB_CONNECTED;
493 case -1:
494 return PLUGIN_ERROR;
495 default:
496 return PLUGIN_OK;
497 }
498} 351}