diff options
Diffstat (limited to 'apps/tagtree.c')
-rw-r--r-- | apps/tagtree.c | 138 |
1 files changed, 95 insertions, 43 deletions
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 | { |