diff options
-rw-r--r-- | apps/misc.h | 3 | ||||
-rw-r--r-- | apps/onplay.c | 35 | ||||
-rw-r--r-- | apps/plugin.c | 3 | ||||
-rw-r--r-- | apps/plugin.h | 6 | ||||
-rw-r--r-- | apps/plugins/properties.c | 94 | ||||
-rw-r--r-- | apps/tagtree.c | 138 | ||||
-rw-r--r-- | apps/tagtree.h | 2 |
7 files changed, 205 insertions, 76 deletions
diff --git a/apps/misc.h b/apps/misc.h index 51684cb658..403a8c53ac 100644 --- a/apps/misc.h +++ b/apps/misc.h | |||
@@ -187,6 +187,9 @@ enum current_activity { | |||
187 | ACTIVITY_USBSCREEN | 187 | ACTIVITY_USBSCREEN |
188 | }; | 188 | }; |
189 | 189 | ||
190 | /* custom string representation of activity */ | ||
191 | #define MAKE_ACT_STR(act) ((char[3]){'>', 'A'+ (act), 0x0}) | ||
192 | |||
190 | void beep_play(unsigned int frequency, unsigned int duration, | 193 | void beep_play(unsigned int frequency, unsigned int duration, |
191 | unsigned int amplitude); | 194 | unsigned int amplitude); |
192 | 195 | ||
diff --git a/apps/onplay.c b/apps/onplay.c index f92ed76050..96c2ddd4e3 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -1611,8 +1611,33 @@ static bool list_viewers(void) | |||
1611 | return false; | 1611 | return false; |
1612 | } | 1612 | } |
1613 | 1613 | ||
1614 | #ifdef HAVE_TAGCACHE | ||
1615 | static bool prepare_database_sel(void *param) | ||
1616 | { | ||
1617 | if (context == CONTEXT_ID3DB && | ||
1618 | (selected_file_attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) | ||
1619 | { | ||
1620 | if (!strcmp(param, "properties")) | ||
1621 | strmemccpy(selected_file_path, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER), | ||
1622 | sizeof(selected_file_path)); | ||
1623 | else if (!tagtree_get_subentry_filename(selected_file_path, MAX_PATH)) | ||
1624 | { | ||
1625 | onplay_result = ONPLAY_RELOAD_DIR; | ||
1626 | return false; | ||
1627 | } | ||
1628 | |||
1629 | selected_file = selected_file_path; | ||
1630 | } | ||
1631 | return true; | ||
1632 | } | ||
1633 | #endif | ||
1634 | |||
1614 | static bool onplay_load_plugin(void *param) | 1635 | static bool onplay_load_plugin(void *param) |
1615 | { | 1636 | { |
1637 | #ifdef HAVE_TAGCACHE | ||
1638 | if (!prepare_database_sel(param)) | ||
1639 | return false; | ||
1640 | #endif | ||
1616 | int ret = filetype_load_plugin((const char*)param, selected_file); | 1641 | int ret = filetype_load_plugin((const char*)param, selected_file); |
1617 | if (ret == PLUGIN_USB_CONNECTED) | 1642 | if (ret == PLUGIN_USB_CONNECTED) |
1618 | onplay_result = ONPLAY_RELOAD_DIR; | 1643 | onplay_result = ONPLAY_RELOAD_DIR; |
@@ -1717,10 +1742,8 @@ static int clipboard_callback(int action, | |||
1717 | #ifdef HAVE_TAGCACHE | 1742 | #ifdef HAVE_TAGCACHE |
1718 | if (context == CONTEXT_ID3DB) | 1743 | if (context == CONTEXT_ID3DB) |
1719 | { | 1744 | { |
1720 | if (((selected_file_attr & FILE_ATTR_MASK) == | 1745 | if (this_item == &track_info_item || |
1721 | FILE_ATTR_AUDIO) && | 1746 | this_item == &pictureflow_item) |
1722 | (this_item == &track_info_item || | ||
1723 | this_item == &pictureflow_item)) | ||
1724 | return action; | 1747 | return action; |
1725 | return ACTION_EXIT_MENUITEM; | 1748 | return ACTION_EXIT_MENUITEM; |
1726 | } | 1749 | } |
@@ -1895,6 +1918,10 @@ static int hotkey_tree_pl_insert_shuffled(void) | |||
1895 | 1918 | ||
1896 | static int hotkey_tree_run_plugin(void *param) | 1919 | static int hotkey_tree_run_plugin(void *param) |
1897 | { | 1920 | { |
1921 | #ifdef HAVE_TAGCACHE | ||
1922 | if (!prepare_database_sel(param)) | ||
1923 | return ONPLAY_RELOAD_DIR; | ||
1924 | #endif | ||
1898 | if (filetype_load_plugin((const char*)param, selected_file) == PLUGIN_GOTO_WPS) | 1925 | if (filetype_load_plugin((const char*)param, selected_file) == PLUGIN_GOTO_WPS) |
1899 | return ONPLAY_START_PLAY; | 1926 | return ONPLAY_START_PLAY; |
1900 | 1927 | ||
diff --git a/apps/plugin.c b/apps/plugin.c index c28954e9eb..00fac21b8d 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -825,6 +825,9 @@ static const struct plugin_api rockbox_api = { | |||
825 | splash_progress_set_delay, | 825 | splash_progress_set_delay, |
826 | fix_path_part, | 826 | fix_path_part, |
827 | onplay_show_playlist_cat_menu, | 827 | onplay_show_playlist_cat_menu, |
828 | #if defined(HAVE_TAGCACHE) | ||
829 | tagtree_subentries_do_action, | ||
830 | #endif | ||
828 | }; | 831 | }; |
829 | 832 | ||
830 | static int plugin_buffer_handle; | 833 | static int plugin_buffer_handle; |
diff --git a/apps/plugin.h b/apps/plugin.h index 850e7484d9..20df7e72f2 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -103,6 +103,7 @@ int plugin_open(const char *plugin, const char *parameter); | |||
103 | #include "buflib.h" | 103 | #include "buflib.h" |
104 | #include "buffering.h" | 104 | #include "buffering.h" |
105 | #include "tagcache.h" | 105 | #include "tagcache.h" |
106 | #include "tagtree.h" | ||
106 | #include "viewport.h" | 107 | #include "viewport.h" |
107 | #include "ata_idle_notify.h" | 108 | #include "ata_idle_notify.h" |
108 | #include "settings_list.h" | 109 | #include "settings_list.h" |
@@ -157,7 +158,7 @@ int plugin_open(const char *plugin, const char *parameter); | |||
157 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ | 158 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ |
158 | 159 | ||
159 | /* increase this every time the api struct changes */ | 160 | /* increase this every time the api struct changes */ |
160 | #define PLUGIN_API_VERSION 263 | 161 | #define PLUGIN_API_VERSION 264 |
161 | 162 | ||
162 | /* update this to latest version if a change to the api struct breaks | 163 | /* update this to latest version if a change to the api struct breaks |
163 | backwards compatibility (and please take the opportunity to sort in any | 164 | backwards compatibility (and please take the opportunity to sort in any |
@@ -950,6 +951,9 @@ struct plugin_api { | |||
950 | void (*fix_path_part)(char* path, int offset, int count); | 951 | void (*fix_path_part)(char* path, int offset, int count); |
951 | void (*onplay_show_playlist_cat_menu)(const char* track_name, int attr, | 952 | void (*onplay_show_playlist_cat_menu)(const char* track_name, int attr, |
952 | void (*add_to_pl_cb)); | 953 | void (*add_to_pl_cb)); |
954 | #ifdef HAVE_TAGCACHE | ||
955 | bool (*tagtree_subentries_do_action)(bool (*action_cb)(const char *file_name)); | ||
956 | #endif | ||
953 | }; | 957 | }; |
954 | 958 | ||
955 | /* plugin header */ | 959 | /* plugin header */ |
diff --git a/apps/plugins/properties.c b/apps/plugins/properties.c index 46cf818fb4..7dacda3579 100644 --- a/apps/plugins/properties.c +++ b/apps/plugins/properties.c | |||
@@ -19,6 +19,11 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include "plugin.h" | 21 | #include "plugin.h" |
22 | #include "lib/id3.h" | ||
23 | |||
24 | #ifdef HAVE_TAGCACHE | ||
25 | #include "lib/mul_id3.h" | ||
26 | #endif | ||
22 | 27 | ||
23 | #if !defined(ARRAY_SIZE) | 28 | #if !defined(ARRAY_SIZE) |
24 | #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) | 29 | #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) |
@@ -35,12 +40,16 @@ struct dir_stats { | |||
35 | enum props_types { | 40 | enum props_types { |
36 | PROPS_FILE = 0, | 41 | PROPS_FILE = 0, |
37 | PROPS_ID3, | 42 | PROPS_ID3, |
43 | PROPS_MUL_ID3, | ||
38 | PROPS_DIR | 44 | PROPS_DIR |
39 | }; | 45 | }; |
40 | 46 | ||
41 | static int props_type = PROPS_FILE; | 47 | static int props_type = PROPS_FILE; |
42 | 48 | ||
43 | static struct mp3entry id3; | 49 | static struct mp3entry id3; |
50 | #ifdef HAVE_TAGCACHE | ||
51 | static int mul_id3_count; | ||
52 | #endif | ||
44 | 53 | ||
45 | static char str_filename[MAX_PATH]; | 54 | static char str_filename[MAX_PATH]; |
46 | static char str_dirname[MAX_PATH]; | 55 | static char str_dirname[MAX_PATH]; |
@@ -118,14 +127,8 @@ static bool file_properties(const char* selected_file) | |||
118 | rb->snprintf(str_time, sizeof str_time, "%02d:%02d:%02d", | 127 | rb->snprintf(str_time, sizeof str_time, "%02d:%02d:%02d", |
119 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 128 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
120 | 129 | ||
121 | int fd = rb->open(selected_file, O_RDONLY); | 130 | if (retrieve_id3(&id3, selected_file, false)) |
122 | if (fd >= 0) | 131 | props_type = PROPS_ID3; |
123 | { | ||
124 | if (rb->get_metadata(&id3, fd, selected_file)) | ||
125 | props_type = PROPS_ID3; | ||
126 | |||
127 | rb->close(fd); | ||
128 | } | ||
129 | found = true; | 132 | found = true; |
130 | break; | 133 | break; |
131 | } | 134 | } |
@@ -369,6 +372,19 @@ static bool determine_file_or_dir(void) | |||
369 | return false; | 372 | return false; |
370 | } | 373 | } |
371 | 374 | ||
375 | #ifdef HAVE_TAGCACHE | ||
376 | bool mul_id3_add(const char *file_name) | ||
377 | { | ||
378 | if (!retrieve_id3(&id3, file_name, false)) | ||
379 | return false; | ||
380 | |||
381 | collect_id3(&id3, mul_id3_count == 0); | ||
382 | mul_id3_count++; | ||
383 | |||
384 | return true; | ||
385 | } | ||
386 | #endif | ||
387 | |||
372 | enum plugin_status plugin_start(const void* parameter) | 388 | enum plugin_status plugin_start(const void* parameter) |
373 | { | 389 | { |
374 | static struct dir_stats stats = | 390 | static struct dir_stats stats = |
@@ -380,40 +396,62 @@ enum plugin_status plugin_start(const void* parameter) | |||
380 | }; | 396 | }; |
381 | 397 | ||
382 | const char *file = parameter; | 398 | const char *file = parameter; |
383 | if(!parameter || (file[0] != '/')) return PLUGIN_ERROR; | 399 | if(!parameter) |
400 | return PLUGIN_ERROR; | ||
384 | 401 | ||
385 | #ifdef HAVE_TOUCHSCREEN | 402 | #ifdef HAVE_TOUCHSCREEN |
386 | rb->touchscreen_set_mode(rb->global_settings->touch_mode); | 403 | rb->touchscreen_set_mode(rb->global_settings->touch_mode); |
387 | #endif | 404 | #endif |
388 | 405 | ||
389 | const char* file_name = rb->strrchr(file, '/') + 1; | 406 | #ifdef HAVE_TAGCACHE |
390 | int dirlen = (file_name - file); | 407 | if (!rb->strcmp(file, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER))) /* db table selected */ |
408 | { | ||
409 | props_type = PROPS_MUL_ID3; | ||
410 | init_mul_id3(); | ||
411 | mul_id3_count = 0; | ||
391 | 412 | ||
392 | rb->strlcpy(str_dirname, file, dirlen + 1); | 413 | if (!rb->tagtree_subentries_do_action(&mul_id3_add) || mul_id3_count == 0) |
393 | rb->snprintf(str_filename, sizeof str_filename, "%s", file+dirlen); | 414 | return PLUGIN_ERROR; |
394 | 415 | ||
395 | if(!determine_file_or_dir()) | 416 | if (mul_id3_count > 1) /* otherwise, the retrieved id3 can be used as-is */ |
396 | { | 417 | write_id3_mul_tracks(&id3); |
397 | /* weird: we couldn't find the entry. This Should Never Happen (TM) */ | ||
398 | rb->splashf(0, "File/Dir not found: %s", file); | ||
399 | rb->action_userabort(TIMEOUT_BLOCK); | ||
400 | return PLUGIN_OK; | ||
401 | } | 418 | } |
402 | 419 | else | |
403 | /* get the info depending on its_a_dir */ | 420 | #endif |
404 | if(!(props_type == PROPS_DIR ? dir_properties(file, &stats) : file_properties(file))) | 421 | if (file[0] == '/') /* single track selected */ |
405 | { | 422 | { |
406 | /* something went wrong (to do: tell user what it was (nesting,...) */ | 423 | const char* file_name = rb->strrchr(file, '/') + 1; |
407 | rb->splash(0, ID2P(LANG_PROPERTIES_FAIL)); | 424 | int dirlen = (file_name - file); |
408 | rb->action_userabort(TIMEOUT_BLOCK); | 425 | |
409 | return PLUGIN_OK; | 426 | rb->strlcpy(str_dirname, file, dirlen + 1); |
427 | rb->snprintf(str_filename, sizeof str_filename, "%s", file+dirlen); | ||
428 | |||
429 | if(!determine_file_or_dir()) | ||
430 | { | ||
431 | /* weird: we couldn't find the entry. This Should Never Happen (TM) */ | ||
432 | rb->splashf(0, "File/Dir not found: %s", file); | ||
433 | rb->action_userabort(TIMEOUT_BLOCK); | ||
434 | return PLUGIN_OK; | ||
435 | } | ||
436 | |||
437 | /* get the info depending on its_a_dir */ | ||
438 | if(!(props_type == PROPS_DIR ? dir_properties(file, &stats) : file_properties(file))) | ||
439 | { | ||
440 | /* something went wrong (to do: tell user what it was (nesting,...) */ | ||
441 | rb->splash(0, ID2P(LANG_PROPERTIES_FAIL)); | ||
442 | rb->action_userabort(TIMEOUT_BLOCK); | ||
443 | return PLUGIN_OK; | ||
444 | } | ||
410 | } | 445 | } |
446 | else | ||
447 | return PLUGIN_ERROR; | ||
411 | 448 | ||
412 | FOR_NB_SCREENS(i) | 449 | FOR_NB_SCREENS(i) |
413 | rb->viewportmanager_theme_enable(i, true, NULL); | 450 | rb->viewportmanager_theme_enable(i, true, NULL); |
414 | 451 | ||
415 | bool usb = props_type == PROPS_ID3 ? rb->browse_id3(&id3, 0, 0, &tm) : | 452 | bool usb = props_type == PROPS_ID3 ? rb->browse_id3(&id3, 0, 0, &tm) : |
416 | browse_file_or_dir(&stats); | 453 | (props_type == PROPS_MUL_ID3 ? rb->browse_id3(&id3, 0, 0, NULL) : |
454 | browse_file_or_dir(&stats)); | ||
417 | 455 | ||
418 | FOR_NB_SCREENS(i) | 456 | FOR_NB_SCREENS(i) |
419 | rb->viewportmanager_theme_undo(i, false); | 457 | rb->viewportmanager_theme_undo(i, false); |
diff --git a/apps/tagtree.c b/apps/tagtree.c index 85359cac04..4248538f77 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c | |||
@@ -407,7 +407,7 @@ static int get_tag(int *tag) | |||
407 | 407 | ||
408 | static int get_clause(int *condition) | 408 | static int get_clause(int *condition) |
409 | { | 409 | { |
410 | /* one or two operator conditionals */ | 410 | /* one or two operator conditionals */ |
411 | #define OPS2VAL(op1, op2) ((int)op1 << 8 | (int)op2) | 411 | #define OPS2VAL(op1, op2) ((int)op1 << 8 | (int)op2) |
412 | #define CLAUSE(op1, op2, symbol) {OPS2VAL(op1, op2), symbol } | 412 | #define CLAUSE(op1, op2, symbol) {OPS2VAL(op1, op2), symbol } |
413 | 413 | ||
@@ -2160,6 +2160,27 @@ static bool insert_all_playlist(struct tree_context *c, | |||
2160 | return true; | 2160 | return true; |
2161 | } | 2161 | } |
2162 | 2162 | ||
2163 | static bool goto_allsubentries(int newtable) | ||
2164 | { | ||
2165 | int i = 0; | ||
2166 | while (i < 2 && (newtable == NAVIBROWSE || newtable == ALLSUBENTRIES)) | ||
2167 | { | ||
2168 | tagtree_enter(tc, false); | ||
2169 | tagtree_load(tc); | ||
2170 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | ||
2171 | i++; | ||
2172 | } | ||
2173 | return (newtable == PLAYTRACK); | ||
2174 | } | ||
2175 | |||
2176 | static void reset_tc_to_prev(int dirlevel, int selected_item) | ||
2177 | { | ||
2178 | while (tc->dirlevel > dirlevel) | ||
2179 | tagtree_exit(tc, false); | ||
2180 | tc->selected_item = selected_item; | ||
2181 | tagtree_load(tc); | ||
2182 | } | ||
2183 | |||
2163 | static bool tagtree_insert_selection(int position, bool queue, | 2184 | static bool tagtree_insert_selection(int position, bool queue, |
2164 | const char* playlist, bool new_playlist) | 2185 | const char* playlist, bool new_playlist) |
2165 | { | 2186 | { |
@@ -2167,6 +2188,7 @@ static bool tagtree_insert_selection(int position, bool queue, | |||
2167 | int dirlevel = tc->dirlevel; | 2188 | int dirlevel = tc->dirlevel; |
2168 | int selected_item = tc->selected_item; | 2189 | int selected_item = tc->selected_item; |
2169 | int newtable; | 2190 | int newtable; |
2191 | int ret; | ||
2170 | 2192 | ||
2171 | show_search_progress( | 2193 | show_search_progress( |
2172 | #ifdef HAVE_DISK_STORAGE | 2194 | #ifdef HAVE_DISK_STORAGE |
@@ -2176,71 +2198,101 @@ static bool tagtree_insert_selection(int position, bool queue, | |||
2176 | #endif | 2198 | #endif |
2177 | , 0); | 2199 | , 0); |
2178 | 2200 | ||
2179 | |||
2180 | /* We need to set the table to allsubentries. */ | ||
2181 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | 2201 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; |
2182 | 2202 | ||
2183 | /* Insert a single track? */ | 2203 | if (newtable == PLAYTRACK) /* Insert a single track? */ |
2184 | if (newtable == PLAYTRACK) | ||
2185 | { | 2204 | { |
2186 | if (tagtree_get_filename(tc, buf, sizeof buf) < 0) | 2205 | if (tagtree_get_filename(tc, buf, sizeof buf) < 0) |
2187 | { | ||
2188 | logf("tagtree_get_filename failed"); | ||
2189 | return false; | 2206 | return false; |
2190 | } | 2207 | |
2191 | playlist_insert_track(NULL, buf, position, queue, true); | 2208 | playlist_insert_track(NULL, buf, position, queue, true); |
2192 | 2209 | ||
2193 | return true; | 2210 | return true; |
2194 | } | 2211 | } |
2195 | 2212 | ||
2196 | if (newtable == NAVIBROWSE) | 2213 | ret = goto_allsubentries(newtable); |
2197 | { | 2214 | if (ret) |
2198 | tagtree_enter(tc, false); | ||
2199 | tagtree_load(tc); | ||
2200 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | ||
2201 | } | ||
2202 | else if (newtable != ALLSUBENTRIES) | ||
2203 | { | 2215 | { |
2204 | logf("unsupported table: %d", newtable); | 2216 | if (tc->filesindir <= 0) |
2205 | return false; | 2217 | splash(HZ, ID2P(LANG_END_PLAYLIST)); |
2218 | else if (!insert_all_playlist(tc, playlist, new_playlist, position, queue)) | ||
2219 | splash(HZ*2, ID2P(LANG_FAILED)); | ||
2206 | } | 2220 | } |
2207 | 2221 | ||
2208 | /* Now the current table should be allsubentries. */ | 2222 | reset_tc_to_prev(dirlevel, selected_item); |
2209 | if (newtable != PLAYTRACK) | 2223 | return ret; |
2210 | { | 2224 | } |
2211 | tagtree_enter(tc, false); | 2225 | |
2212 | tagtree_load(tc); | 2226 | /* Execute action_cb for all subentries of the current table's |
2213 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | 2227 | * selected item, handing over each entry's filename in the |
2228 | * callback function parameter. | ||
2229 | */ | ||
2230 | bool tagtree_subentries_do_action(bool (*action_cb)(const char *file_name)) | ||
2231 | { | ||
2232 | struct tagcache_search tcs; | ||
2233 | int i, n; | ||
2234 | unsigned long last_tick; | ||
2235 | char buf[MAX_PATH]; | ||
2236 | int ret = true; | ||
2237 | int dirlevel = tc->dirlevel; | ||
2238 | int selected_item = tc->selected_item; | ||
2239 | int newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | ||
2214 | 2240 | ||
2215 | /* And now the newtable should be playtrack. */ | 2241 | cpu_boost(true); |
2216 | if (newtable != PLAYTRACK) | 2242 | if (!goto_allsubentries(newtable)) |
2243 | ret = false; | ||
2244 | else if (tagcache_search(&tcs, tag_filename)) | ||
2245 | { | ||
2246 | last_tick = current_tick + HZ/2; | ||
2247 | splash_progress_set_delay(HZ / 2); /* wait 1/2 sec before progress */ | ||
2248 | n = tc->filesindir; | ||
2249 | for (i = 0; i < n; i++) | ||
2217 | { | 2250 | { |
2218 | logf("newtable: %d !!", newtable); | 2251 | splash_progress(i, n, "%s (%s)", str(LANG_WAIT), str(LANG_OFF_ABORT)); |
2219 | while (tc->dirlevel > dirlevel) | 2252 | if (TIME_AFTER(current_tick, last_tick + HZ/4)) |
2220 | tagtree_exit(tc, false); | 2253 | { |
2221 | tagtree_load(tc); | 2254 | if (action_userabort(TIMEOUT_NOBLOCK)) |
2222 | return false; | 2255 | break; |
2256 | last_tick = current_tick; | ||
2257 | } | ||
2258 | |||
2259 | if (!tagcache_retrieve(&tcs, tagtree_get_entry(tc, i)->extraseek, | ||
2260 | tcs.type, buf, sizeof buf) | ||
2261 | || !action_cb(buf)) | ||
2262 | { | ||
2263 | ret = false; | ||
2264 | break; | ||
2265 | } | ||
2266 | yield(); | ||
2223 | } | 2267 | } |
2224 | } | ||
2225 | 2268 | ||
2226 | if (tc->filesindir <= 0) | 2269 | tagcache_search_finish(&tcs); |
2227 | splash(HZ, ID2P(LANG_END_PLAYLIST)); | 2270 | } |
2228 | else | 2271 | else |
2229 | { | 2272 | { |
2230 | logf("insert_all_playlist"); | 2273 | splash(HZ, ID2P(LANG_TAGCACHE_BUSY)); |
2231 | if (!insert_all_playlist(tc, playlist, new_playlist, position, queue)) | 2274 | ret = false; |
2232 | splash(HZ*2, ID2P(LANG_FAILED)); | ||
2233 | } | 2275 | } |
2276 | reset_tc_to_prev(dirlevel, selected_item); | ||
2277 | cpu_boost(false); | ||
2278 | return ret; | ||
2279 | } | ||
2234 | 2280 | ||
2235 | /* Finally return the dirlevel to its original value. */ | 2281 | /* Try to return first subentry's filename for current selection |
2236 | while (tc->dirlevel > dirlevel) | 2282 | */ |
2237 | tagtree_exit(tc, false); | 2283 | bool tagtree_get_subentry_filename(char *buf, size_t bufsize) |
2238 | tc->selected_item = selected_item; | 2284 | { |
2239 | tagtree_load(tc); | 2285 | int ret = true; |
2286 | int dirlevel = tc->dirlevel; | ||
2287 | int selected_item = tc->selected_item; | ||
2288 | int newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | ||
2240 | 2289 | ||
2241 | return true; | 2290 | if (!goto_allsubentries(newtable) || tagtree_get_filename(tc, buf, bufsize) < 0) |
2242 | } | 2291 | ret = false; |
2243 | 2292 | ||
2293 | reset_tc_to_prev(dirlevel, selected_item); | ||
2294 | return ret; | ||
2295 | } | ||
2244 | 2296 | ||
2245 | bool tagtree_current_playlist_insert(int position, bool queue) | 2297 | bool tagtree_current_playlist_insert(int position, bool queue) |
2246 | { | 2298 | { |
diff --git a/apps/tagtree.h b/apps/tagtree.h index 6eaaf3dfac..39ab545bd0 100644 --- a/apps/tagtree.h +++ b/apps/tagtree.h | |||
@@ -45,6 +45,8 @@ char *tagtree_get_title(struct tree_context* c); | |||
45 | int tagtree_get_attr(struct tree_context* c); | 45 | int tagtree_get_attr(struct tree_context* c); |
46 | int tagtree_get_icon(struct tree_context* c); | 46 | int tagtree_get_icon(struct tree_context* c); |
47 | int tagtree_get_filename(struct tree_context* c, char *buf, int buflen); | 47 | int tagtree_get_filename(struct tree_context* c, char *buf, int buflen); |
48 | bool tagtree_get_subentry_filename(char *buf, size_t bufsize); | ||
49 | bool tagtree_subentries_do_action(bool (*action_cb)(const char *file_name)); | ||
48 | 50 | ||
49 | #endif | 51 | #endif |
50 | #endif | 52 | #endif |