From 16699deaf9b1cb36f3513709953dee615a65afff Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Mon, 1 Jul 2013 12:51:31 +0100 Subject: [PATCH] linuxdvb webui: starting to get a very rough editor for satconf This is still very crap, but if I can get "something" it'll be better than nothing at this stage. --- src/input/mpegts/linuxdvb/linuxdvb_lnb.c | 5 +- src/input/mpegts/linuxdvb/linuxdvb_private.h | 13 ++- src/input/mpegts/linuxdvb/linuxdvb_rotor.c | 14 ++- src/input/mpegts/linuxdvb/linuxdvb_satconf.c | 60 +++++++++- src/input/mpegts/linuxdvb/linuxdvb_switch.c | 7 +- src/prop.c | 3 + src/webui/extjs.c | 30 +++++ src/webui/static/app/idnode.js | 110 +++++++++++++------ src/webui/static/app/mpegts.js | 3 +- 9 files changed, 194 insertions(+), 51 deletions(-) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c index afa61a06..f71f57f6 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c @@ -44,8 +44,11 @@ typedef struct linuxdvb_lnb_conf int lnb_switch; } linuxdvb_lnb_conf_t; +extern const idclass_t linuxdvb_diseqc_class; + const idclass_t linuxdvb_lnb_class = { + .ic_super = &linuxdvb_diseqc_class, .ic_class = "linuxdvb_lnb_basic", .ic_caption = "LNB", }; @@ -220,7 +223,7 @@ linuxdvb_lnb_list ( void *o ) linuxdvb_lnb_t * linuxdvb_lnb_create0 - ( const char *name, htsmsg_t *conf ) + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ) { int i; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 3905c125..ebe709c9 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -230,6 +230,7 @@ struct linuxdvb_diseqc { idnode_t ld_id; const char *ld_type; + linuxdvb_satconf_t *ld_satconf; int (*ld_grace) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm); int (*ld_tune) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, linuxdvb_satconf_t *ls, int fd); @@ -243,20 +244,20 @@ struct linuxdvb_lnb linuxdvb_diseqc_t *linuxdvb_diseqc_create0 ( linuxdvb_diseqc_t *ld, const char *uuid, const idclass_t *idc, - htsmsg_t *conf, const char *type ); + htsmsg_t *conf, const char *type, linuxdvb_satconf_t *parent ); void linuxdvb_diseqc_destroy ( linuxdvb_diseqc_t *ld ); -#define linuxdvb_diseqc_create(_d, _u, _c, _t)\ +#define linuxdvb_diseqc_create(_d, _u, _c, _t, _p)\ linuxdvb_diseqc_create0(calloc(1, sizeof(struct _d)),\ - _u, &_d##_class, _c, _t) + _u, &_d##_class, _c, _t, _p) linuxdvb_lnb_t *linuxdvb_lnb_create0 - ( const char *name, htsmsg_t *conf ); + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ); linuxdvb_diseqc_t *linuxdvb_switch_create0 - ( const char *name, htsmsg_t *conf ); + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ); linuxdvb_diseqc_t *linuxdvb_rotor_create0 - ( const char *name, htsmsg_t *conf ); + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ); void linuxdvb_lnb_destroy ( linuxdvb_lnb_t *lnb ); void linuxdvb_switch_destroy ( linuxdvb_diseqc_t *ld ); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index f83cd11e..35a7e61b 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -50,8 +50,17 @@ typedef struct linuxdvb_rotor } linuxdvb_rotor_t; +extern const idclass_t linuxdvb_diseqc_class; + +const idclass_t linuxdvb_rotor_class = { + .ic_super = &linuxdvb_diseqc_class, + .ic_class = "linuxdvb_rotor", + .ic_caption = "DiseqC Rotor", +}; + const idclass_t linuxdvb_rotor_gotox_class = { + .ic_super = &linuxdvb_rotor_class, .ic_class = "linuxdvb_rotor_gotox", .ic_caption = "GOTOX Rotor", .ic_properties = (const property_t[]) { @@ -73,6 +82,7 @@ const idclass_t linuxdvb_rotor_gotox_class = const idclass_t linuxdvb_rotor_usals_class = { + .ic_super = &linuxdvb_rotor_class, .ic_class = "linuxdvb_rotor_usals", .ic_caption = "USALS Rotor", .ic_properties = (const property_t[]) { @@ -256,7 +266,7 @@ linuxdvb_rotor_list ( void *o ) linuxdvb_diseqc_t * linuxdvb_rotor_create0 - ( const char *name, htsmsg_t *conf ) + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ) { int i; linuxdvb_diseqc_t *ld = NULL; @@ -265,7 +275,7 @@ linuxdvb_rotor_create0 if (!strcmp(name ?: "", linuxdvb_rotor_all[i].name)) { ld = linuxdvb_diseqc_create0(calloc(1, sizeof(linuxdvb_rotor_t)), NULL, linuxdvb_rotor_all[i].idc, conf, - linuxdvb_rotor_all[i].name); + linuxdvb_rotor_all[i].name, ls); if (ld) { ld->ld_tune = linuxdvb_rotor_tune; ld->ld_grace = linuxdvb_rotor_grace; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 80ed17cb..81f139f6 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -174,7 +174,7 @@ linuxdvb_satconf_class_lnbtype_set ( void *o, const void *p ) if (ls->ls_lnb && !strcmp(str ?: "", ls->ls_lnb->ld_type)) return 0; if (ls->ls_lnb) linuxdvb_lnb_destroy(ls->ls_lnb); - ls->ls_lnb = linuxdvb_lnb_create0(str, NULL); + ls->ls_lnb = linuxdvb_lnb_create0(str, NULL, ls); return 0; } @@ -195,7 +195,7 @@ linuxdvb_satconf_class_switchtype_set ( void *o, const void *p ) if (ls->ls_switch && !strcmp(str ?: "", ls->ls_switch->ld_type)) return 0; if (ls->ls_switch) linuxdvb_switch_destroy(ls->ls_switch); - ls->ls_switch = linuxdvb_switch_create0(str, NULL); + ls->ls_switch = linuxdvb_switch_create0(str, NULL, ls); return 0; } @@ -216,7 +216,7 @@ linuxdvb_satconf_class_rotortype_set ( void *o, const void *p ) if (ls->ls_rotor && !strcmp(str ?: "", ls->ls_rotor->ld_type)) return 0; if (ls->ls_rotor) linuxdvb_rotor_destroy(ls->ls_rotor); - ls->ls_rotor = linuxdvb_rotor_create0(str, NULL); + ls->ls_rotor = linuxdvb_rotor_create0(str, NULL, ls); return 0; } @@ -229,12 +229,36 @@ linuxdvb_satconf_class_rotortype_get ( void *o ) return &s; } +static const char * +linuxdvb_satconf_class_get_title ( idnode_t *o ) +{ + static char buf[128]; + linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)o; + ls->mi_display_name((mpegts_input_t*)ls, buf, sizeof(buf)); + return buf; +} + +static idnode_set_t * +linuxdvb_satconf_class_get_childs ( idnode_t *o ) +{ + linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)o; + idnode_set_t *is = idnode_set_create(); + if (ls->ls_lnb) + idnode_set_add(is, &ls->ls_lnb->ld_id, NULL); + if (ls->ls_switch) + idnode_set_add(is, &ls->ls_switch->ld_id, NULL); + if (ls->ls_rotor) + idnode_set_add(is, &ls->ls_rotor->ld_id, NULL); + return is; +} + const idclass_t linuxdvb_satconf_class = { .ic_super = &mpegts_input_class, .ic_class = "linuxdvb_satconf", .ic_caption = "Linux DVB Satconf", - //.ic_get_title = linuxdvb_satconf_class_get_title, + .ic_get_title = linuxdvb_satconf_class_get_title, + .ic_get_childs = linuxdvb_satconf_class_get_childs, .ic_save = linuxdvb_satconf_class_save, .ic_properties = (const property_t[]) { { @@ -564,10 +588,33 @@ void linuxdvb_satconf_init ( void ) } } +static const char * +linuxdvb_diseqc_class_get_title ( idnode_t *o ) +{ + linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; + return ld->ld_type; +} + +static void +linuxdvb_diseqc_class_save ( idnode_t *o ) +{ + linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; + if (ld->ld_satconf) + linuxdvb_satconf_class_save(&ld->ld_satconf->mi_id); +} + +const idclass_t linuxdvb_diseqc_class = +{ + .ic_class = "linuxdvb_diseqc", + .ic_caption = "DiseqC", + .ic_get_title = linuxdvb_diseqc_class_get_title, + .ic_save = linuxdvb_diseqc_class_save, +}; + linuxdvb_diseqc_t * linuxdvb_diseqc_create0 ( linuxdvb_diseqc_t *ld, const char *uuid, const idclass_t *idc, - htsmsg_t *conf, const char *type ) + htsmsg_t *conf, const char *type, linuxdvb_satconf_t *parent ) { /* Insert */ if (idnode_insert(&ld->ld_id, uuid, idc)) { @@ -576,7 +623,8 @@ linuxdvb_diseqc_create0 } assert(type != NULL); - ld->ld_type = strdup(type); + ld->ld_type = strdup(type); + ld->ld_satconf = parent; /* Load config */ if (conf) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_switch.c b/src/input/mpegts/linuxdvb/linuxdvb_switch.c index d33d84a4..9c7aebc7 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_switch.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_switch.c @@ -65,8 +65,11 @@ linuxdvb_switch_class_toneburst_list ( void *o ) return m; } +extern const idclass_t linuxdvb_diseqc_class; + const idclass_t linuxdvb_switch_class = { + .ic_super = &linuxdvb_diseqc_class, .ic_class = "linuxdvb_switch", .ic_caption = "DiseqC switch", .ic_properties = (const property_t[]) { @@ -163,11 +166,11 @@ linuxdvb_switch_list ( void *o ) linuxdvb_diseqc_t * linuxdvb_switch_create0 - ( const char *name, htsmsg_t *conf ) + ( const char *name, htsmsg_t *conf, linuxdvb_satconf_t *ls ) { linuxdvb_diseqc_t *ld = NULL; if (!strcmp(name ?: "", "Generic")) { - ld = linuxdvb_diseqc_create(linuxdvb_switch, NULL, conf, "Generic"); + ld = linuxdvb_diseqc_create(linuxdvb_switch, NULL, conf, "Generic", ls); if (ld) { ld->ld_tune = linuxdvb_switch_tune; } diff --git a/src/prop.c b/src/prop.c index ee0e8646..c238ffc8 100644 --- a/src/prop.c +++ b/src/prop.c @@ -83,6 +83,9 @@ prop_write_values(void *obj, const property_t *pl, htsmsg_t *m, int optmask) { int save = 0; htsmsg_field_t *f; + + if (!pl) return 0; + HTSMSG_FOREACH(f, m) { if(f->hmf_name == NULL) continue; diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 7a90b687..59635d16 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -2174,8 +2174,18 @@ extjs_idnode (http_connection_t *hc, const char *remain, void *opaque) { htsbuf_queue_t *hq = &hc->hc_reply; + int isroot = 0; const char *uuid = http_arg_get(&hc->hc_req_args, "uuid"); const char *op = http_arg_get(&hc->hc_req_args, "op"); + const char *root = http_arg_get(&hc->hc_req_args, "root"); + if (uuid == NULL) + uuid = http_arg_get(&hc->hc_req_args, "node"); + if (!strcmp(uuid, "root")) { + isroot = 1; + uuid = root; + } + if (op == NULL) + op = "get"; htsmsg_t *out = NULL; idnode_t *node; @@ -2208,12 +2218,32 @@ extjs_idnode htsmsg_destroy(conf); } out = htsmsg_create_map(); + } else if (!strcmp(op, "childs")) { + out = htsmsg_create_list(); + if (isroot) { + htsmsg_t *m = idnode_serialize(node); + htsmsg_add_u32(m, "leaf", idnode_is_leaf(node)); + htsmsg_add_msg(out, NULL, m); + } else { + idnode_set_t *v; + if ((v = idnode_get_childs(node))) { + int i; + for(i = 0; i < v->is_count; i++) { + htsmsg_t *m = idnode_serialize(v->is_array[i]); + htsmsg_add_u32(m, "leaf", idnode_is_leaf(v->is_array[i])); + htsmsg_add_msg(out, NULL, m); + } + idnode_set_free(v); + } + } } pthread_mutex_unlock(&global_lock); if (!out) return HTTP_STATUS_BAD_REQUEST; +printf("IDNODE: %s %s\n", uuid, op); +htsmsg_print(out); htsmsg_json_serialize(out, hq, 0); htsmsg_destroy(out); diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index db472dbb..c52fff37 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -52,6 +52,7 @@ tvheadend.idnode_editor_field = function(f, create) width : 300 }); } + break; case 'bool': return new Ext.form.Checkbox({ @@ -60,18 +61,39 @@ tvheadend.idnode_editor_field = function(f, create) checked : f.value, disabled : d }); + break; case 'int': case 'u32': case 'u16': case 'dbl': - return new Ext.form.NumberField({ - fieldLabel : f.caption, - name : f.id, - value : f.value, - disabled : d, - width : 300 - }); + if (f.enum) { + var store = f.enum; + return new Ext.form.ComboBox({ + fieldLabel : f.caption, + name : f.id, + value : f.value, + disabled : d, + width : 300, + mode : 'local', + valueField : 'key', + displayField : 'val', + store : store, + typeAhead : true, + forceSelection : true, + triggerAction : 'all', + emptyText :'Select ' + f.caption +' ...' + }); + } else { + return new Ext.form.NumberField({ + fieldLabel : f.caption, + name : f.id, + value : f.value, + disabled : d, + width : 300 + }); + } + break; /* case 'separator': @@ -391,29 +413,49 @@ tvheadend.idnode_grid = function(panel, conf) text : 'Edit', disabled : true, handler : function() { - r = select.getSelected(); + var r = select.getSelected(); if (r) { - Ext.Ajax.request({ - url : 'api/idnode', - params : { - op: 'get', - uuid: r.id - }, - success : function(d) - { - d = json_decode(d); - p = tvheadend.idnode_editor(d[0], {}); - w = new Ext.Window({ - title : 'Add ' + conf.titleS, - layout : 'fit', - autoWidth : true, - autoHeight : true, - plain : true, - items : p - }); - w.show(); - } - }); + if (conf.edittree) { + var p = tvheadend.idnode_tree({ + url : 'api/idnode', + params : { + op : 'childs', + root : r.id + } + }); + p.setSize(800,600); + var w = new Ext.Window({ + title : 'Edit ' + conf.titleS, + layout : 'fit', + autoWidth : true, + autoHeight : true, + plain : true, + items : p + }); + w.show(); + } else { + Ext.Ajax.request({ + url : 'api/idnode', + params : { + op: 'get', + uuid: r.id + }, + success : function(d) + { + d = json_decode(d); + var p = tvheadend.idnode_editor(d[0], {}); + var w = new Ext.Window({ + title : 'Edit ' + conf.titleS, + layout : 'fit', + autoWidth : true, + autoHeight : true, + plain : true, + items : p + }); + w.show(); + } + }); + } } } }); @@ -474,7 +516,9 @@ tvheadend.idnode_tree = function (conf) var current = null; var loader = new Ext.tree.TreeLoader({ - dataUrl : conf.url + dataUrl : conf.url, + baseParams : conf.params, + preloadChildren : conf.preload, }); var tree = new Ext.tree.TreePanel({ @@ -482,8 +526,8 @@ tvheadend.idnode_tree = function (conf) flex : 1, border : false, root : new Ext.tree.AsyncTreeNode({ - id : 'root', - text : conf.title + id : conf.root || 'root', + text : conf.title || '' }), listeners : { click: function(n) { @@ -512,7 +556,7 @@ tvheadend.idnode_tree = function (conf) var panel = new Ext.Panel({ - title : conf.title, + title : conf.title || '', layout : 'hbox', flex : 1, padding : 5, diff --git a/src/webui/static/app/mpegts.js b/src/webui/static/app/mpegts.js index 489e52e4..48cfa884 100644 --- a/src/webui/static/app/mpegts.js +++ b/src/webui/static/app/mpegts.js @@ -86,6 +86,7 @@ tvheadend.satconfs = function(panel) op: 'class' } }, - del : true + del : true, + edittree : true, }); }