diff options
-rw-r--r-- | apps/tagtree.c | 77 |
1 files changed, 35 insertions, 42 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c index 4983231663..60f8a795e3 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c | |||
@@ -191,19 +191,12 @@ struct menu_entry { | |||
191 | }; | 191 | }; |
192 | 192 | ||
193 | struct menu_root { | 193 | struct menu_root { |
194 | char title[64]; | 194 | char title[MENUENTRY_MAX_NAME]; |
195 | char id[MAX_MENU_ID_SIZE]; | 195 | char id[MAX_MENU_ID_SIZE]; |
196 | int itemcount; | 196 | int itemcount; |
197 | struct menu_entry *items[TAGMENU_MAX_ITEMS]; | 197 | struct menu_entry *items[TAGMENU_MAX_ITEMS]; |
198 | }; | 198 | }; |
199 | 199 | ||
200 | struct match | ||
201 | { | ||
202 | const char* str; | ||
203 | uint16_t len; | ||
204 | uint16_t symbol; | ||
205 | }; | ||
206 | |||
207 | /* Statusbar text of the current view. */ | 200 | /* Statusbar text of the current view. */ |
208 | static char current_title[MAX_TAGS][128]; | 201 | static char current_title[MAX_TAGS][128]; |
209 | 202 | ||
@@ -355,12 +348,13 @@ static int get_token_str(char *buf, int size) | |||
355 | static int get_tag(int *tag) | 348 | static int get_tag(int *tag) |
356 | { | 349 | { |
357 | #define TAG_MATCH(str, tag) {str, sizeof(str) - 1, tag} | 350 | #define TAG_MATCH(str, tag) {str, sizeof(str) - 1, tag} |
351 | struct match {const char* str; uint16_t len; uint16_t symbol;}; | ||
358 | static const struct match get_tag_match[] = | 352 | static const struct match get_tag_match[] = |
359 | { | 353 | { |
360 | TAG_MATCH("Lm", tag_virt_length_min), | 354 | TAG_MATCH("lm", tag_virt_length_min), |
361 | TAG_MATCH("Ls", tag_virt_length_sec), | 355 | TAG_MATCH("ls", tag_virt_length_sec), |
362 | TAG_MATCH("Pm", tag_virt_playtime_min), | 356 | TAG_MATCH("pm", tag_virt_playtime_min), |
363 | TAG_MATCH("Ps", tag_virt_playtime_sec), | 357 | TAG_MATCH("ps", tag_virt_playtime_sec), |
364 | TAG_MATCH("->", menu_next), | 358 | TAG_MATCH("->", menu_next), |
365 | TAG_MATCH("~>", menu_shuffle_songs), | 359 | TAG_MATCH("~>", menu_shuffle_songs), |
366 | 360 | ||
@@ -383,7 +377,6 @@ static int get_tag(int *tag) | |||
383 | TAG_MATCH("comment", tag_comment), | 377 | TAG_MATCH("comment", tag_comment), |
384 | TAG_MATCH("discnum", tag_discnumber), | 378 | TAG_MATCH("discnum", tag_discnumber), |
385 | TAG_MATCH("%format", var_format), | 379 | TAG_MATCH("%format", var_format), |
386 | TAG_MATCH("%byfirstletter", menu_byfirstletter), | ||
387 | TAG_MATCH("%reload", menu_reload), | 380 | TAG_MATCH("%reload", menu_reload), |
388 | 381 | ||
389 | TAG_MATCH("filename", tag_filename), | 382 | TAG_MATCH("filename", tag_filename), |
@@ -407,13 +400,15 @@ static int get_tag(int *tag) | |||
407 | TAG_MATCH("lastelapsed", tag_lastelapsed), | 400 | TAG_MATCH("lastelapsed", tag_lastelapsed), |
408 | TAG_MATCH("%menu_start", var_menu_start), | 401 | TAG_MATCH("%menu_start", var_menu_start), |
409 | 402 | ||
403 | TAG_MATCH("%byfirstletter", menu_byfirstletter), | ||
410 | TAG_MATCH("canonicalartist", tag_virt_canonicalartist), | 404 | TAG_MATCH("canonicalartist", tag_virt_canonicalartist), |
405 | |||
411 | TAG_MATCH("", 0) /* sentinel */ | 406 | TAG_MATCH("", 0) /* sentinel */ |
412 | }; | 407 | }; |
413 | #undef TAG_MATCH | 408 | #undef TAG_MATCH |
414 | const size_t max_cmd_sz = 32; /* needs to be >= to len of longest tagstr */ | 409 | const size_t max_cmd_sz = 32; /* needs to be >= to len of longest tagstr */ |
415 | const char *tagstr; | 410 | const char *tagstr; |
416 | unsigned int tagstr_len; | 411 | uint16_t tagstr_len; |
417 | const struct match *match; | 412 | const struct match *match; |
418 | 413 | ||
419 | /* Find the start. */ | 414 | /* Find the start. */ |
@@ -1059,10 +1054,11 @@ int tagtree_import(void) | |||
1059 | return 0; | 1054 | return 0; |
1060 | } | 1055 | } |
1061 | 1056 | ||
1062 | static bool parse_menu(const char *filename); | 1057 | static bool alloc_menu_parse_buf(char *buf, int type) |
1063 | |||
1064 | static bool alloc_menu_item(void) | ||
1065 | { | 1058 | { |
1059 | /* allocate a new menu item (if needed) initialize it with data parsed | ||
1060 | from buf Note: allows setting menu type, type ignored when < 0 | ||
1061 | */ | ||
1066 | /* Allocate */ | 1062 | /* Allocate */ |
1067 | if (menu->items[menu->itemcount] == NULL) | 1063 | if (menu->items[menu->itemcount] == NULL) |
1068 | menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry)); | 1064 | menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry)); |
@@ -1071,18 +1067,17 @@ static bool alloc_menu_item(void) | |||
1071 | logf("tagtree failed to allocate %s", "menu items"); | 1067 | logf("tagtree failed to allocate %s", "menu items"); |
1072 | return false; | 1068 | return false; |
1073 | } | 1069 | } |
1074 | return true; | ||
1075 | } | ||
1076 | 1070 | ||
1077 | static void firstletter_parse_buf(char *buf) | 1071 | /* Initialize */ |
1078 | { | ||
1079 | core_pin(tagtree_handle); | 1072 | core_pin(tagtree_handle); |
1080 | if (parse_search(menu->items[menu->itemcount], buf)) | 1073 | if (parse_search(menu->items[menu->itemcount], buf)) |
1081 | { | 1074 | { |
1082 | menu->items[menu->itemcount]->type = menu_byfirstletter; | 1075 | if (type >= 0) |
1076 | menu->items[menu->itemcount]->type = type; | ||
1083 | menu->itemcount++; | 1077 | menu->itemcount++; |
1084 | } | 1078 | } |
1085 | core_unpin(tagtree_handle);; | 1079 | core_unpin(tagtree_handle); |
1080 | return true; | ||
1086 | } | 1081 | } |
1087 | 1082 | ||
1088 | static void build_firstletter_menu(char *buf, size_t bufsz) | 1083 | static void build_firstletter_menu(char *buf, size_t bufsz) |
@@ -1092,32 +1087,32 @@ static void build_firstletter_menu(char *buf, size_t bufsz) | |||
1092 | buf+=l; | 1087 | buf+=l; |
1093 | bufsz-=l; | 1088 | bufsz-=l; |
1094 | 1089 | ||
1095 | const char *showalbum = ""; | 1090 | const char * const fmt ="\"%s\"-> %s ? %s %c\"%c\"-> %s =\"fmt_title\""; |
1096 | const char * const fmt ="\"%s\" -> %s ? %s %c \"%c\" -> %s title = \"fmt_title\""; | 1091 | const char * const showsub = /* album subitem for canonicalartist */ |
1097 | if (!alloc_menu_item()) | 1092 | ((strcasestr(subitem, "artist") == NULL) ? "title" : "album -> title"); |
1098 | return; | ||
1099 | |||
1100 | if (strcasestr(subitem, "artist") != NULL) | ||
1101 | showalbum = "album ->"; /* album subitem for canonicalartist */ | ||
1102 | 1093 | ||
1103 | /* Numeric ex: "Numeric" -> album ? album < "A" -> title = "fmt_title" */ | 1094 | /* Numeric ex: "Numeric" -> album ? album < "A" -> title = "fmt_title" */ |
1104 | snprintf(buf, bufsz, fmt, | 1095 | snprintf(buf, bufsz, fmt, |
1105 | str(LANG_DISPLAY_NUMERIC), subitem, subitem,'<', 'A', showalbum); | 1096 | str(LANG_DISPLAY_NUMERIC), subitem, subitem,'<', 'A', showsub); |
1106 | 1097 | ||
1107 | firstletter_parse_buf(buf); | 1098 | if (!alloc_menu_parse_buf(buf, menu_byfirstletter)) |
1099 | { | ||
1100 | return; | ||
1101 | } | ||
1108 | 1102 | ||
1109 | for (int i = 0; i < 26; i++) | 1103 | for (int i = 0; i < 26; i++) |
1110 | { | 1104 | { |
1111 | if (!alloc_menu_item()) | 1105 | snprintf(buf, bufsz, fmt, "#", subitem, subitem,'^', 'A' + i, showsub); |
1112 | return; | ||
1113 | |||
1114 | snprintf(buf, bufsz, fmt, "#", subitem, subitem,'^', 'A' + i, showalbum); | ||
1115 | buf[1] = 'A' + i; /* overwrite the placeholder # with the current letter */ | 1106 | buf[1] = 'A' + i; /* overwrite the placeholder # with the current letter */ |
1116 | /* ex: "A" -> title ? title ^ "A" -> title = "fmt_title" */ | 1107 | /* ex: "A" -> title ? title ^ "A" -> title = "fmt_title" */ |
1117 | firstletter_parse_buf(buf); | 1108 | if (!alloc_menu_parse_buf(buf, menu_byfirstletter)) |
1109 | { | ||
1110 | return; | ||
1111 | } | ||
1118 | } | 1112 | } |
1119 | } | 1113 | } |
1120 | 1114 | ||
1115 | static bool parse_menu(const char *filename); | ||
1121 | static int parse_line(int n, char *buf, void *parameters) | 1116 | static int parse_line(int n, char *buf, void *parameters) |
1122 | { | 1117 | { |
1123 | char data[256]; | 1118 | char data[256]; |
@@ -1275,12 +1270,10 @@ static int parse_line(int n, char *buf, void *parameters) | |||
1275 | return 0; | 1270 | return 0; |
1276 | } | 1271 | } |
1277 | 1272 | ||
1278 | if (!alloc_menu_item()) | 1273 | if (!alloc_menu_parse_buf(buf, -1)) |
1274 | { | ||
1279 | return -2; | 1275 | return -2; |
1280 | core_pin(tagtree_handle); | 1276 | } |
1281 | if (parse_search(menu->items[menu->itemcount], buf)) | ||
1282 | menu->itemcount++; | ||
1283 | core_unpin(tagtree_handle); | ||
1284 | 1277 | ||
1285 | return 0; | 1278 | return 0; |
1286 | } | 1279 | } |