mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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
This commit is contained in:
parent
67ad6589fb
commit
06986d27f0
4 changed files with 93 additions and 99 deletions
|
@ -28,6 +28,7 @@
|
||||||
enum {
|
enum {
|
||||||
ONPLAY_NO_CUSTOMACTION,
|
ONPLAY_NO_CUSTOMACTION,
|
||||||
ONPLAY_CUSTOMACTION_SHUFFLE_SONGS,
|
ONPLAY_CUSTOMACTION_SHUFFLE_SONGS,
|
||||||
|
ONPLAY_CUSTOMACTION_FIRSTLETTER,
|
||||||
};
|
};
|
||||||
|
|
||||||
int onplay(char* file, int attr, int from_context, bool hotkey, int customaction);
|
int onplay(char* file, int attr, int from_context, bool hotkey, int customaction);
|
||||||
|
|
|
@ -30,97 +30,14 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# Define the A to Z Artist sub menu
|
# Define the A to Z Artist sub menu
|
||||||
%menu_start "custom_artist" "Artist A to Z"
|
%byfirstletter "custom_artist" "Artist A to Z" "canonicalartist"
|
||||||
"Numeric" -> canonicalartist ? canonicalartist < "A" -> album -> title = "fmt_title"
|
# Define the A to Z album sub menu
|
||||||
"A" -> canonicalartist ? canonicalartist ^ "A" -> album -> title = "fmt_title"
|
%byfirstletter "custom_album" "Album A to Z" "album"
|
||||||
"B" -> canonicalartist ? canonicalartist ^ "B" -> album -> title = "fmt_title"
|
# Define the A to Z track sub menu
|
||||||
"C" -> canonicalartist ? canonicalartist ^ "C" -> album -> title = "fmt_title"
|
%byfirstletter "custom_track" "Track A to Z" "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
|
# ^ An empy line ends the menu
|
||||||
|
|
||||||
# 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"
|
|
||||||
|
|
||||||
# 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"
|
|
||||||
|
|
||||||
# Define the A to Z sub menu
|
# Define the A to Z sub menu
|
||||||
%menu_start "a2z" "A to Z..."
|
%menu_start "a2z" "A to Z..."
|
||||||
"Artists" ==> "custom_artist"
|
"Artists" ==> "custom_artist"
|
||||||
|
|
|
@ -112,6 +112,7 @@ enum variables {
|
||||||
var_include,
|
var_include,
|
||||||
var_rootmenu,
|
var_rootmenu,
|
||||||
var_format,
|
var_format,
|
||||||
|
menu_byfirstletter,
|
||||||
menu_next,
|
menu_next,
|
||||||
menu_load,
|
menu_load,
|
||||||
menu_reload,
|
menu_reload,
|
||||||
|
@ -173,11 +174,12 @@ struct display_format {
|
||||||
static struct display_format *formats[TAGMENU_MAX_FMTS];
|
static struct display_format *formats[TAGMENU_MAX_FMTS];
|
||||||
static int format_count;
|
static int format_count;
|
||||||
|
|
||||||
|
#define MENUENTRY_MAX_NAME 64
|
||||||
struct menu_entry {
|
struct menu_entry {
|
||||||
char name[64];
|
char name[MENUENTRY_MAX_NAME];
|
||||||
int type;
|
int type;
|
||||||
struct search_instruction {
|
struct search_instruction {
|
||||||
char name[64];
|
char name[MENUENTRY_MAX_NAME];
|
||||||
int tagorder[MAX_TAGS];
|
int tagorder[MAX_TAGS];
|
||||||
int tagorder_count;
|
int tagorder_count;
|
||||||
struct tagcache_search_clause *clause[MAX_TAGS][TAGCACHE_MAX_CLAUSES];
|
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("comment", tag_comment),
|
||||||
TAG_MATCH("discnum", tag_discnumber),
|
TAG_MATCH("discnum", tag_discnumber),
|
||||||
TAG_MATCH("%format", var_format),
|
TAG_MATCH("%format", var_format),
|
||||||
|
TAG_MATCH("%byfirstletter", menu_byfirstletter),
|
||||||
TAG_MATCH("%reload", menu_reload),
|
TAG_MATCH("%reload", menu_reload),
|
||||||
|
|
||||||
TAG_MATCH("filename", tag_filename),
|
TAG_MATCH("filename", tag_filename),
|
||||||
|
@ -1058,6 +1061,63 @@ int tagtree_import(void)
|
||||||
|
|
||||||
static bool parse_menu(const char *filename);
|
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)
|
static int parse_line(int n, char *buf, void *parameters)
|
||||||
{
|
{
|
||||||
char data[256];
|
char data[256];
|
||||||
|
@ -1127,7 +1187,7 @@ static int parse_line(int n, char *buf, void *parameters)
|
||||||
logf("Load menu fail: %s", data);
|
logf("Load menu fail: %s", data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case menu_byfirstletter: /* Fallthrough */
|
||||||
case var_menu_start:
|
case var_menu_start:
|
||||||
if (menu_count >= TAGMENU_MAX_MENUS)
|
if (menu_count >= TAGMENU_MAX_MENUS)
|
||||||
{
|
{
|
||||||
|
@ -1169,6 +1229,19 @@ static int parse_line(int n, char *buf, void *parameters)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
logf("menu: %s", menu->title);
|
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;
|
read_menu = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1202,14 +1275,8 @@ static int parse_line(int n, char *buf, void *parameters)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate */
|
if (!alloc_menu_item())
|
||||||
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 -2;
|
return -2;
|
||||||
}
|
|
||||||
core_pin(tagtree_handle);
|
core_pin(tagtree_handle);
|
||||||
if (parse_search(menu->items[menu->itemcount], buf))
|
if (parse_search(menu->items[menu->itemcount], buf))
|
||||||
menu->itemcount++;
|
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)
|
static int retrieve_entries(struct tree_context *c, int offset, bool init)
|
||||||
{
|
{
|
||||||
|
logf( "%s", __func__);
|
||||||
char tcs_buf[TAGCACHE_BUFSZ];
|
char tcs_buf[TAGCACHE_BUFSZ];
|
||||||
const long tcs_bufsz = sizeof(tcs_buf);
|
const long tcs_bufsz = sizeof(tcs_buf);
|
||||||
struct tagcache_search tcs;
|
struct tagcache_search tcs;
|
||||||
|
@ -1818,6 +1886,12 @@ static int load_root(struct tree_context *c)
|
||||||
dptr->extraseek = i;
|
dptr->extraseek = i;
|
||||||
dptr->customaction = ONPLAY_CUSTOMACTION_SHUFFLE_SONGS;
|
dptr->customaction = ONPLAY_CUSTOMACTION_SHUFFLE_SONGS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case menu_byfirstletter:
|
||||||
|
dptr->newtable = TABLE_NAVIBROWSE;
|
||||||
|
dptr->extraseek = i;
|
||||||
|
dptr->customaction = ONPLAY_CUSTOMACTION_FIRSTLETTER;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dptr++;
|
dptr++;
|
||||||
|
|
|
@ -205,6 +205,7 @@ static int tree_voice_cb(int selected_item, void * data)
|
||||||
struct tree_context * local_tc=(struct tree_context *)data;
|
struct tree_context * local_tc=(struct tree_context *)data;
|
||||||
char *name;
|
char *name;
|
||||||
int attr=0;
|
int attr=0;
|
||||||
|
int customaction = ONPLAY_NO_CUSTOMACTION;
|
||||||
#ifdef HAVE_TAGCACHE
|
#ifdef HAVE_TAGCACHE
|
||||||
bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;
|
bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;
|
||||||
char buf[AVERAGE_FILENAME_LENGTH*2];
|
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);
|
attr = tagtree_get_attr(local_tc);
|
||||||
name = tagtree_get_entry_name(local_tc, selected_item, buf, sizeof(buf));
|
name = tagtree_get_entry_name(local_tc, selected_item, buf, sizeof(buf));
|
||||||
|
customaction = tagtree_get_custom_action(local_tc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -245,7 +247,7 @@ static int tree_voice_cb(int selected_item, void * data)
|
||||||
did_clip = false;
|
did_clip = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool spell_name = false;
|
bool spell_name = (customaction == ONPLAY_CUSTOMACTION_FIRSTLETTER);
|
||||||
if(!did_clip)
|
if(!did_clip)
|
||||||
{
|
{
|
||||||
/* say the number or spell if required or as a fallback */
|
/* say the number or spell if required or as a fallback */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue