forked from len0rd/rockbox
(1) New syntax to support conditional formatting.
(2) Reduced tagnavi memory consumption. (3) There was a bug that splash screen counter was counting down when inserting tracks next. But in fact that might be preferred, so always count down after successful tagcache query. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11223 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
a7acf1351f
commit
b89b5ba2ee
5 changed files with 399 additions and 232 deletions
353
apps/tagcache.c
353
apps/tagcache.c
|
@ -538,6 +538,96 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool open_files(struct tagcache_search *tcs, int tag)
|
||||||
|
{
|
||||||
|
if (tcs->idxfd[tag] < 0)
|
||||||
|
{
|
||||||
|
char fn[MAX_PATH];
|
||||||
|
|
||||||
|
snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tag);
|
||||||
|
tcs->idxfd[tag] = open(fn, O_RDONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcs->idxfd[tag] < 0)
|
||||||
|
{
|
||||||
|
logf("File not open!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
|
||||||
|
int tag, char *buf, long size)
|
||||||
|
{
|
||||||
|
struct tagfile_entry tfe;
|
||||||
|
long seek;
|
||||||
|
|
||||||
|
*buf = '\0';
|
||||||
|
|
||||||
|
if (tagcache_is_numeric_tag(tag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
seek = idx->tag_seek[tag];
|
||||||
|
if (seek < 0)
|
||||||
|
{
|
||||||
|
logf("Retrieve failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
|
if (tcs->ramsearch)
|
||||||
|
{
|
||||||
|
struct tagfile_entry *ep;
|
||||||
|
|
||||||
|
# ifdef HAVE_DIRCACHE
|
||||||
|
if (tag == tag_filename && idx->flag & FLAG_DIRCACHE)
|
||||||
|
{
|
||||||
|
dircache_copy_path((struct dircache_entry *)seek,
|
||||||
|
buf, size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
if (tag != tag_filename)
|
||||||
|
{
|
||||||
|
ep = (struct tagfile_entry *)&hdr->tags[tag][seek];
|
||||||
|
strncpy(buf, ep->tag_data, size-1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!open_files(tcs, tag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lseek(tcs->idxfd[tag], seek, SEEK_SET);
|
||||||
|
if (read(tcs->idxfd[tag], &tfe, sizeof(struct tagfile_entry)) !=
|
||||||
|
sizeof(struct tagfile_entry))
|
||||||
|
{
|
||||||
|
logf("read error #5");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tfe.tag_length >= size)
|
||||||
|
{
|
||||||
|
logf("too small buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read(tcs->idxfd[tag], buf, tfe.tag_length) !=
|
||||||
|
tfe.tag_length)
|
||||||
|
{
|
||||||
|
logf("read error #6");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[tfe.tag_length] = '\0';
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static long check_virtual_tags(int tag, const struct index_entry *idx)
|
static long check_virtual_tags(int tag, const struct index_entry *idx)
|
||||||
{
|
{
|
||||||
long data = 0;
|
long data = 0;
|
||||||
|
@ -671,6 +761,96 @@ static bool check_against_clause(long numeric, const char *str,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_clauses(struct tagcache_search *tcs,
|
||||||
|
struct index_entry *idx,
|
||||||
|
struct tagcache_search_clause **clause, int count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
|
if (tcs->ramsearch)
|
||||||
|
{
|
||||||
|
/* Go through all conditional clauses. */
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
struct tagfile_entry *tfe;
|
||||||
|
int seek;
|
||||||
|
char buf[256];
|
||||||
|
char *str = NULL;
|
||||||
|
|
||||||
|
seek = check_virtual_tags(clause[i]->tag, idx);
|
||||||
|
|
||||||
|
if (!tagcache_is_numeric_tag(clause[i]->tag))
|
||||||
|
{
|
||||||
|
if (clause[i]->tag == tag_filename)
|
||||||
|
{
|
||||||
|
retrieve(tcs, idx, tag_filename, buf, sizeof buf);
|
||||||
|
str = buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tfe = (struct tagfile_entry *)&hdr->tags[clause[i]->tag][seek];
|
||||||
|
str = tfe->tag_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!check_against_clause(seek, str, clause[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Check for conditions. */
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
struct tagfile_entry tfe;
|
||||||
|
int seek;
|
||||||
|
char str[256];
|
||||||
|
|
||||||
|
seek = check_virtual_tags(clause[i]->tag, idx);
|
||||||
|
|
||||||
|
memset(str, 0, sizeof str);
|
||||||
|
if (!tagcache_is_numeric_tag(clause[i]->tag))
|
||||||
|
{
|
||||||
|
int fd = tcs->idxfd[clause[i]->tag];
|
||||||
|
lseek(fd, seek, SEEK_SET);
|
||||||
|
read(fd, &tfe, sizeof(struct tagfile_entry));
|
||||||
|
if (tfe.tag_length >= (int)sizeof(str))
|
||||||
|
{
|
||||||
|
logf("Too long tag read!");
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
|
read(fd, str, tfe.tag_length);
|
||||||
|
|
||||||
|
/* Check if entry has been deleted. */
|
||||||
|
if (str[0] == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!check_against_clause(seek, str, clause[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tagcache_check_clauses(struct tagcache_search *tcs,
|
||||||
|
struct tagcache_search_clause **clause, int count)
|
||||||
|
{
|
||||||
|
struct index_entry idx;
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return check_clauses(tcs, &idx, clause, count);
|
||||||
|
}
|
||||||
|
|
||||||
static bool add_uniqbuf(struct tagcache_search *tcs, long id)
|
static bool add_uniqbuf(struct tagcache_search *tcs, long id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -713,18 +893,18 @@ static bool build_lookup_list(struct tagcache_search *tcs)
|
||||||
|
|
||||||
for (i = tcs->seek_pos; i < hdr->h.tch.entry_count; i++)
|
for (i = tcs->seek_pos; i < hdr->h.tch.entry_count; i++)
|
||||||
{
|
{
|
||||||
|
struct index_entry *idx = &hdr->indices[i];
|
||||||
if (tcs->seek_list_count == SEEK_LIST_SIZE)
|
if (tcs->seek_list_count == SEEK_LIST_SIZE)
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
/* Skip deleted files. */
|
/* Skip deleted files. */
|
||||||
if (hdr->indices[i].flag & FLAG_DELETED)
|
if (idx->flag & FLAG_DELETED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Go through all filters.. */
|
/* Go through all filters.. */
|
||||||
for (j = 0; j < tcs->filter_count; j++)
|
for (j = 0; j < tcs->filter_count; j++)
|
||||||
{
|
{
|
||||||
if (hdr->indices[i].tag_seek[tcs->filter_tag[j]] !=
|
if (idx->tag_seek[tcs->filter_tag[j]] != tcs->filter_seek[j])
|
||||||
tcs->filter_seek[j])
|
|
||||||
{
|
{
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
|
@ -733,51 +913,17 @@ static bool build_lookup_list(struct tagcache_search *tcs)
|
||||||
if (j < tcs->filter_count)
|
if (j < tcs->filter_count)
|
||||||
continue ;
|
continue ;
|
||||||
|
|
||||||
/* Go through all conditional clauses. */
|
/* Check for conditions. */
|
||||||
for (j = 0; j < tcs->clause_count; j++)
|
if (!check_clauses(tcs, idx, tcs->clause, tcs->clause_count))
|
||||||
{
|
continue;
|
||||||
struct index_entry *idx = &hdr->indices[i];
|
|
||||||
int seek;
|
|
||||||
char buf[256];
|
|
||||||
char *str = NULL;
|
|
||||||
struct tagfile_entry *entry;
|
|
||||||
|
|
||||||
seek = check_virtual_tags(tcs->clause[j]->tag, idx);
|
|
||||||
|
|
||||||
if (!tagcache_is_numeric_tag(tcs->clause[j]->tag))
|
|
||||||
{
|
|
||||||
if (tcs->clause[j]->tag == tag_filename)
|
|
||||||
{
|
|
||||||
int oldtype = tcs->type;
|
|
||||||
tcs->type = tag_filename;
|
|
||||||
tagcache_retrieve(tcs, i, buf, sizeof buf);
|
|
||||||
tcs->type = oldtype;
|
|
||||||
str = buf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry = (struct tagfile_entry *)&hdr->tags[tcs->clause[j]->tag][seek];
|
|
||||||
str = entry->tag_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!check_against_clause(seek, str, tcs->clause[j]))
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j < tcs->clause_count)
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
/* Add to the seek list if not already in uniq buffer. */
|
/* Add to the seek list if not already in uniq buffer. */
|
||||||
if (!add_uniqbuf(tcs, hdr->indices[i].tag_seek[tcs->type]))
|
if (!add_uniqbuf(tcs, idx->tag_seek[tcs->type]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Lets add it. */
|
/* Lets add it. */
|
||||||
tcs->seek_list[tcs->seek_list_count] =
|
tcs->seek_list[tcs->seek_list_count] = idx->tag_seek[tcs->type];
|
||||||
hdr->indices[i].tag_seek[tcs->type];
|
tcs->seek_flags[tcs->seek_list_count] = idx->flag;
|
||||||
tcs->seek_flags[tcs->seek_list_count] =
|
|
||||||
hdr->indices[i].flag;
|
|
||||||
tcs->seek_list_count++;
|
tcs->seek_list_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,39 +959,8 @@ static bool build_lookup_list(struct tagcache_search *tcs)
|
||||||
continue ;
|
continue ;
|
||||||
|
|
||||||
/* Check for conditions. */
|
/* Check for conditions. */
|
||||||
for (i = 0; i < tcs->clause_count; i++)
|
if (!check_clauses(tcs, &entry, tcs->clause, tcs->clause_count))
|
||||||
{
|
continue;
|
||||||
struct tagfile_entry tfe;
|
|
||||||
int seek;
|
|
||||||
char str[256];
|
|
||||||
|
|
||||||
seek = check_virtual_tags(tcs->clause[i]->tag, &entry);
|
|
||||||
|
|
||||||
memset(str, 0, sizeof str);
|
|
||||||
if (!tagcache_is_numeric_tag(tcs->clause[i]->tag))
|
|
||||||
{
|
|
||||||
int fd = tcs->idxfd[tcs->clause[i]->tag];
|
|
||||||
lseek(fd, seek, SEEK_SET);
|
|
||||||
read(fd, &tfe, sizeof(struct tagfile_entry));
|
|
||||||
if (tfe.tag_length >= (int)sizeof(str))
|
|
||||||
{
|
|
||||||
logf("Too long tag read!");
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
|
|
||||||
read(fd, str, tfe.tag_length);
|
|
||||||
|
|
||||||
/* Check if entry has been deleted. */
|
|
||||||
if (str[0] == '\0')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_against_clause(seek, str, tcs->clause[i]))
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < tcs->clause_count)
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
/* Add to the seek list if not already in uniq buffer. */
|
/* Add to the seek list if not already in uniq buffer. */
|
||||||
if (!add_uniqbuf(tcs, entry.tag_seek[tcs->type]))
|
if (!add_uniqbuf(tcs, entry.tag_seek[tcs->type]))
|
||||||
|
@ -1025,25 +1140,6 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool open_files(struct tagcache_search *tcs)
|
|
||||||
{
|
|
||||||
if (tcs->idxfd[tcs->type] < 0)
|
|
||||||
{
|
|
||||||
char fn[MAX_PATH];
|
|
||||||
|
|
||||||
snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tcs->type);
|
|
||||||
tcs->idxfd[tcs->type] = open(fn, O_RDONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tcs->idxfd[tcs->type] < 0)
|
|
||||||
{
|
|
||||||
logf("File not open!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TAG_FILENAME_RAM(tcs) ((tcs->type == tag_filename) \
|
#define TAG_FILENAME_RAM(tcs) ((tcs->type == tag_filename) \
|
||||||
? (flag & FLAG_DIRCACHE) : 1)
|
? (flag & FLAG_DIRCACHE) : 1)
|
||||||
|
|
||||||
|
@ -1085,7 +1181,7 @@ static bool get_next(struct tagcache_search *tcs)
|
||||||
if ((!tcs->ramsearch || !TAG_FILENAME_RAM(tcs))
|
if ((!tcs->ramsearch || !TAG_FILENAME_RAM(tcs))
|
||||||
&& !tagcache_is_numeric_tag(tcs->type))
|
&& !tagcache_is_numeric_tag(tcs->type))
|
||||||
{
|
{
|
||||||
if (!open_files(tcs))
|
if (!open_files(tcs, tcs->type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lseek(tcs->idxfd[tcs->type], tcs->seek_list[tcs->seek_list_count], SEEK_SET);
|
lseek(tcs->idxfd[tcs->type], tcs->seek_list[tcs->seek_list_count], SEEK_SET);
|
||||||
|
@ -1144,7 +1240,7 @@ static bool get_next(struct tagcache_search *tcs)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!open_files(tcs))
|
if (!open_files(tcs, tcs->type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tcs->result_seek = lseek(tcs->idxfd[tcs->type], 0, SEEK_CUR);
|
tcs->result_seek = lseek(tcs->idxfd[tcs->type], 0, SEEK_CUR);
|
||||||
|
@ -1193,72 +1289,13 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
|
bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
|
||||||
char *buf, long size)
|
char *buf, long size)
|
||||||
{
|
{
|
||||||
struct tagfile_entry tfe;
|
|
||||||
struct index_entry idx;
|
struct index_entry idx;
|
||||||
long seek;
|
|
||||||
|
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
if (!get_index(tcs->masterfd, idxid, &idx, true))
|
if (!get_index(tcs->masterfd, idxid, &idx, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
seek = idx.tag_seek[tcs->type];
|
return retrieve(tcs, &idx, tcs->type, buf, size);
|
||||||
if (seek < 0)
|
|
||||||
{
|
|
||||||
logf("Retrieve failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
|
||||||
if (tcs->ramsearch)
|
|
||||||
{
|
|
||||||
struct tagfile_entry *ep;
|
|
||||||
|
|
||||||
# ifdef HAVE_DIRCACHE
|
|
||||||
if (tcs->type == tag_filename && hdr->indices[idxid].flag & FLAG_DIRCACHE)
|
|
||||||
{
|
|
||||||
dircache_copy_path((struct dircache_entry *)seek,
|
|
||||||
buf, size);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# endif
|
|
||||||
if (tcs->type != tag_filename)
|
|
||||||
{
|
|
||||||
ep = (struct tagfile_entry *)&hdr->tags[tcs->type][seek];
|
|
||||||
strncpy(buf, ep->tag_data, size-1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!open_files(tcs))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
lseek(tcs->idxfd[tcs->type], seek, SEEK_SET);
|
|
||||||
if (read(tcs->idxfd[tcs->type], &tfe, sizeof(struct tagfile_entry)) !=
|
|
||||||
sizeof(struct tagfile_entry))
|
|
||||||
{
|
|
||||||
logf("read error #5");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tfe.tag_length >= size)
|
|
||||||
{
|
|
||||||
logf("too small buffer");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read(tcs->idxfd[tcs->type], buf, tfe.tag_length) !=
|
|
||||||
tfe.tag_length)
|
|
||||||
{
|
|
||||||
logf("read error #6");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[tfe.tag_length] = '\0';
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -2962,10 +2999,12 @@ static bool delete_entry(long idx_id)
|
||||||
/* Skip the header block */
|
/* Skip the header block */
|
||||||
lseek(fd, myidx.tag_seek[tag] + sizeof(struct tagfile_entry), SEEK_SET);
|
lseek(fd, myidx.tag_seek[tag] + sizeof(struct tagfile_entry), SEEK_SET);
|
||||||
|
|
||||||
|
/* Debug, print 10 first characters of the tag
|
||||||
read(fd, buf, 10);
|
read(fd, buf, 10);
|
||||||
buf[10]='\0';
|
buf[10]='\0';
|
||||||
logf("TAG:%s", buf);
|
logf("TAG:%s", buf);
|
||||||
lseek(fd, -10, SEEK_CUR);
|
lseek(fd, -10, SEEK_CUR);
|
||||||
|
*/
|
||||||
|
|
||||||
/* Write first data byte in tag as \0 */
|
/* Write first data byte in tag as \0 */
|
||||||
write(fd, "", 1);
|
write(fd, "", 1);
|
||||||
|
|
|
@ -98,7 +98,7 @@ struct tagcache_search_clause
|
||||||
bool numeric;
|
bool numeric;
|
||||||
bool input;
|
bool input;
|
||||||
long numeric_data;
|
long numeric_data;
|
||||||
char str[128];
|
char *str;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tagcache_search {
|
struct tagcache_search {
|
||||||
|
@ -139,6 +139,8 @@ bool tagcache_is_numeric_tag(int type);
|
||||||
bool tagcache_is_unique_tag(int type);
|
bool tagcache_is_unique_tag(int type);
|
||||||
bool tagcache_is_sorted_tag(int type);
|
bool tagcache_is_sorted_tag(int type);
|
||||||
bool tagcache_find_index(struct tagcache_search *tcs, const char *filename);
|
bool tagcache_find_index(struct tagcache_search *tcs, const char *filename);
|
||||||
|
bool tagcache_check_clauses(struct tagcache_search *tcs,
|
||||||
|
struct tagcache_search_clause **clause, int count);
|
||||||
bool tagcache_search(struct tagcache_search *tcs, int tag);
|
bool tagcache_search(struct tagcache_search *tcs, int tag);
|
||||||
void tagcache_search_set_uniqbuf(struct tagcache_search *tcs,
|
void tagcache_search_set_uniqbuf(struct tagcache_search *tcs,
|
||||||
void *buffer, long length);
|
void *buffer, long length);
|
||||||
|
|
|
@ -5,6 +5,15 @@
|
||||||
# Instead, you can modify "/.rockbox/tagnavi_custom.config" which will never
|
# Instead, you can modify "/.rockbox/tagnavi_custom.config" which will never
|
||||||
# get overwritten automatically.
|
# get overwritten automatically.
|
||||||
|
|
||||||
|
# Basic format declarations
|
||||||
|
%format "fmt_title" "%02d. %s" tracknum title ? tracknum > "0"
|
||||||
|
%format "fmt_title" "%s" title
|
||||||
|
%format "fmt_mostplayed" "(%3d) %s" playcount title %sort = "inverse" %limit = "100"
|
||||||
|
%format "fmt_lastplayed" "%06d%s" lastplayed title %sort = "inverse" %limit = "99" %strip = "6"
|
||||||
|
%format "fmt_best_tracks" "%02d. %s (%3d)" tracknum title autoscore
|
||||||
|
%format "fmt_played" "(%3d/%d) %s" autoscore playcount title
|
||||||
|
%format "fmt_score" "(%3d) %s" autoscore title
|
||||||
|
|
||||||
# Include our custom menu
|
# Include our custom menu
|
||||||
%include "/.rockbox/tagnavi_custom.config"
|
%include "/.rockbox/tagnavi_custom.config"
|
||||||
|
|
||||||
|
@ -14,11 +23,11 @@
|
||||||
|
|
||||||
# Define the search sub menu
|
# Define the search sub menu
|
||||||
%menu_start "search" "Search by..."
|
%menu_start "search" "Search by..."
|
||||||
"Artist" -> artist ? artist ~ "" -> album -> title = "%02d. %s" tracknum title
|
"Artist" -> artist ? artist ~ "" -> album -> title = "fmt_title"
|
||||||
"Album" -> album ? album ~ "" -> title = "%02d. %s" tracknum title
|
"Album" -> album ? album ~ "" -> title = "fmt_title"
|
||||||
"Title" -> title ? title ~ ""
|
"Title" -> title ? title ~ ""
|
||||||
"Filename" -> filename ? filename ~ ""
|
"Filename" -> filename ? filename ~ ""
|
||||||
"Score" -> title = "(%3d) %s" autoscore title ? autoscore > ""
|
"Score" -> title = "fmt_score" ? autoscore > ""
|
||||||
|
|
||||||
# ^ An empy line ends the menu
|
# ^ An empy line ends the menu
|
||||||
|
|
||||||
|
@ -28,19 +37,20 @@
|
||||||
|
|
||||||
# Define the title of the main menu
|
# Define the title of the main menu
|
||||||
%menu_start "main" "Browse by..."
|
%menu_start "main" "Browse by..."
|
||||||
"Artist" -> artist -> album -> title = "%02d. %s" tracknum title
|
"Artist" -> artist -> album -> title = "fmt_title"
|
||||||
"Album" -> album -> title = "%02d. %s" tracknum title
|
"Album" -> album -> title = "fmt_title"
|
||||||
"Genre" -> genre -> artist -> album -> title = "%02d. %s" tracknum title
|
"Genre" -> genre -> artist -> album -> title = "fmt_title"
|
||||||
"Composer" -> composer -> album -> title = "%02d. %s" tracknum title
|
"Composer" -> composer -> album -> title = "fmt_title"
|
||||||
"Track" -> title
|
"Track" -> title
|
||||||
"Year" -> year ? year > "1000" & year < "2008" -> artist -> album -> title = "%02d. %s" tracknum title
|
"Year" -> year ? year > "1000" & year < "2008" -> artist -> album -> title = "fmt_title"
|
||||||
"Search..." ==> "search"
|
"Search..." ==> "search"
|
||||||
"Most played tracks" -> title = "(%3d) %s" playcount title %sort = "inverse" %limit = "100" ? playcount > "0"
|
"Most played tracks" -> title = "fmt_mostplayed" ? playcount > "0"
|
||||||
"Last played tracks" -> title = "%06d%s" lastplayed title %sort = "inverse" %limit = "99" %strip = "6" ? playcount > "0"
|
"Last played tracks" -> title = "fmt_lastplayed" ? playcount > "0"
|
||||||
"Never played tracks" -> artist ? playcount == "0" -> album -> title = "%02d. %s" tracknum title
|
"Never played tracks" -> artist ? playcount == "0" -> album -> title = "fmt_title"
|
||||||
"Best tracks" -> artist ? playcount > "1" & autoscore > "85" -> album -> title = "%02d. %s (%3d)" tracknum title autoscore
|
"Best tracks" -> artist ? playcount > "1" & autoscore > "85" -> album -> title = "fmt_best_tracks"
|
||||||
"List played tracks" -> title = "(%3d/%d) %s" autoscore playcount title ? playcount > "0"
|
"List played tracks" -> title = "fmt_played" ? playcount > "0"
|
||||||
"Custom view..." ==> "custom"
|
"Custom view..." ==> "custom"
|
||||||
|
|
||||||
# And finally set main menu as our root menu
|
# And finally set main menu as our root menu
|
||||||
%root_menu "main"
|
%root_menu "main"
|
||||||
|
|
||||||
|
|
237
apps/tagtree.c
237
apps/tagtree.c
|
@ -56,6 +56,7 @@ enum variables {
|
||||||
var_menu_start,
|
var_menu_start,
|
||||||
var_include,
|
var_include,
|
||||||
var_rootmenu,
|
var_rootmenu,
|
||||||
|
var_format,
|
||||||
menu_next,
|
menu_next,
|
||||||
menu_load,
|
menu_load,
|
||||||
};
|
};
|
||||||
|
@ -82,8 +83,11 @@ static bool sort_inverse;
|
||||||
* sort_inverse = true
|
* sort_inverse = true
|
||||||
*/
|
*/
|
||||||
struct display_format {
|
struct display_format {
|
||||||
bool valid;
|
char name[32];
|
||||||
char formatstr[64];
|
struct tagcache_search_clause *clause[TAGCACHE_MAX_CLAUSES];
|
||||||
|
int clause_count;
|
||||||
|
char *formatstr;
|
||||||
|
int group_id;
|
||||||
int tags[MAX_TAGS];
|
int tags[MAX_TAGS];
|
||||||
int tag_count;
|
int tag_count;
|
||||||
|
|
||||||
|
@ -92,12 +96,15 @@ struct display_format {
|
||||||
bool sort_inverse;
|
bool sort_inverse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct display_format *formats[TAGMENU_MAX_FMTS];
|
||||||
|
static int format_count;
|
||||||
|
|
||||||
struct search_instruction {
|
struct search_instruction {
|
||||||
char name[64];
|
char name[64];
|
||||||
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];
|
||||||
struct display_format format[MAX_TAGS];
|
int format_id[MAX_TAGS];
|
||||||
int clause_count[MAX_TAGS];
|
int clause_count[MAX_TAGS];
|
||||||
int result_seek[MAX_TAGS];
|
int result_seek[MAX_TAGS];
|
||||||
};
|
};
|
||||||
|
@ -130,6 +137,7 @@ static int root_menu;
|
||||||
static int current_offset;
|
static int current_offset;
|
||||||
static int current_entry_count;
|
static int current_entry_count;
|
||||||
|
|
||||||
|
static int format_count;
|
||||||
static struct tree_context *tc;
|
static struct tree_context *tc;
|
||||||
|
|
||||||
static int get_token_str(char *buf, int size)
|
static int get_token_str(char *buf, int size)
|
||||||
|
@ -200,6 +208,7 @@ static int get_tag(int *tag)
|
||||||
MATCH(tag, buf, "%menu_start", var_menu_start);
|
MATCH(tag, buf, "%menu_start", var_menu_start);
|
||||||
MATCH(tag, buf, "%include", var_include);
|
MATCH(tag, buf, "%include", var_include);
|
||||||
MATCH(tag, buf, "%root_menu", var_rootmenu);
|
MATCH(tag, buf, "%root_menu", var_rootmenu);
|
||||||
|
MATCH(tag, buf, "%format", var_format);
|
||||||
MATCH(tag, buf, "->", menu_next);
|
MATCH(tag, buf, "->", menu_next);
|
||||||
MATCH(tag, buf, "==>", menu_load);
|
MATCH(tag, buf, "==>", menu_load);
|
||||||
|
|
||||||
|
@ -249,45 +258,36 @@ static int get_clause(int *condition)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool add_clause(struct search_instruction *inst,
|
static bool read_clause(struct tagcache_search_clause *clause)
|
||||||
int tag, int type, const char *str)
|
|
||||||
{
|
{
|
||||||
int len = strlen(str);
|
char buf[256];
|
||||||
struct tagcache_search_clause *clause;
|
|
||||||
|
|
||||||
if (inst->clause_count[inst->tagorder_count] >= TAGCACHE_MAX_CLAUSES)
|
if (get_tag(&clause->tag) <= 0)
|
||||||
{
|
|
||||||
logf("Too many clauses");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
clause = &inst->clause[inst->tagorder_count]
|
if (get_clause(&clause->type) <= 0)
|
||||||
[inst->clause_count[inst->tagorder_count]];
|
|
||||||
if (len >= (int)sizeof(clause->str) - 1)
|
|
||||||
{
|
|
||||||
logf("Too long str in condition");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
clause->tag = tag;
|
if (get_token_str(buf, sizeof buf) < 0)
|
||||||
clause->type = type;
|
return false;
|
||||||
if (len == 0)
|
|
||||||
|
clause->str = buffer_alloc(strlen(buf)+1);
|
||||||
|
strcpy(clause->str, buf);
|
||||||
|
|
||||||
|
logf("got clause: %d/%d [%s]", clause->tag, clause->type, clause->str);
|
||||||
|
|
||||||
|
if (*(clause->str) == '\0')
|
||||||
clause->input = true;
|
clause->input = true;
|
||||||
else
|
else
|
||||||
clause->input = false;
|
clause->input = false;
|
||||||
|
|
||||||
if (tagcache_is_numeric_tag(tag))
|
if (tagcache_is_numeric_tag(clause->tag))
|
||||||
{
|
{
|
||||||
clause->numeric = true;
|
clause->numeric = true;
|
||||||
clause->numeric_data = atoi(str);
|
clause->numeric_data = atoi(clause->str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
clause->numeric = false;
|
clause->numeric = false;
|
||||||
strcpy(clause->str, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
inst->clause_count[inst->tagorder_count]++;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -313,12 +313,38 @@ static int get_format_str(struct display_format *fmt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
int i;
|
||||||
|
|
||||||
memset(fmt, 0, sizeof(struct display_format));
|
memset(fmt, 0, sizeof(struct display_format));
|
||||||
|
|
||||||
if (get_token_str(fmt->formatstr, sizeof fmt->formatstr) < 0)
|
if (get_token_str(fmt->name, sizeof fmt->name) < 0)
|
||||||
return -10;
|
return -10;
|
||||||
|
|
||||||
|
/* Determine the group id */
|
||||||
|
fmt->group_id = 0;
|
||||||
|
for (i = 0; i < format_count; i++)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(formats[i]->name, fmt->name))
|
||||||
|
{
|
||||||
|
fmt->group_id = formats[i]->group_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formats[i]->group_id > fmt->group_id)
|
||||||
|
fmt->group_id = formats[i]->group_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == format_count)
|
||||||
|
fmt->group_id++;
|
||||||
|
|
||||||
|
logf("format: (%d) %s", fmt->group_id, fmt->name);
|
||||||
|
|
||||||
|
if (get_token_str(buf, sizeof buf) < 0)
|
||||||
|
return -10;
|
||||||
|
|
||||||
|
fmt->formatstr = buffer_alloc(strlen(buf) + 1);
|
||||||
|
strcpy(fmt->formatstr, buf);
|
||||||
|
|
||||||
while (fmt->tag_count < MAX_TAGS)
|
while (fmt->tag_count < MAX_TAGS)
|
||||||
{
|
{
|
||||||
ret = get_tag(&fmt->tags[fmt->tag_count]);
|
ret = get_tag(&fmt->tags[fmt->tag_count]);
|
||||||
|
@ -353,27 +379,79 @@ static int get_format_str(struct display_format *fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt->valid = true;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_format(const char *buf)
|
||||||
|
{
|
||||||
|
strp = buf;
|
||||||
|
|
||||||
|
if (formats[format_count] == NULL)
|
||||||
|
formats[format_count] = buffer_alloc(sizeof(struct display_format));
|
||||||
|
|
||||||
|
memset(formats[format_count], 0, sizeof(struct display_format));
|
||||||
|
if (get_format_str(formats[format_count]) < 0)
|
||||||
|
{
|
||||||
|
logf("get_format_str() parser failed!");
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*strp != '\0' && *strp != '?')
|
||||||
|
strp++;
|
||||||
|
|
||||||
|
if (*strp == '?')
|
||||||
|
{
|
||||||
|
int clause_count = 0;
|
||||||
|
strp++;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
formats[format_count]->clause[clause_count] =
|
||||||
|
buffer_alloc(sizeof(struct tagcache_search_clause));
|
||||||
|
|
||||||
|
if (!read_clause(formats[format_count]->clause[clause_count]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
clause_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
formats[format_count]->clause_count = clause_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
format_count++;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_condition(struct search_instruction *inst)
|
static int get_condition(struct search_instruction *inst)
|
||||||
{
|
{
|
||||||
int tag;
|
int clause_count;
|
||||||
int condition;
|
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
switch (*strp)
|
switch (*strp)
|
||||||
{
|
{
|
||||||
case '=':
|
case '=':
|
||||||
if (get_format_str(&inst->format[inst->tagorder_count]) < 0)
|
|
||||||
{
|
{
|
||||||
logf("get_format_str() parser failed!");
|
int i;
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
if (get_token_str(buf, sizeof buf) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < format_count; i++)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(formats[i]->name, buf))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == format_count)
|
||||||
|
{
|
||||||
|
logf("format not found: %s", buf);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
inst->format_id[inst->tagorder_count] = formats[i]->group_id;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
case '?':
|
case '?':
|
||||||
case ' ':
|
case ' ':
|
||||||
case '&':
|
case '&':
|
||||||
|
@ -384,17 +462,20 @@ static int get_condition(struct search_instruction *inst)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_tag(&tag) <= 0)
|
clause_count = inst->clause_count[inst->tagorder_count];
|
||||||
|
if (clause_count >= TAGCACHE_MAX_CLAUSES)
|
||||||
|
{
|
||||||
|
logf("Too many clauses");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inst->clause[inst->tagorder_count][clause_count] =
|
||||||
|
buffer_alloc(sizeof(struct tagcache_search_clause));
|
||||||
|
|
||||||
|
if (!read_clause(inst->clause[inst->tagorder_count][clause_count]))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (get_clause(&condition) <= 0)
|
inst->clause_count[inst->tagorder_count]++;
|
||||||
return -2;
|
|
||||||
|
|
||||||
if (get_token_str(buf, sizeof buf) < 0)
|
|
||||||
return -3;
|
|
||||||
|
|
||||||
logf("got clause: %d/%d [%s]", tag, condition, buf);
|
|
||||||
add_clause(inst, tag, condition, buf);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -465,7 +546,9 @@ static bool parse_search(struct menu_entry *entry, const char *str)
|
||||||
|
|
||||||
logf("tag: %d", inst->tagorder[inst->tagorder_count]);
|
logf("tag: %d", inst->tagorder[inst->tagorder_count]);
|
||||||
|
|
||||||
while (get_condition(inst) > 0) ;
|
while ( (ret = get_condition(inst)) > 0 ) ;
|
||||||
|
if (ret < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
inst->tagorder_count++;
|
inst->tagorder_count++;
|
||||||
|
|
||||||
|
@ -658,6 +741,13 @@ static bool parse_menu(const char *filename)
|
||||||
|
|
||||||
switch (variable)
|
switch (variable)
|
||||||
{
|
{
|
||||||
|
case var_format:
|
||||||
|
if (add_format(strp) < 0)
|
||||||
|
{
|
||||||
|
logf("Format add fail: %s", data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case var_include:
|
case var_include:
|
||||||
if (get_token_str(data, sizeof(data)) < 0)
|
if (get_token_str(data, sizeof(data)) < 0)
|
||||||
{
|
{
|
||||||
|
@ -731,9 +821,9 @@ static bool parse_menu(const char *filename)
|
||||||
menu->items[menu->itemcount] = buffer_alloc(sizeof(struct menu_entry));
|
menu->items[menu->itemcount] = buffer_alloc(sizeof(struct menu_entry));
|
||||||
memset(menu->items[menu->itemcount], 0, sizeof(struct menu_entry));
|
memset(menu->items[menu->itemcount], 0, sizeof(struct menu_entry));
|
||||||
menu->items[menu->itemcount]->si = buffer_alloc(sizeof(struct search_instruction));
|
menu->items[menu->itemcount]->si = buffer_alloc(sizeof(struct search_instruction));
|
||||||
memset(menu->items[menu->itemcount]->si, 0, sizeof(struct search_instruction));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(menu->items[menu->itemcount]->si, 0, sizeof(struct search_instruction));
|
||||||
if (!parse_search(menu->items[menu->itemcount], buf))
|
if (!parse_search(menu->items[menu->itemcount], buf))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -746,6 +836,7 @@ static bool parse_menu(const char *filename)
|
||||||
|
|
||||||
void tagtree_init(void)
|
void tagtree_init(void)
|
||||||
{
|
{
|
||||||
|
format_count = 0;
|
||||||
menu_count = 0;
|
menu_count = 0;
|
||||||
menu = NULL;
|
menu = NULL;
|
||||||
root_menu = 0;
|
root_menu = 0;
|
||||||
|
@ -852,14 +943,21 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < csi->clause_count[i]; j++)
|
for (j = 0; j < csi->clause_count[i]; j++)
|
||||||
tagcache_search_add_clause(tcs, &csi->clause[i][j]);
|
tagcache_search_add_clause(tcs, csi->clause[i][j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_offset = offset;
|
current_offset = offset;
|
||||||
current_entry_count = 0;
|
current_entry_count = 0;
|
||||||
c->dirfull = false;
|
c->dirfull = false;
|
||||||
fmt = &csi->format[level];
|
|
||||||
if (fmt->valid)
|
fmt = NULL;
|
||||||
|
for (i = 0; i < format_count; i++)
|
||||||
|
{
|
||||||
|
if (formats[i]->group_id == csi->format_id[level])
|
||||||
|
fmt = formats[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fmt)
|
||||||
{
|
{
|
||||||
sort_inverse = fmt->sort_inverse;
|
sort_inverse = fmt->sort_inverse;
|
||||||
sort_limit = fmt->limit;
|
sort_limit = fmt->limit;
|
||||||
|
@ -900,12 +998,27 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
|
||||||
else
|
else
|
||||||
dptr->extraseek = tcs->result_seek;
|
dptr->extraseek = tcs->result_seek;
|
||||||
|
|
||||||
if (!tcs->ramresult || fmt->valid)
|
fmt = NULL;
|
||||||
|
/* Check the format */
|
||||||
|
for (i = 0; i < format_count; i++)
|
||||||
|
{
|
||||||
|
if (formats[i]->group_id != csi->format_id[level])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tagcache_check_clauses(tcs, formats[i]->clause,
|
||||||
|
formats[i]->clause_count))
|
||||||
|
{
|
||||||
|
fmt = formats[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tcs->ramresult || fmt)
|
||||||
{
|
{
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
int buf_pos = 0;
|
int buf_pos = 0;
|
||||||
|
|
||||||
if (fmt->valid)
|
if (fmt)
|
||||||
{
|
{
|
||||||
char fmtbuf[8];
|
char fmtbuf[8];
|
||||||
bool read_format = false;
|
bool read_format = false;
|
||||||
|
@ -968,7 +1081,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
|
||||||
}
|
}
|
||||||
|
|
||||||
dptr->name = &c->name_buffer[namebufused];
|
dptr->name = &c->name_buffer[namebufused];
|
||||||
if (fmt->valid)
|
if (fmt)
|
||||||
namebufused += buf_pos;
|
namebufused += buf_pos;
|
||||||
else
|
else
|
||||||
namebufused += tcs->result_len;
|
namebufused += tcs->result_len;
|
||||||
|
@ -980,7 +1093,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
|
||||||
sort = false;
|
sort = false;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
if (fmt->valid)
|
if (fmt)
|
||||||
strcpy(dptr->name, buf);
|
strcpy(dptr->name, buf);
|
||||||
else
|
else
|
||||||
strcpy(dptr->name, tcs->result);
|
strcpy(dptr->name, tcs->result);
|
||||||
|
@ -1192,7 +1305,7 @@ int tagtree_enter(struct tree_context* c)
|
||||||
{
|
{
|
||||||
for (j = 0; j < csi->clause_count[i]; j++)
|
for (j = 0; j < csi->clause_count[i]; j++)
|
||||||
{
|
{
|
||||||
if (!csi->clause[i][j].input)
|
if (!csi->clause[i][j]->input)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rc = kbd_input(searchstring, sizeof(searchstring));
|
rc = kbd_input(searchstring, sizeof(searchstring));
|
||||||
|
@ -1202,11 +1315,11 @@ int tagtree_enter(struct tree_context* c)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (csi->clause[i][j].numeric)
|
if (csi->clause[i][j]->numeric)
|
||||||
csi->clause[i][j].numeric_data = atoi(searchstring);
|
csi->clause[i][j]->numeric_data = atoi(searchstring);
|
||||||
else
|
else
|
||||||
strncpy(csi->clause[i][j].str, searchstring,
|
strncpy(csi->clause[i][j]->str, searchstring,
|
||||||
sizeof(csi->clause[i][j].str)-1);
|
sizeof(csi->clause[i][j]->str)-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1297,6 +1410,7 @@ bool insert_all_playlist(struct tree_context *c, int position, bool queue)
|
||||||
int i;
|
int i;
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
int from, to, direction;
|
int from, to, direction;
|
||||||
|
int files_left = c->filesindir;
|
||||||
|
|
||||||
cpu_boost_id(true, CPUBOOSTID_TAGTREE);
|
cpu_boost_id(true, CPUBOOSTID_TAGTREE);
|
||||||
if (!tagcache_search(&tcs, tag_filename))
|
if (!tagcache_search(&tcs, tag_filename))
|
||||||
|
@ -1321,7 +1435,8 @@ bool insert_all_playlist(struct tree_context *c, int position, bool queue)
|
||||||
|
|
||||||
for (i = from; i != to; i += direction)
|
for (i = from; i != to; i += direction)
|
||||||
{
|
{
|
||||||
if (!show_search_progress(false, i))
|
/* Count back to zero */
|
||||||
|
if (!show_search_progress(false, files_left--))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!tagcache_retrieve(&tcs, tagtree_get_entry(c, i)->extraseek,
|
if (!tagcache_retrieve(&tcs, tagtree_get_entry(c, i)->extraseek,
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#define TAGNAVI_VERSION "#! rockbox/tagbrowser/2.0"
|
#define TAGNAVI_VERSION "#! rockbox/tagbrowser/2.0"
|
||||||
#define TAGMENU_MAX_ITEMS 64
|
#define TAGMENU_MAX_ITEMS 64
|
||||||
#define TAGMENU_MAX_MENUS 16
|
#define TAGMENU_MAX_MENUS 16
|
||||||
|
#define TAGMENU_MAX_FMTS 32
|
||||||
|
|
||||||
enum table { root = 1, navibrowse, allsubentries, playtrack };
|
enum table { root = 1, navibrowse, allsubentries, playtrack };
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue