summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2024-09-23 03:23:36 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2024-11-02 17:27:22 -0400
commit06986d27f06528c8eb9f672a8f4913d3e3e7a307 (patch)
treeeba4e37fbc0685621702b7ab04ad69f6616253b0
parent67ad6589fbcd65281364dba51aabefdc55990b2d (diff)
downloadrockbox-06986d27f0.tar.gz
rockbox-06986d27f0.zip
Generate A-Z menus in the tagtree
this adds a new command %byfirstletter %byfirstletter "custom_track" "Track A to Z" "title" ^ command ^menu name ^menu title ^subitem need a better name for subitem btw.. this patch also allows us to tell when we are in the BFL menu by checking customaction == ONPLAY_CUSTOMACTION_FIRSTLETTER we then enable spelling of the letters in the menu it spells Numeric too but that shouldn't matter with the upcoming voice patch Change-Id: I59815f697a4ef84a8cb540783b620d15f6670e00
-rw-r--r--apps/onplay.h1
-rw-r--r--apps/tagnavi.config93
-rw-r--r--apps/tagtree.c94
-rw-r--r--apps/tree.c4
4 files changed, 93 insertions, 99 deletions
diff --git a/apps/onplay.h b/apps/onplay.h
index 03861e9cf6..26b1247f7b 100644
--- a/apps/onplay.h
+++ b/apps/onplay.h
@@ -28,6 +28,7 @@
enum {
ONPLAY_NO_CUSTOMACTION,
ONPLAY_CUSTOMACTION_SHUFFLE_SONGS,
+ ONPLAY_CUSTOMACTION_FIRSTLETTER,
};
int onplay(char* file, int attr, int from_context, bool hotkey, int customaction);
diff --git a/apps/tagnavi.config b/apps/tagnavi.config
index b599f9577c..6335610253 100644
--- a/apps/tagnavi.config
+++ b/apps/tagnavi.config
@@ -30,96 +30,13 @@
#
# Define the A to Z Artist sub menu
-%menu_start "custom_artist" "Artist A to Z"
-"Numeric" -> canonicalartist ? canonicalartist < "A" -> album -> title = "fmt_title"
-"A" -> canonicalartist ? canonicalartist ^ "A" -> album -> title = "fmt_title"
-"B" -> canonicalartist ? canonicalartist ^ "B" -> album -> title = "fmt_title"
-"C" -> canonicalartist ? canonicalartist ^ "C" -> album -> title = "fmt_title"
-"D" -> canonicalartist ? canonicalartist ^ "D" -> album -> title = "fmt_title"
-"E" -> canonicalartist ? canonicalartist ^ "E" -> album -> title = "fmt_title"
-"F" -> canonicalartist ? canonicalartist ^ "F" -> album -> title = "fmt_title"
-"G" -> canonicalartist ? canonicalartist ^ "G" -> album -> title = "fmt_title"
-"H" -> canonicalartist ? canonicalartist ^ "H" -> album -> title = "fmt_title"
-"I" -> canonicalartist ? canonicalartist ^ "I" -> album -> title = "fmt_title"
-"J" -> canonicalartist ? canonicalartist ^ "J" -> album -> title = "fmt_title"
-"K" -> canonicalartist ? canonicalartist ^ "K" -> album -> title = "fmt_title"
-"L" -> canonicalartist ? canonicalartist ^ "L" -> album -> title = "fmt_title"
-"M" -> canonicalartist ? canonicalartist ^ "M" -> album -> title = "fmt_title"
-"N" -> canonicalartist ? canonicalartist ^ "N" -> album -> title = "fmt_title"
-"O" -> canonicalartist ? canonicalartist ^ "O" -> album -> title = "fmt_title"
-"P" -> canonicalartist ? canonicalartist ^ "P" -> album -> title = "fmt_title"
-"Q" -> canonicalartist ? canonicalartist ^ "Q" -> album -> title = "fmt_title"
-"R" -> canonicalartist ? canonicalartist ^ "R" -> album -> title = "fmt_title"
-"S" -> canonicalartist ? canonicalartist ^ "S" -> album -> title = "fmt_title"
-"T" -> canonicalartist ? canonicalartist ^ "T" -> album -> title = "fmt_title"
-"U" -> canonicalartist ? canonicalartist ^ "U" -> album -> title = "fmt_title"
-"V" -> canonicalartist ? canonicalartist ^ "V" -> album -> title = "fmt_title"
-"W" -> canonicalartist ? canonicalartist ^ "W" -> album -> title = "fmt_title"
-"X" -> canonicalartist ? canonicalartist ^ "X" -> album -> title = "fmt_title"
-"Y" -> canonicalartist ? canonicalartist ^ "Y" -> album -> title = "fmt_title"
-"Z" -> canonicalartist ? canonicalartist ^ "Z" -> album -> title = "fmt_title"
-
-# ^ An empy line ends the menu
-
+%byfirstletter "custom_artist" "Artist A to Z" "canonicalartist"
# Define the A to Z album sub menu
-%menu_start "custom_album" "Album A to Z"
-"Numeric" -> album ? album < "A" -> title = "fmt_title"
-"A" -> album ? album ^ "A" -> title = "fmt_title"
-"B" -> album ? album ^ "B" -> title = "fmt_title"
-"C" -> album ? album ^ "C" -> title = "fmt_title"
-"D" -> album ? album ^ "D" -> title = "fmt_title"
-"E" -> album ? album ^ "E" -> title = "fmt_title"
-"F" -> album ? album ^ "F" -> title = "fmt_title"
-"G" -> album ? album ^ "G" -> title = "fmt_title"
-"H" -> album ? album ^ "H" -> title = "fmt_title"
-"I" -> album ? album ^ "I" -> title = "fmt_title"
-"J" -> album ? album ^ "J" -> title = "fmt_title"
-"K" -> album ? album ^ "K" -> title = "fmt_title"
-"L" -> album ? album ^ "L" -> title = "fmt_title"
-"M" -> album ? album ^ "M" -> title = "fmt_title"
-"N" -> album ? album ^ "N" -> title = "fmt_title"
-"O" -> album ? album ^ "O" -> title = "fmt_title"
-"P" -> album ? album ^ "P" -> title = "fmt_title"
-"Q" -> album ? album ^ "Q" -> title = "fmt_title"
-"R" -> album ? album ^ "R" -> title = "fmt_title"
-"S" -> album ? album ^ "S" -> title = "fmt_title"
-"T" -> album ? album ^ "T" -> title = "fmt_title"
-"U" -> album ? album ^ "U" -> title = "fmt_title"
-"V" -> album ? album ^ "V" -> title = "fmt_title"
-"W" -> album ? album ^ "W" -> title = "fmt_title"
-"X" -> album ? album ^ "X" -> title = "fmt_title"
-"Y" -> album ? album ^ "Y" -> title = "fmt_title"
-"Z" -> album ? album ^ "Z" -> title = "fmt_title"
-
+%byfirstletter "custom_album" "Album A to Z" "album"
# Define the A to Z track sub menu
-%menu_start "custom_track" "Track A to Z"
-"Numeric" -> title ? title < "A" -> title = "fmt_title"
-"A" -> title ? title ^ "A" -> title = "fmt_title"
-"B" -> title ? title ^ "B" -> title = "fmt_title"
-"C" -> title ? title ^ "C" -> title = "fmt_title"
-"D" -> title ? title ^ "D" -> title = "fmt_title"
-"E" -> title ? title ^ "E" -> title = "fmt_title"
-"F" -> title ? title ^ "F" -> title = "fmt_title"
-"G" -> title ? title ^ "G" -> title = "fmt_title"
-"H" -> title ? title ^ "H" -> title = "fmt_title"
-"I" -> title ? title ^ "I" -> title = "fmt_title"
-"J" -> title ? title ^ "J" -> title = "fmt_title"
-"K" -> title ? title ^ "K" -> title = "fmt_title"
-"L" -> title ? title ^ "L" -> title = "fmt_title"
-"M" -> title ? title ^ "M" -> title = "fmt_title"
-"N" -> title ? title ^ "N" -> title = "fmt_title"
-"O" -> title ? title ^ "O" -> title = "fmt_title"
-"P" -> title ? title ^ "P" -> title = "fmt_title"
-"Q" -> title ? title ^ "Q" -> title = "fmt_title"
-"R" -> title ? title ^ "R" -> title = "fmt_title"
-"S" -> title ? title ^ "S" -> title = "fmt_title"
-"T" -> title ? title ^ "T" -> title = "fmt_title"
-"U" -> title ? title ^ "U" -> title = "fmt_title"
-"V" -> title ? title ^ "V" -> title = "fmt_title"
-"W" -> title ? title ^ "W" -> title = "fmt_title"
-"X" -> title ? title ^ "X" -> title = "fmt_title"
-"Y" -> title ? title ^ "Y" -> title = "fmt_title"
-"Z" -> title ? title ^ "Z" -> title = "fmt_title"
+%byfirstletter "custom_track" "Track A to Z" "title"
+
+# ^ An empy line ends the menu
# Define the A to Z sub menu
%menu_start "a2z" "A to Z..."
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 {
var_include,
var_rootmenu,
var_format,
+ menu_byfirstletter,
menu_next,
menu_load,
menu_reload,
@@ -173,11 +174,12 @@ struct display_format {
static struct display_format *formats[TAGMENU_MAX_FMTS];
static int format_count;
+#define MENUENTRY_MAX_NAME 64
struct menu_entry {
- char name[64];
+ char name[MENUENTRY_MAX_NAME];
int type;
struct search_instruction {
- char name[64];
+ char name[MENUENTRY_MAX_NAME];
int tagorder[MAX_TAGS];
int tagorder_count;
struct tagcache_search_clause *clause[MAX_TAGS][TAGCACHE_MAX_CLAUSES];
@@ -381,6 +383,7 @@ static int get_tag(int *tag)
TAG_MATCH("comment", tag_comment),
TAG_MATCH("discnum", tag_discnumber),
TAG_MATCH("%format", var_format),
+ TAG_MATCH("%byfirstletter", menu_byfirstletter),
TAG_MATCH("%reload", menu_reload),
TAG_MATCH("filename", tag_filename),
@@ -1058,6 +1061,63 @@ int tagtree_import(void)
static bool parse_menu(const char *filename);
+static bool alloc_menu_item(void)
+{
+ /* Allocate */
+ if (menu->items[menu->itemcount] == NULL)
+ menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry));
+ if (!menu->items[menu->itemcount])
+ {
+ logf("tagtree failed to allocate %s", "menu items");
+ return false;
+ }
+ return true;
+}
+
+static void firstletter_parse_buf(char *buf)
+{
+ core_pin(tagtree_handle);
+ if (parse_search(menu->items[menu->itemcount], buf))
+ {
+ menu->items[menu->itemcount]->type = menu_byfirstletter;
+ menu->itemcount++;
+ }
+ core_unpin(tagtree_handle);;
+}
+
+static void build_firstletter_menu(char *buf, size_t bufsz)
+{
+ const char *subitem = buf;
+ size_t l = strlen(buf) + 1;
+ buf+=l;
+ bufsz-=l;
+
+ const char *showalbum = "";
+ const char * const fmt ="\"%s\" -> %s ? %s %c \"%c\" -> %s title = \"fmt_title\"";
+ if (!alloc_menu_item())
+ return;
+
+ if (strcasestr(subitem, "artist") != NULL)
+ showalbum = "album ->"; /* album subitem for canonicalartist */
+
+ /* Numeric ex: "Numeric" -> album ? album < "A" -> title = "fmt_title" */
+ snprintf(buf, bufsz, fmt,
+ str(LANG_DISPLAY_NUMERIC), subitem, subitem,'<', 'A', showalbum);
+
+ firstletter_parse_buf(buf);
+
+ for (int i = 0; i < 26; i++)
+ {
+ if (!alloc_menu_item())
+ return;
+
+ snprintf(buf, bufsz, fmt, "#", subitem, subitem,'^', 'A' + i, showalbum);
+ buf[1] = 'A' + i; /* overwrite the placeholder # with the current letter */
+ /* ex: "A" -> title ? title ^ "A" -> title = "fmt_title" */
+ firstletter_parse_buf(buf);
+ }
+}
+
static int parse_line(int n, char *buf, void *parameters)
{
char data[256];
@@ -1127,7 +1187,7 @@ static int parse_line(int n, char *buf, void *parameters)
logf("Load menu fail: %s", data);
}
break;
-
+ case menu_byfirstletter: /* Fallthrough */
case var_menu_start:
if (menu_count >= TAGMENU_MAX_MENUS)
{
@@ -1169,6 +1229,19 @@ static int parse_line(int n, char *buf, void *parameters)
return 0;
}
logf("menu: %s", menu->title);
+
+ if (variable == menu_byfirstletter)
+ {
+ if (get_token_str(data, sizeof(data)) < 0)
+ {
+ logf("%%firstletter_menu has no subitem"); /*artist,album*/
+ return 0;
+ }
+ logf("A-Z Menu subitem: %s", data);
+ read_menu = false;
+ build_firstletter_menu(data, sizeof(data));
+ break;
+ }
read_menu = true;
break;
@@ -1202,14 +1275,8 @@ static int parse_line(int n, char *buf, void *parameters)
return 0;
}
- /* Allocate */
- if (menu->items[menu->itemcount] == NULL)
- menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry));
- if (!menu->items[menu->itemcount])
- {
- logf("tagtree failed to allocate %s", "menu items");
+ if (!alloc_menu_item())
return -2;
- }
core_pin(tagtree_handle);
if (parse_search(menu->items[menu->itemcount], buf))
menu->itemcount++;
@@ -1449,6 +1516,7 @@ static void tcs_get_basename(struct tagcache_search *tcs, bool is_basename)
static int retrieve_entries(struct tree_context *c, int offset, bool init)
{
+ logf( "%s", __func__);
char tcs_buf[TAGCACHE_BUFSZ];
const long tcs_bufsz = sizeof(tcs_buf);
struct tagcache_search tcs;
@@ -1818,6 +1886,12 @@ static int load_root(struct tree_context *c)
dptr->extraseek = i;
dptr->customaction = ONPLAY_CUSTOMACTION_SHUFFLE_SONGS;
break;
+
+ case menu_byfirstletter:
+ dptr->newtable = TABLE_NAVIBROWSE;
+ dptr->extraseek = i;
+ dptr->customaction = ONPLAY_CUSTOMACTION_FIRSTLETTER;
+ break;
}
dptr++;
diff --git a/apps/tree.c b/apps/tree.c
index ac82b6c2df..c422100de8 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -205,6 +205,7 @@ static int tree_voice_cb(int selected_item, void * data)
struct tree_context * local_tc=(struct tree_context *)data;
char *name;
int attr=0;
+ int customaction = ONPLAY_NO_CUSTOMACTION;
#ifdef HAVE_TAGCACHE
bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;
char buf[AVERAGE_FILENAME_LENGTH*2];
@@ -213,6 +214,7 @@ static int tree_voice_cb(int selected_item, void * data)
{
attr = tagtree_get_attr(local_tc);
name = tagtree_get_entry_name(local_tc, selected_item, buf, sizeof(buf));
+ customaction = tagtree_get_custom_action(local_tc);
}
else
#endif
@@ -245,7 +247,7 @@ static int tree_voice_cb(int selected_item, void * data)
did_clip = false;
}
}
- bool spell_name = false;
+ bool spell_name = (customaction == ONPLAY_CUSTOMACTION_FIRSTLETTER);
if(!did_clip)
{
/* say the number or spell if required or as a fallback */