summaryrefslogtreecommitdiff
path: root/apps/tagtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tagtree.c')
-rw-r--r--apps/tagtree.c94
1 files changed, 84 insertions, 10 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 83bfb4e36d..4983231663 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -112,6 +112,7 @@ enum variables {
112 var_include, 112 var_include,
113 var_rootmenu, 113 var_rootmenu,
114 var_format, 114 var_format,
115 menu_byfirstletter,
115 menu_next, 116 menu_next,
116 menu_load, 117 menu_load,
117 menu_reload, 118 menu_reload,
@@ -173,11 +174,12 @@ struct display_format {
173static struct display_format *formats[TAGMENU_MAX_FMTS]; 174static struct display_format *formats[TAGMENU_MAX_FMTS];
174static int format_count; 175static int format_count;
175 176
177#define MENUENTRY_MAX_NAME 64
176struct menu_entry { 178struct menu_entry {
177 char name[64]; 179 char name[MENUENTRY_MAX_NAME];
178 int type; 180 int type;
179 struct search_instruction { 181 struct search_instruction {
180 char name[64]; 182 char name[MENUENTRY_MAX_NAME];
181 int tagorder[MAX_TAGS]; 183 int tagorder[MAX_TAGS];
182 int tagorder_count; 184 int tagorder_count;
183 struct tagcache_search_clause *clause[MAX_TAGS][TAGCACHE_MAX_CLAUSES]; 185 struct tagcache_search_clause *clause[MAX_TAGS][TAGCACHE_MAX_CLAUSES];
@@ -381,6 +383,7 @@ static int get_tag(int *tag)
381 TAG_MATCH("comment", tag_comment), 383 TAG_MATCH("comment", tag_comment),
382 TAG_MATCH("discnum", tag_discnumber), 384 TAG_MATCH("discnum", tag_discnumber),
383 TAG_MATCH("%format", var_format), 385 TAG_MATCH("%format", var_format),
386 TAG_MATCH("%byfirstletter", menu_byfirstletter),
384 TAG_MATCH("%reload", menu_reload), 387 TAG_MATCH("%reload", menu_reload),
385 388
386 TAG_MATCH("filename", tag_filename), 389 TAG_MATCH("filename", tag_filename),
@@ -1058,6 +1061,63 @@ int tagtree_import(void)
1058 1061
1059static bool parse_menu(const char *filename); 1062static bool parse_menu(const char *filename);
1060 1063
1064static bool alloc_menu_item(void)
1065{
1066 /* Allocate */
1067 if (menu->items[menu->itemcount] == NULL)
1068 menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry));
1069 if (!menu->items[menu->itemcount])
1070 {
1071 logf("tagtree failed to allocate %s", "menu items");
1072 return false;
1073 }
1074 return true;
1075}
1076
1077static void firstletter_parse_buf(char *buf)
1078{
1079 core_pin(tagtree_handle);
1080 if (parse_search(menu->items[menu->itemcount], buf))
1081 {
1082 menu->items[menu->itemcount]->type = menu_byfirstletter;
1083 menu->itemcount++;
1084 }
1085 core_unpin(tagtree_handle);;
1086}
1087
1088static void build_firstletter_menu(char *buf, size_t bufsz)
1089{
1090 const char *subitem = buf;
1091 size_t l = strlen(buf) + 1;
1092 buf+=l;
1093 bufsz-=l;
1094
1095 const char *showalbum = "";
1096 const char * const fmt ="\"%s\" -> %s ? %s %c \"%c\" -> %s title = \"fmt_title\"";
1097 if (!alloc_menu_item())
1098 return;
1099
1100 if (strcasestr(subitem, "artist") != NULL)
1101 showalbum = "album ->"; /* album subitem for canonicalartist */
1102
1103 /* Numeric ex: "Numeric" -> album ? album < "A" -> title = "fmt_title" */
1104 snprintf(buf, bufsz, fmt,
1105 str(LANG_DISPLAY_NUMERIC), subitem, subitem,'<', 'A', showalbum);
1106
1107 firstletter_parse_buf(buf);
1108
1109 for (int i = 0; i < 26; i++)
1110 {
1111 if (!alloc_menu_item())
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 */
1116 /* ex: "A" -> title ? title ^ "A" -> title = "fmt_title" */
1117 firstletter_parse_buf(buf);
1118 }
1119}
1120
1061static int parse_line(int n, char *buf, void *parameters) 1121static int parse_line(int n, char *buf, void *parameters)
1062{ 1122{
1063 char data[256]; 1123 char data[256];
@@ -1127,7 +1187,7 @@ static int parse_line(int n, char *buf, void *parameters)
1127 logf("Load menu fail: %s", data); 1187 logf("Load menu fail: %s", data);
1128 } 1188 }
1129 break; 1189 break;
1130 1190 case menu_byfirstletter: /* Fallthrough */
1131 case var_menu_start: 1191 case var_menu_start:
1132 if (menu_count >= TAGMENU_MAX_MENUS) 1192 if (menu_count >= TAGMENU_MAX_MENUS)
1133 { 1193 {
@@ -1169,6 +1229,19 @@ static int parse_line(int n, char *buf, void *parameters)
1169 return 0; 1229 return 0;
1170 } 1230 }
1171 logf("menu: %s", menu->title); 1231 logf("menu: %s", menu->title);
1232
1233 if (variable == menu_byfirstletter)
1234 {
1235 if (get_token_str(data, sizeof(data)) < 0)
1236 {
1237 logf("%%firstletter_menu has no subitem"); /*artist,album*/
1238 return 0;
1239 }
1240 logf("A-Z Menu subitem: %s", data);
1241 read_menu = false;
1242 build_firstletter_menu(data, sizeof(data));
1243 break;
1244 }
1172 read_menu = true; 1245 read_menu = true;
1173 break; 1246 break;
1174 1247
@@ -1202,14 +1275,8 @@ static int parse_line(int n, char *buf, void *parameters)
1202 return 0; 1275 return 0;
1203 } 1276 }
1204 1277
1205 /* Allocate */ 1278 if (!alloc_menu_item())
1206 if (menu->items[menu->itemcount] == NULL)
1207 menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry));
1208 if (!menu->items[menu->itemcount])
1209 {
1210 logf("tagtree failed to allocate %s", "menu items");
1211 return -2; 1279 return -2;
1212 }
1213 core_pin(tagtree_handle); 1280 core_pin(tagtree_handle);
1214 if (parse_search(menu->items[menu->itemcount], buf)) 1281 if (parse_search(menu->items[menu->itemcount], buf))
1215 menu->itemcount++; 1282 menu->itemcount++;
@@ -1449,6 +1516,7 @@ static void tcs_get_basename(struct tagcache_search *tcs, bool is_basename)
1449 1516
1450static int retrieve_entries(struct tree_context *c, int offset, bool init) 1517static int retrieve_entries(struct tree_context *c, int offset, bool init)
1451{ 1518{
1519 logf( "%s", __func__);
1452 char tcs_buf[TAGCACHE_BUFSZ]; 1520 char tcs_buf[TAGCACHE_BUFSZ];
1453 const long tcs_bufsz = sizeof(tcs_buf); 1521 const long tcs_bufsz = sizeof(tcs_buf);
1454 struct tagcache_search tcs; 1522 struct tagcache_search tcs;
@@ -1818,6 +1886,12 @@ static int load_root(struct tree_context *c)
1818 dptr->extraseek = i; 1886 dptr->extraseek = i;
1819 dptr->customaction = ONPLAY_CUSTOMACTION_SHUFFLE_SONGS; 1887 dptr->customaction = ONPLAY_CUSTOMACTION_SHUFFLE_SONGS;
1820 break; 1888 break;
1889
1890 case menu_byfirstletter:
1891 dptr->newtable = TABLE_NAVIBROWSE;
1892 dptr->extraseek = i;
1893 dptr->customaction = ONPLAY_CUSTOMACTION_FIRSTLETTER;
1894 break;
1821 } 1895 }
1822 1896
1823 dptr++; 1897 dptr++;