From 12a963e8393f8f1be62e75398414daa5765fd8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Sun, 31 Mar 2013 13:28:02 +0200 Subject: [PATCH] Implement updating of properties from webui --- src/dvb/dvb_multiplex.c | 10 +- src/dvb/dvb_network.c | 39 +++--- src/dvb/dvb_service.c | 57 ++------- src/idnode.c | 85 +++++++++++-- src/idnode.h | 9 ++ src/prop.c | 184 ++++++++++++++++++++------- src/prop.h | 14 +- src/service.c | 16 ++- src/webui/extjs.c | 98 ++++++++++++++ src/webui/extjs_dvb.c | 45 +------ src/webui/static/app/dvb_networks.js | 68 ++++++++-- src/webui/webui.h | 5 + 12 files changed, 454 insertions(+), 176 deletions(-) diff --git a/src/dvb/dvb_multiplex.c b/src/dvb/dvb_multiplex.c index 5069549f..232670e9 100644 --- a/src/dvb/dvb_multiplex.c +++ b/src/dvb/dvb_multiplex.c @@ -65,6 +65,7 @@ static const idclass_t dvb_mux_class = { .ic_class = "dvbmux", .ic_get_title = dvb_mux_get_title, .ic_get_childs = dvb_mux_get_childs, + .ic_save = (void *)dvb_mux_save, .ic_properties = (const property_t[]){ { "enabled", "Enabled", PT_BOOL, @@ -517,6 +518,7 @@ dvb_mux_save(dvb_mux_t *dm) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_u32(m, "enabled", dm->dm_enabled); + htsmsg_add_str(m, "uuid", idnode_uuid_as_str(&dm->dm_id)); htsmsg_add_u32(m, "transportstreamid", dm->dm_transport_stream_id); htsmsg_add_u32(m, "originalnetworkid", dm->dm_network_id); @@ -727,14 +729,20 @@ dvb_mux_create_by_msg(dvb_network_t *dn, htsmsg_t *m, const char *fname) if(htsmsg_get_u32(m, "enabled", &enabled)) enabled = 1; + const char *uuid = htsmsg_get_str(m, "uuid"); dm = dvb_mux_create(dn, &dmc, onid, tsid, htsmsg_get_str(m, "network"), NULL, enabled, htsmsg_get_u32_or_default(m, "needscan", 1), - htsmsg_get_str(m, "uuid")); + uuid); if(dm != NULL) { if((s = htsmsg_get_str(m, "default_authority"))) dm->dm_default_authority = strdup(s); + + + if(uuid == NULL) + // If mux didn't have UUID, write it to make sure UUID is stable + dvb_mux_save(dm); } return NULL; } diff --git a/src/dvb/dvb_network.c b/src/dvb/dvb_network.c index 3dc45902..feca6cb6 100644 --- a/src/dvb/dvb_network.c +++ b/src/dvb/dvb_network.c @@ -25,13 +25,24 @@ #include "settings.h" #include "dvb_support.h" + +const static struct strtab typetab[] = { + {"DVB-T", FE_OFDM}, + {"DVB-C", FE_QAM}, + {"DVB-S", FE_QPSK}, + {"ATSC", FE_ATSC}, +}; + + struct dvb_network_list dvb_networks; static idnode_t **dvb_network_get_childs(struct idnode *self); +static void dvb_network_save(idnode_t *in); static const idclass_t dvb_network_class = { .ic_class = "dvbnetwork", .ic_get_childs = dvb_network_get_childs, + .ic_save = dvb_network_save, .ic_properties = (const property_t[]){ { "autodiscovery", "Auto discovery", PT_BOOL, @@ -42,11 +53,7 @@ static const idclass_t dvb_network_class = { }, { "disable_pmt_monitor", "Disable PMT monitor", PT_BOOL, offsetof(dvb_network_t, dn_disable_pmt_monitor) - }, { - "disable_pmt_monitor", "Disable PMT monitor", PT_BOOL, - offsetof(dvb_network_t, dn_disable_pmt_monitor) - }, { - }}, + }, {}}, }; /** @@ -116,15 +123,19 @@ dvb_network_get_childs(struct idnode *self) static void dvb_network_load(htsmsg_t *m, const char *uuid) { - uint32_t fetype; + const char *s = htsmsg_get_str(m, "type"); + if(s == NULL) + return; - if(htsmsg_get_u32(m, "fetype", &fetype)) + int fetype = str2val(s, typetab); + if(fetype == -1) return; dvb_network_t *dn = dvb_network_create(fetype, uuid); if(dn == NULL) return; + htsmsg_delete_field(m, "type"); prop_write_values(dn, dvb_network_class.ic_properties, m); dvb_mux_load(dn); dvb_network_schedule_initial_scan(dn); @@ -135,16 +146,19 @@ dvb_network_load(htsmsg_t *m, const char *uuid) * */ static void -dvb_network_save(dvb_network_t *dn) +dvb_network_save(idnode_t *in) { + dvb_network_t *dn = (dvb_network_t *)in; htsmsg_t *m = htsmsg_create_map(); lock_assert(&global_lock); - prop_read_values(dn, dvb_network_class.ic_properties, m); + htsmsg_add_str(m, "type", val2str(dn->dn_fe_type, typetab)); + prop_read_values(in, dvb_network_class.ic_properties, m); hts_settings_save(m, "dvb/networks/%s/config", - idnode_uuid_as_str(&dn->dn_id)); + idnode_uuid_as_str(in)); + htsmsg_destroy(m); } @@ -185,11 +199,6 @@ dvb_network_init(void) htsmsg_t *l, *c; htsmsg_field_t *f; - if(0) { - dvb_network_save(dvb_network_create(FE_QAM, NULL)); - exit(0); - } - if((l = hts_settings_load_r(1, "dvb/networks")) == NULL) return; diff --git a/src/dvb/dvb_service.c b/src/dvb/dvb_service.c index 748b445c..0fc6062a 100644 --- a/src/dvb/dvb_service.c +++ b/src/dvb/dvb_service.c @@ -175,6 +175,7 @@ dvb_service_save(service_t *t) lock_assert(&global_lock); + htsmsg_add_str(m, "uuid", idnode_uuid_as_str(&t->s_id)); htsmsg_add_u32(m, "service_id", t->s_dvb_service_id); htsmsg_add_u32(m, "pmt", t->s_pmt_pid); htsmsg_add_u32(m, "stype", t->s_servicetype); @@ -246,7 +247,8 @@ dvb_service_load(dvb_mux_t *dm) if(htsmsg_get_u32(c, "pmt", &pmt)) continue; - t = dvb_service_find(dm, sid, pmt, f->hmf_name); + const char *uuid = htsmsg_get_str(c, "uuid"); + t = dvb_service_find(dm, sid, pmt, uuid); htsmsg_get_u32(c, "stype", &t->s_servicetype); if(htsmsg_get_u32(c, "scrambled", &u32)) @@ -285,6 +287,12 @@ dvb_service_load(dvb_mux_t *dm) if(s && u32) service_map_channel(t, channel_find_by_name(s, 1, 0), 0); + + if(uuid == NULL) { + // If service config on disk lacked UUID (for whatever reason), + // write it back + dvb_service_save(t); + } } htsmsg_destroy(l); } @@ -422,53 +430,6 @@ dvb_service_find2(dvb_mux_t *dm, uint16_t sid, int pmt_pid, return t; } -#if 0 -/** - * - */ -static htsmsg_t * -dvb_service_serialize(service_t *s) -{ - dvb_mux_t *dm = s->s_dvb_mux; - htsmsg_t *m = htsmsg_create_map(); - char buf[100]; - - if(s->s_svcname) { - htsmsg_add_str(m, "text", s->s_svcname); - } else { - snprintf(buf, sizeof(buf), "Service-0x%04x", - s->s_dvb_service_id); - htsmsg_add_str(m, "text", buf); - } - - htsmsg_add_u32(m, "enabled", s->s_enabled); - htsmsg_add_u32(m, "channel", s->s_channel_number); - - htsmsg_add_u32(m, "sid", s->s_dvb_service_id); - htsmsg_add_u32(m, "pmt", s->s_pmt_pid); - htsmsg_add_u32(m, "pcr", s->s_pcr_pid); - - htsmsg_add_str(m, "type", service_servicetype_txt(s)); - - htsmsg_add_str(m, "svcname", s->s_svcname ?: ""); - htsmsg_add_str(m, "provider", s->s_provider ?: ""); - - htsmsg_add_str(m, "network", dm->dm_network_name ?: ""); - - htsmsg_add_str(m, "mux", dvb_mux_nicefreq(dm)); - - if(s->s_ch != NULL) - htsmsg_add_str(m, "channelname", s->s_ch->ch_name); - - if(s->s_dvb_charset != NULL) - htsmsg_add_str(m, "dvb_charset", s->s_dvb_charset); - - htsmsg_add_u32(m, "dvb_eit_enable", s->s_dvb_eit_enable); - - return m; -} -#endif - /** * diff --git a/src/idnode.c b/src/idnode.c index ec3211ea..9394c578 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -166,6 +166,27 @@ idnode_unlink(idnode_t *in) } +/** + * Recursive to get superclass nodes first + */ +static void +add_descriptors(struct idnode *self, const idclass_t *ic, htsmsg_t *p) +{ + if(ic->ic_super != NULL) + add_descriptors(self, ic->ic_super, p); + + if(TAILQ_FIRST(&p->hm_fields) != NULL) { + // Only add separator if not empty + htsmsg_t *m = htsmsg_create_map(); + htsmsg_add_str(m, "caption", ic->ic_caption ?: ic->ic_class); + htsmsg_add_str(m, "type", "separator"); + htsmsg_add_msg(p, NULL, m); + } + + prop_add_descriptors_to_msg(self, ic->ic_properties, p); +} + + /** * */ @@ -179,24 +200,70 @@ idnode_serialize(struct idnode *self) } else { m = htsmsg_create_map(); - htsmsg_t *p = htsmsg_create_map(); - htsmsg_t *pn = htsmsg_create_map(); - if(c->ic_get_title != NULL) { htsmsg_add_str(m, "text", c->ic_get_title(self)); } else { htsmsg_add_str(m, "text", idnode_uuid_as_str(self)); } - for(;c != NULL; c = c->ic_super) { - prop_read_values(self, c->ic_properties, p); - prop_read_names(c->ic_properties, pn); - } + htsmsg_t *p = htsmsg_create_list(); + add_descriptors(self, c, p); - htsmsg_add_msg(m, "properties", p); - htsmsg_add_msg(m, "propertynames", pn); + htsmsg_add_msg(m, "descriptors", p); htsmsg_add_str(m, "id", idnode_uuid_as_str(self)); } return m; } + +/** + * + */ +static void +idnode_save(idnode_t *in) +{ + const idclass_t *ic = in->in_class; + for(; ic != NULL; ic = ic->ic_super) { + if(ic->ic_save != NULL) { + ic->ic_save(in); + return; + } + } +} + + +/** + * + */ +void +idnode_set_prop(idnode_t *in, const char *key, const char *value) +{ + const idclass_t *ic = in->in_class; + int do_save = 0; + for(;ic != NULL; ic = ic->ic_super) { + int x = prop_set(in, ic->ic_properties, key, value); + if(x == -1) + continue; + do_save |= x; + break; + } + if(do_save) + idnode_save(in); +} + + +/** + * + */ +void +idnode_update_all_props(idnode_t *in, + const char *(*getvalue)(void *opaque, const char *key), + void *opaque) +{ + const idclass_t *ic = in->in_class; + int do_save = 0; + for(;ic != NULL; ic = ic->ic_super) + do_save |= prop_update_all(in, ic->ic_properties, getvalue, opaque); + if(do_save) + idnode_save(in); +} diff --git a/src/idnode.h b/src/idnode.h index a5a0901b..a71b8828 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -9,9 +9,11 @@ struct idnode; typedef struct idclass { const struct idclass *ic_super; const char *ic_class; + const char *ic_caption; struct htsmsg *(*ic_serialize)(struct idnode *self); struct idnode **(*ic_get_childs)(struct idnode *self); const char *(*ic_get_title)(struct idnode *self); + void (*ic_save)(struct idnode *self); const property_t *ic_properties; } idclass_t; @@ -33,3 +35,10 @@ void *idnode_find(const char *uuid, const idclass_t *class); void idnode_unlink(idnode_t *in); htsmsg_t *idnode_serialize(struct idnode *self); + +void idnode_set_prop(idnode_t *in, const char *key, const char *value); + +void idnode_update_all_props(idnode_t *in, + const char *(*getvalue)(void *opaque, + const char *key), + void *opaque); diff --git a/src/prop.c b/src/prop.c index d148b43a..559130dc 100644 --- a/src/prop.c +++ b/src/prop.c @@ -7,13 +7,33 @@ + +/** + * + */ +static int +str_to_bool(const char *s) +{ + if(s == NULL) + return 0; + int v = atoi(s); + if(v) + return 1; + if(!strcasecmp(s, "on") || + !strcasecmp(s, "true") || + !strcasecmp(s, "yes")) + return 1; + return 0; +} + + static const property_t * prop_find(const property_t *p, const char *id) { - int i; + int i = 0; for(;p[i].id; i++) if(!strcmp(id, p[i].id)) - return p; + return p + i; return NULL; } @@ -63,68 +83,142 @@ prop_write_values(void *obj, const property_t *pl, htsmsg_t *m) /** * */ -void -prop_read_values(void *obj, const property_t *p, htsmsg_t *m) +static void +prop_read_value(void *obj, const property_t *p, htsmsg_t *m, const char *name) { const char *s; - if(p == NULL) - return; - int i = 0; - for(;p[i].id; i++) { - void *val = obj + p[i].off; - switch(p[i].type) { - case PT_BOOL: - htsmsg_add_bool(m, p[i].id, *(int *)val); - break; - case PT_INT: - htsmsg_add_s32(m, p[i].id, *(int *)val); - break; - case PT_STR: - if(p->str_get != NULL) - s = p->str_get(obj); - else - s = *(const char **)val; - if(s != NULL) - htsmsg_add_str(m, p[i].id, s); - break; - } + const void *val = obj + p->off; + + switch(p->type) { + case PT_BOOL: + htsmsg_add_bool(m, name, *(int *)val); + break; + case PT_INT: + htsmsg_add_s32(m, name, *(int *)val); + break; + case PT_STR: + if(p->str_get != NULL) + s = p->str_get(obj); + else + s = *(const char **)val; + if(s != NULL) + htsmsg_add_str(m, name, s); + break; } } - -/** - * - */ -htsmsg_t * -prop_get_values(void *ptr, const property_t *p) -{ - htsmsg_t *m = htsmsg_create_map(); - prop_read_values(ptr, p, m); - return m; -} - - /** * */ void -prop_read_names(const property_t *p, htsmsg_t *m) +prop_read_values(void *obj, const property_t *p, htsmsg_t *m) { if(p == NULL) return; int i = 0; for(;p[i].id; i++) - htsmsg_add_str(m, p[i].id, p[i].name); + prop_read_value(obj, p+i, m, p[i].id); } /** * */ -htsmsg_t * -prop_get_names(const property_t *p) +const static struct strtab typetab[] = { + { "bool", PT_BOOL }, + { "int", PT_INT }, + { "str", PT_STR }, +}; + + +/** + * + */ +void +prop_add_descriptors_to_msg(void *obj, const property_t *p, htsmsg_t *msg) { - htsmsg_t *m = htsmsg_create_map(); - prop_read_names(p, m); - return m; + if(p == NULL) + return; + int i = 0; + for(;p[i].id; i++) { + htsmsg_t *m = htsmsg_create_map(); + htsmsg_add_str(m, "id", p[i].id); + htsmsg_add_str(m, "caption", p[i].name); + htsmsg_add_str(m, "type", val2str(p[i].type, typetab) ?: "unknown"); + prop_read_value(obj, p+i, m, "value"); + htsmsg_add_msg(msg, NULL, m); + } +} + + +/** + * value can be NULL + * + * Return 1 if we actually changed something + */ +static int +prop_seti(void *obj, const property_t *p, const char *value) +{ + int i32; + const char *s; + + void *val = obj + p->off; + switch(p->type) { + + case PT_BOOL: + i32 = str_to_bool(value); + if(0) + case PT_INT: + i32 = value ? atoi(value) : 0; + if(*(int *)val == i32) + return 0; // Already set + *(int *)val = i32; + break; + + case PT_STR: + if(p->str_get != NULL) + s = p->str_get(obj); + else + s = *(const char **)val; + + if(!strcmp(s ?: "", value ?: "")) + return 0; + + if(p->str_set != NULL) + p->str_set(obj, value); + else + mystrset(val, value); + break; + } + + return 1; + +} + + +/** + * Return 1 if something changed + */ +int +prop_set(void *obj, const property_t *p, const char *key, const char *value) +{ + if((p = prop_find(p, key)) == NULL) + return -1; + return prop_seti(obj, p, value); +} + + +/** + * + */ +int +prop_update_all(void *obj, const property_t *p, + const char *(*getvalue)(void *opaque, const char *key), + void *opaque) +{ + int i = 0; + int r = 0; + for(; p[i].id; i++) + r |= prop_seti(obj, p+i, getvalue(opaque, p[i].id)); + return r; } diff --git a/src/prop.h b/src/prop.h index 4bfd89b2..178bb287 100644 --- a/src/prop.h +++ b/src/prop.h @@ -22,8 +22,14 @@ typedef struct property { -void prop_read_values(void *ptr, const property_t *p, htsmsg_t *m); -htsmsg_t *prop_get_values(void *ptr, const property_t *p); -void prop_read_names(const property_t *p, htsmsg_t *m); -htsmsg_t *prop_get_names(const property_t *p); +void prop_add_descriptors_to_msg(void *obj, const property_t *p, htsmsg_t *msg); + void prop_write_values(void *ptr, const property_t *pl, htsmsg_t *m); + +void prop_read_values(void *obj, const property_t *p, htsmsg_t *m); + +int prop_set(void *obj, const property_t *p, const char *key, const char *val); + +int prop_update_all(void *obj, const property_t *p, + const char *(*getvalue)(void *opaque, const char *key), + void *opaque); diff --git a/src/service.c b/src/service.c index 4e12c045..e93da9af 100644 --- a/src/service.c +++ b/src/service.c @@ -52,10 +52,12 @@ static void service_data_timeout(void *aux); static const char *service_channel_get(void *obj); static void service_channel_set(void *obj, const char *str); - +static void service_save(struct idnode *self); const idclass_t service_class = { .ic_class = "service", + .ic_caption = "Service", + .ic_save = service_save, .ic_properties = (const property_t[]){ { "channel", "Channel", PT_STR, @@ -675,7 +677,7 @@ static const char *service_channel_get(void *obj) static void service_channel_set(void *obj, const char *str) { - service_map_channel(obj, str ? channel_find_by_name(str, 1, 0) : NULL, 1); + service_map_channel(obj, str ? channel_find_by_name(str, 1, 0) : NULL, 0); } @@ -931,6 +933,16 @@ service_request_save(service_t *t, int restart) } +/** + * + */ +static void +service_save(struct idnode *self) +{ + service_t *s = (service_t *)self; + s->s_config_save(s); +} + /** * */ diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 841840b8..4f8e3bac 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -1900,6 +1900,103 @@ extjs_config(http_connection_t *hc, const char *remain, void *opaque) return 0; } + +/** + * + */ +int +extjs_get_idnode(http_connection_t *hc, const char *remain, void *opaque, + idnode_t **(*rootfn)(void)) +{ + htsbuf_queue_t *hq = &hc->hc_reply; + const char *s = http_arg_get(&hc->hc_req_args, "node"); + htsmsg_t *out = NULL; + + if(s == NULL) + return HTTP_STATUS_BAD_REQUEST; + + pthread_mutex_lock(&global_lock); + + if(http_access_verify(hc, ACCESS_ADMIN)) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_UNAUTHORIZED; + } + + out = htsmsg_create_list(); + idnode_t **v; + + if(!strcmp(s, "root")) { + v = rootfn(); + } else { + idnode_t *n = idnode_find(s, NULL); + v = n != NULL && n->in_class->ic_get_childs != NULL ? + n->in_class->ic_get_childs(n) : NULL; + } + + if(v != NULL) { + int i; + for(i = 0; v[i] != NULL; i++) { + htsmsg_t *m = idnode_serialize(v[i]); + if(v[i]->in_class->ic_get_childs == NULL) + htsmsg_add_u32(m, "leaf", 1); + htsmsg_add_msg(out, NULL, m); + } + } + + pthread_mutex_unlock(&global_lock); + + free(v); + + htsmsg_json_serialize(out, hq, 0); + htsmsg_destroy(out); + http_output_content(hc, "text/x-json; charset=UTF-8"); + return 0; +} + + +static const char * +get_prop_value(void *opaque, const char *key) +{ + http_connection_t *hc = opaque; + return http_arg_get(&hc->hc_req_args, key); +} + +/** + * + */ +static int +extjs_item_update(http_connection_t *hc, const char *remain, void *opaque) +{ + htsbuf_queue_t *hq = &hc->hc_reply; + htsmsg_t *out = NULL; + + if(remain == NULL) + return HTTP_STATUS_BAD_REQUEST; + + pthread_mutex_lock(&global_lock); + + idnode_t *n = idnode_find(remain, NULL); + + if(n == NULL) { + pthread_mutex_unlock(&global_lock); + return 404; + } + + idnode_update_all_props(n, get_prop_value, hc); + + pthread_mutex_unlock(&global_lock); + + out = htsmsg_create_map(); + htsmsg_add_u32(out, "success", 1); + htsmsg_json_serialize(out, hq, 0); + htsmsg_destroy(out); + http_output_content(hc, "text/x-json; charset=UTF-8"); + return 0; +} + + + + /** * WEB user interface */ @@ -1926,6 +2023,7 @@ extjs_start(void) http_path_add("/iptv/services", NULL, extjs_iptvservices, ACCESS_ADMIN); http_path_add("/servicedetails", NULL, extjs_servicedetails, ACCESS_ADMIN); http_path_add("/tv/adapter", NULL, extjs_tvadapter, ACCESS_ADMIN); + http_path_add("/item/update", NULL, extjs_item_update, ACCESS_ADMIN); #if ENABLE_LINUXDVB extjs_start_dvb(); diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index e3a3bd18..4173b425 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -684,53 +684,10 @@ extjs_list_dvb_adapters(htsmsg_t *array) static int extjs_dvbnetworks(http_connection_t *hc, const char *remain, void *opaque) { - htsbuf_queue_t *hq = &hc->hc_reply; - const char *s = http_arg_get(&hc->hc_req_args, "node"); - htsmsg_t *out = NULL; - - if(s == NULL) - return HTTP_STATUS_BAD_REQUEST; - - pthread_mutex_lock(&global_lock); - - if(http_access_verify(hc, ACCESS_ADMIN)) { - pthread_mutex_unlock(&global_lock); - return HTTP_STATUS_UNAUTHORIZED; - } - - out = htsmsg_create_list(); - idnode_t **v; - - if(!strcmp(s, "root")) { - v = dvb_network_root(); - } else { - idnode_t *n = idnode_find(s, NULL); - v = n != NULL && n->in_class->ic_get_childs != NULL ? - n->in_class->ic_get_childs(n) : NULL; - } - - if(v != NULL) { - int i; - for(i = 0; v[i] != NULL; i++) { - htsmsg_t *m = idnode_serialize(v[i]); - if(v[i]->in_class->ic_get_childs == NULL) - htsmsg_add_u32(m, "leaf", 1); - htsmsg_add_msg(out, NULL, m); - } - } - - pthread_mutex_unlock(&global_lock); - - free(v); - - htsmsg_json_serialize(out, hq, 0); - htsmsg_destroy(out); - http_output_content(hc, "text/x-json; charset=UTF-8"); - return 0; + return extjs_get_idnode(hc, remain, opaque, &dvb_network_root); } - /** * DVB WEB user interface */ diff --git a/src/webui/static/app/dvb_networks.js b/src/webui/static/app/dvb_networks.js index be0ecab6..ee028417 100644 --- a/src/webui/static/app/dvb_networks.js +++ b/src/webui/static/app/dvb_networks.js @@ -1,14 +1,66 @@ - - tvheadend.item_editor = function(item) { - var propsGrid = new Ext.grid.PropertyGrid({ - flex:1, - padding: 5, - propertyNames: item.propertynames, - source: item.properties + + var fields = [] + console.log(fields); + for (var idx in item.descriptors) { + var f = item.descriptors[idx]; + switch(f.type) { + case 'str': + fields.push({ + fieldLabel: f.caption, + name: f.id, + value: f.value + }); + break; + + case 'bool': + fields.push({ + xtype: 'checkbox', + fieldLabel: f.caption, + name: f.id, + checked: f.value + }); + break; + + case 'separator': + fields.push({ + xtype: 'label', + fieldLabel: f.caption, + }); + break; + } + } + + var panel = new Ext.FormPanel({ + labelWidth: 75, // label settings here cascade unless overridden + url:'save-form.php', + frame:true, + title: 'Parameters', + bodyStyle:'padding:5px 5px 0', + width: 350, + defaults: {width: 230}, + defaultType: 'textfield', + items: fields, + + buttons: [{ + text: 'Save', + handler: function(){ + if(panel.getForm().isValid()){ + panel.getForm().submit({ + url: 'item/update/' + item.id, + waitMsg : 'Saving Data...' + }); + } + } + },{ + text: 'Reset', + handler: function(){ + panel.getForm().reset(); + } + }] }); - return propsGrid; + return panel; } diff --git a/src/webui/webui.h b/src/webui/webui.h index cbbec569..300d32f6 100644 --- a/src/webui/webui.h +++ b/src/webui/webui.h @@ -20,6 +20,8 @@ #define WEBUI_H_ #include "htsmsg.h" +#include "idnode.h" +#include "http.h" void webui_init(void); @@ -45,6 +47,9 @@ void extjs_service_update(htsmsg_t *in); void extjs_service_delete(htsmsg_t *in); +int extjs_get_idnode(http_connection_t *hc, const char *remain, void *opaque, + idnode_t **(*rootfn)(void)); + /** * */