diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-08-26 22:00:22 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-08-26 22:00:22 +0000 |
commit | 4f1a252aa168cea7f277f54d15594300d585627e (patch) | |
tree | 99a89fca1d5c89d04959fe8261f8c42a226f21d1 | |
parent | d844cd2a0204ee4db6da0f3e2b185a1b8ee9291e (diff) | |
download | rockbox-4f1a252aa168cea7f277f54d15594300d585627e.tar.gz rockbox-4f1a252aa168cea7f277f54d15594300d585627e.zip |
Add %sort and %limit variables for better control of the tag browser
list format. Show most played 100 tracks.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10763 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/tagnavi.config | 15 | ||||
-rw-r--r-- | apps/tagtree.c | 105 |
2 files changed, 90 insertions, 30 deletions
diff --git a/apps/tagnavi.config b/apps/tagnavi.config index ea12409396..55418718bf 100644 --- a/apps/tagnavi.config +++ b/apps/tagnavi.config | |||
@@ -1,16 +1,15 @@ | |||
1 | "Artists" artist : album : title = "%02d. %s" tracknum title | 1 | "Artist" artist : album : title = "%02d. %s" tracknum title |
2 | "Albums" album : title = "%02d. %s" tracknum title | 2 | "Album" album : title = "%02d. %s" tracknum title |
3 | "Genres" genre : artist : album : title = "%02d. %s" tracknum title | 3 | "Genre" genre : artist : album : title = "%02d. %s" tracknum title |
4 | "Composers" composer : album : title = "%02d. %s" tracknum title | 4 | "Composer" composer : album : title = "%02d. %s" tracknum title |
5 | "Tracks" title | 5 | "Track" title |
6 | "Year" year ? year > "1000" & year < "2008" : artist : album : title = "%02d. %s" tracknum title | 6 | "Year" year ? year > "1000" & year < "2008" : artist : album : title = "%02d. %s" tracknum title |
7 | "Search by artist" artist ? artist ~ "" : album : title = "%02d. %s" tracknum title | 7 | "Search by artist" artist ? artist ~ "" : album : title = "%02d. %s" tracknum title |
8 | "Search by album" album ? album ~ "" : title = "%02d. %s" tracknum title | 8 | "Search by album" album ? album ~ "" : title = "%02d. %s" tracknum title |
9 | "Search by title" title ? title ~ "" | 9 | "Search by title" title ? title ~ "" |
10 | "Search by filename" filename ? filename ~ "" | 10 | "Search by filename" filename ? filename ~ "" |
11 | "Search by year" artist ? year = "" : album : title = "%02d. %s" tracknum title | ||
12 | "Search by score" title = "(%3d) %s" autoscore title ? autoscore > "" | 11 | "Search by score" title = "(%3d) %s" autoscore title ? autoscore > "" |
13 | "Most played tracks" title = "(%2d) %s" playcount title ? playcount > "1" | 12 | "Most played tracks" title = "(%3d) %s" playcount title %sort = "inverse" %limit = "100" ? playcount > "0" |
14 | "Never played tracks" artist ? playcount == "0" : album : title = "%02d. %s" tracknum title | 13 | "Never played tracks" artist ? playcount == "0" : album : title = "%02d. %s" tracknum title |
15 | "Best tracks" artist ? playcount > "1" & autoscore > "85" : album : title = "%02d. %s (%3d)" tracknum title autoscore | 14 | "Best tracks" artist ? playcount > "1" & autoscore > "85" : album : title = "%02d. %s (%3d)" tracknum title autoscore |
16 | "List played tracks" title = "(%3d/%d) %s" autoscore playcount title ? playcount > "0" | 15 | "List played tracks" title = "(%3d/%d) %s" autoscore playcount title ? playcount > "0" |
diff --git a/apps/tagtree.c b/apps/tagtree.c index 6602e9ac24..08e6eb59b0 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c | |||
@@ -49,26 +49,40 @@ static int tagtree_play_folder(struct tree_context* c); | |||
49 | 49 | ||
50 | static char searchstring[32]; | 50 | static char searchstring[32]; |
51 | 51 | ||
52 | enum variables { | ||
53 | var_sorttype = 100, | ||
54 | var_limit | ||
55 | }; | ||
56 | |||
52 | /* Capacity 10 000 entries (for example 10k different artists) */ | 57 | /* Capacity 10 000 entries (for example 10k different artists) */ |
53 | #define UNIQBUF_SIZE (64*1024) | 58 | #define UNIQBUF_SIZE (64*1024) |
54 | static long *uniqbuf; | 59 | static long *uniqbuf; |
55 | 60 | ||
56 | #define MAX_TAGS 5 | 61 | #define MAX_TAGS 5 |
57 | 62 | ||
63 | static struct tagcache_search tcs, tcs2; | ||
64 | static bool sort_inverse; | ||
65 | |||
58 | /* | 66 | /* |
59 | * "%3d. %s" autoscore title | 67 | * "%3d. %s" autoscore title %sort = "inverse" %limit = "100" |
60 | * | 68 | * |
61 | * valid = true | 69 | * valid = true |
62 | * formatstr = "%-3d. %s" | 70 | * formatstr = "%-3d. %s" |
63 | * tags[0] = tag_autoscore | 71 | * tags[0] = tag_autoscore |
64 | * tags[1] = tag_title | 72 | * tags[1] = tag_title |
65 | * tag_count = 2 | 73 | * tag_count = 2 |
74 | * | ||
75 | * limit = 100 | ||
76 | * sort_inverse = true | ||
66 | */ | 77 | */ |
67 | struct display_format { | 78 | struct display_format { |
68 | bool valid; | 79 | bool valid; |
69 | char formatstr[64]; | 80 | char formatstr[64]; |
70 | int tags[MAX_TAGS]; | 81 | int tags[MAX_TAGS]; |
71 | int tag_count; | 82 | int tag_count; |
83 | |||
84 | int limit; | ||
85 | bool sort_inverse; | ||
72 | }; | 86 | }; |
73 | 87 | ||
74 | struct search_instruction { | 88 | struct search_instruction { |
@@ -127,7 +141,7 @@ static int get_tag(int *tag) | |||
127 | while (*strp == ' ' && *strp != '\0') | 141 | while (*strp == ' ' && *strp != '\0') |
128 | strp++; | 142 | strp++; |
129 | 143 | ||
130 | if (*strp == '\0') | 144 | if (*strp == '\0' || *strp == '?' || *strp == ':') |
131 | return 0; | 145 | return 0; |
132 | 146 | ||
133 | for (i = 0; i < (int)sizeof(buf)-1; i++) | 147 | for (i = 0; i < (int)sizeof(buf)-1; i++) |
@@ -151,6 +165,8 @@ static int get_tag(int *tag) | |||
151 | MATCH(tag, buf, "year", tag_year); | 165 | MATCH(tag, buf, "year", tag_year); |
152 | MATCH(tag, buf, "playcount", tag_playcount); | 166 | MATCH(tag, buf, "playcount", tag_playcount); |
153 | MATCH(tag, buf, "autoscore", tag_virt_autoscore); | 167 | MATCH(tag, buf, "autoscore", tag_virt_autoscore); |
168 | MATCH(tag, buf, "%sort", var_sorttype); | ||
169 | MATCH(tag, buf, "%limit", var_limit); | ||
154 | 170 | ||
155 | logf("NO MATCH: %s\n", buf); | 171 | logf("NO MATCH: %s\n", buf); |
156 | if (buf[0] == '?') | 172 | if (buf[0] == '?') |
@@ -240,9 +256,27 @@ static bool add_clause(struct search_instruction *inst, | |||
240 | return true; | 256 | return true; |
241 | } | 257 | } |
242 | 258 | ||
259 | static bool read_variable(char *buf, int size) | ||
260 | { | ||
261 | int condition; | ||
262 | |||
263 | if (!get_clause(&condition)) | ||
264 | return false; | ||
265 | |||
266 | if (condition != clause_is) | ||
267 | return false; | ||
268 | |||
269 | if (get_token_str(buf, size) < 0) | ||
270 | return false; | ||
271 | |||
272 | return true; | ||
273 | } | ||
274 | |||
275 | /* "%3d. %s" autoscore title %sort = "inverse" %limit = "100" */ | ||
243 | static int get_format_str(struct display_format *fmt) | 276 | static int get_format_str(struct display_format *fmt) |
244 | { | 277 | { |
245 | int ret; | 278 | int ret; |
279 | char buf[32]; | ||
246 | 280 | ||
247 | memset(fmt, 0, sizeof(struct display_format)); | 281 | memset(fmt, 0, sizeof(struct display_format)); |
248 | 282 | ||
@@ -258,7 +292,23 @@ static int get_format_str(struct display_format *fmt) | |||
258 | if (ret == 0) | 292 | if (ret == 0) |
259 | break; | 293 | break; |
260 | 294 | ||
261 | fmt->tag_count++; | 295 | switch (fmt->tags[fmt->tag_count]) { |
296 | case var_sorttype: | ||
297 | if (!read_variable(buf, sizeof buf)) | ||
298 | return -12; | ||
299 | if (!strcasecmp("inverse", buf)) | ||
300 | fmt->sort_inverse = true; | ||
301 | break; | ||
302 | |||
303 | case var_limit: | ||
304 | if (!read_variable(buf, sizeof buf)) | ||
305 | return -13; | ||
306 | fmt->limit = atoi(buf); | ||
307 | break; | ||
308 | |||
309 | default: | ||
310 | fmt->tag_count++; | ||
311 | } | ||
262 | } | 312 | } |
263 | 313 | ||
264 | fmt->valid = true; | 314 | fmt->valid = true; |
@@ -268,8 +318,6 @@ static int get_format_str(struct display_format *fmt) | |||
268 | 318 | ||
269 | static int get_condition(struct search_instruction *inst) | 319 | static int get_condition(struct search_instruction *inst) |
270 | { | 320 | { |
271 | struct display_format format; | ||
272 | struct display_format *fmt = NULL; | ||
273 | int tag; | 321 | int tag; |
274 | int condition; | 322 | int condition; |
275 | char buf[32]; | 323 | char buf[32]; |
@@ -277,13 +325,12 @@ static int get_condition(struct search_instruction *inst) | |||
277 | switch (*strp) | 325 | switch (*strp) |
278 | { | 326 | { |
279 | case '=': | 327 | case '=': |
280 | if (get_format_str(&format) < 0) | 328 | if (get_format_str(&inst->format[inst->tagorder_count]) < 0) |
281 | { | 329 | { |
282 | logf("get_format_str() parser failed!"); | 330 | logf("get_format_str() parser failed!"); |
283 | return -4; | 331 | return -4; |
284 | } | 332 | } |
285 | fmt = &format; | 333 | return 1; |
286 | break; | ||
287 | 334 | ||
288 | case '?': | 335 | case '?': |
289 | case ' ': | 336 | case ' ': |
@@ -296,14 +343,6 @@ static int get_condition(struct search_instruction *inst) | |||
296 | return 0; | 343 | return 0; |
297 | } | 344 | } |
298 | 345 | ||
299 | if (fmt) | ||
300 | { | ||
301 | memcpy(&inst->format[inst->tagorder_count], fmt, | ||
302 | sizeof(struct display_format)); | ||
303 | } | ||
304 | else | ||
305 | inst->format[inst->tagorder_count].valid = false; | ||
306 | |||
307 | if (get_tag(&tag) <= 0) | 346 | if (get_tag(&tag) <= 0) |
308 | return -1; | 347 | return -1; |
309 | 348 | ||
@@ -362,14 +401,14 @@ static bool parse_search(struct search_instruction *inst, const char *str) | |||
362 | return true; | 401 | return true; |
363 | } | 402 | } |
364 | 403 | ||
365 | |||
366 | static struct tagcache_search tcs, tcs2; | ||
367 | |||
368 | static int compare(const void *p1, const void *p2) | 404 | static int compare(const void *p1, const void *p2) |
369 | { | 405 | { |
370 | struct tagentry *e1 = (struct tagentry *)p1; | 406 | struct tagentry *e1 = (struct tagentry *)p1; |
371 | struct tagentry *e2 = (struct tagentry *)p2; | 407 | struct tagentry *e2 = (struct tagentry *)p2; |
372 | 408 | ||
409 | if (sort_inverse) | ||
410 | return strncasecmp(e2->name, e1->name, MAX_PATH); | ||
411 | |||
373 | return strncasecmp(e1->name, e2->name, MAX_PATH); | 412 | return strncasecmp(e1->name, e2->name, MAX_PATH); |
374 | } | 413 | } |
375 | 414 | ||
@@ -558,6 +597,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
558 | int offset, bool init) | 597 | int offset, bool init) |
559 | { | 598 | { |
560 | struct tagentry *dptr = (struct tagentry *)c->dircache; | 599 | struct tagentry *dptr = (struct tagentry *)c->dircache; |
600 | struct display_format *fmt; | ||
561 | int i; | 601 | int i; |
562 | int namebufused = 0; | 602 | int namebufused = 0; |
563 | int total_count = 0; | 603 | int total_count = 0; |
@@ -565,6 +605,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
565 | int level = c->currextra; | 605 | int level = c->currextra; |
566 | int tag; | 606 | int tag; |
567 | bool sort = false; | 607 | bool sort = false; |
608 | int sort_limit = 0; | ||
568 | 609 | ||
569 | if (init | 610 | if (init |
570 | #ifdef HAVE_TC_RAMCACHE | 611 | #ifdef HAVE_TC_RAMCACHE |
@@ -625,6 +666,17 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
625 | current_offset = offset; | 666 | current_offset = offset; |
626 | current_entry_count = 0; | 667 | current_entry_count = 0; |
627 | c->dirfull = false; | 668 | c->dirfull = false; |
669 | fmt = &csi->format[level]; | ||
670 | if (fmt->valid) | ||
671 | { | ||
672 | sort_inverse = fmt->sort_inverse; | ||
673 | sort_limit = fmt->limit; | ||
674 | } | ||
675 | else | ||
676 | { | ||
677 | sort_inverse = false; | ||
678 | sort_limit = 0; | ||
679 | } | ||
628 | 680 | ||
629 | if (tag != tag_title && tag != tag_filename) | 681 | if (tag != tag_title && tag != tag_filename) |
630 | { | 682 | { |
@@ -642,8 +694,6 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
642 | 694 | ||
643 | while (tagcache_get_next(tcs)) | 695 | while (tagcache_get_next(tcs)) |
644 | { | 696 | { |
645 | struct display_format *fmt = &csi->format[level]; | ||
646 | |||
647 | if (total_count++ < offset) | 697 | if (total_count++ < offset) |
648 | continue; | 698 | continue; |
649 | 699 | ||
@@ -664,7 +714,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
664 | bool read_format = false; | 714 | bool read_format = false; |
665 | int fmtbuf_pos = 0; | 715 | int fmtbuf_pos = 0; |
666 | int parpos = 0; | 716 | int parpos = 0; |
667 | 717 | ||
668 | memset(buf, 0, sizeof buf); | 718 | memset(buf, 0, sizeof buf); |
669 | for (i = 0; fmt->formatstr[i] != '\0'; i++) | 719 | for (i = 0; fmt->formatstr[i] != '\0'; i++) |
670 | { | 720 | { |
@@ -784,6 +834,17 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
784 | } | 834 | } |
785 | 835 | ||
786 | tagcache_search_finish(tcs); | 836 | tagcache_search_finish(tcs); |
837 | |||
838 | if (!sort && (sort_inverse || sort_limit)) | ||
839 | { | ||
840 | gui_syncsplash(HZ*4, true, str(LANG_INCREASE_DIR_BUFFER), total_count); | ||
841 | logf("Too small dir buffer"); | ||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | if (sort_limit) | ||
846 | total_count = MIN(total_count, sort_limit); | ||
847 | |||
787 | return total_count; | 848 | return total_count; |
788 | } | 849 | } |
789 | 850 | ||