idnode prop: make it possible to properly sort/filter enum/list types
This does require a certain level of extra input from prop_t users where the type is enumerated. A new routine rend() must be implemented to provide the rendered value (for lists that are not enum, this is done transparently).
This commit is contained in:
parent
dc598f8521
commit
887f00856a
2 changed files with 43 additions and 7 deletions
45
src/idnode.c
45
src/idnode.c
|
@ -126,7 +126,6 @@ idnode_init(void)
|
|||
{
|
||||
pthread_t tid;
|
||||
|
||||
|
||||
randfd = open("/dev/urandom", O_RDONLY);
|
||||
if(randfd == -1)
|
||||
exit(1);
|
||||
|
@ -301,6 +300,23 @@ idnode_find_prop
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get display value
|
||||
*/
|
||||
static char *
|
||||
idnode_get_display
|
||||
( idnode_t *self, const property_t *p )
|
||||
{
|
||||
if (p->rend)
|
||||
return p->rend(self);
|
||||
if (p->islist) {
|
||||
htsmsg_t *l = (htsmsg_t*)p->get(self);
|
||||
if (l)
|
||||
return htsmsg_list_2_csv(l);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get field as string
|
||||
*/
|
||||
|
@ -329,6 +345,7 @@ idnode_get_u32
|
|||
( idnode_t *self, const char *key, uint32_t *u32 )
|
||||
{
|
||||
const property_t *p = idnode_find_prop(self, key);
|
||||
if (p->islist) return 1;
|
||||
if (p) {
|
||||
const void *ptr;
|
||||
if (p->get)
|
||||
|
@ -361,6 +378,7 @@ idnode_get_bool
|
|||
( idnode_t *self, const char *key, int *b )
|
||||
{
|
||||
const property_t *p = idnode_find_prop(self, key);
|
||||
if (p->islist) return 1;
|
||||
if (p) {
|
||||
void *ptr = self;
|
||||
ptr += p->off;
|
||||
|
@ -446,17 +464,32 @@ idnode_cmp_sort
|
|||
idnode_t *inb = *(idnode_t**)b;
|
||||
idnode_sort_t *sort = s;
|
||||
const property_t *p = idnode_find_prop(ina, sort->key);
|
||||
if (!p) return 0;
|
||||
|
||||
/* Get display string */
|
||||
if (p->islist || p->list) {
|
||||
int r;
|
||||
char *stra = idnode_get_display(ina, p);
|
||||
char *strb = idnode_get_display(inb, p);
|
||||
if (sort->dir == IS_ASC)
|
||||
r = strcmp(stra ?: "", strb ?: "");
|
||||
else
|
||||
r = strcmp(strb ?: "", stra ?: "");
|
||||
free(stra);
|
||||
free(strb);
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (p->type) {
|
||||
case PT_STR:
|
||||
{
|
||||
int r;
|
||||
char *stra = strdup(idnode_get_str(ina, sort->key) ?: "");
|
||||
const char *stra = idnode_get_str(ina, sort->key);
|
||||
const char *strb = idnode_get_str(inb, sort->key);
|
||||
if (sort->dir == IS_ASC)
|
||||
r = strcmp(stra ?: "", strb ?: "");
|
||||
else
|
||||
r = strcmp(strb ?: "", stra ?: "");
|
||||
free(stra);
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
|
@ -490,8 +523,10 @@ idnode_filter
|
|||
LIST_FOREACH(f, filter, link) {
|
||||
if (f->type == IF_STR) {
|
||||
const char *str;
|
||||
if (!(str = idnode_get_str(in, f->key)))
|
||||
return 1;
|
||||
str = idnode_get_display(in, idnode_find_prop(in, f->key));
|
||||
if (!str)
|
||||
if (!(str = idnode_get_str(in, f->key)))
|
||||
return 1;
|
||||
switch(f->comp) {
|
||||
case IC_IN:
|
||||
if (strstr(str, f->u.s) == NULL)
|
||||
|
|
|
@ -59,8 +59,9 @@ typedef struct property {
|
|||
const void *(*get) (void *ptr);
|
||||
int (*set) (void *ptr, const void *v);
|
||||
htsmsg_t *(*list) (void *ptr);
|
||||
// Note: htsmsg_t can either be a string list or object list
|
||||
// where the object has "key" and "val" fields
|
||||
char *(*rend) (void *ptr); ///< Provide the rendered value for enum/list
|
||||
///< Lists should be CSV. This is used for
|
||||
///< sorting and searching in UI API
|
||||
|
||||
/* Notification callback */
|
||||
void (*notify) (void *ptr);
|
||||
|
|
Loading…
Add table
Reference in a new issue