From: Jaroslav Kysela Date: Fri, 4 Dec 2015 09:08:49 +0000 (+0100) Subject: wizard: more work - add icon+text, and activate tabs according the configuration... X-Git-Tag: v4.2.1~1376 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=605fd6b74a03a130007c70f25348c67568a72fd4;p=thirdparty%2Ftvheadend.git wizard: more work - add icon+text, and activate tabs according the configuration phase! --- diff --git a/src/api/api_wizard.c b/src/api/api_wizard.c index e77bf740a..e30218c36 100644 --- a/src/api/api_wizard.c +++ b/src/api/api_wizard.c @@ -49,17 +49,31 @@ wizard_idnode_save_simple } static int -wizard_cancel - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) +wizard_page + ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp, const char *page ) { pthread_mutex_lock(&global_lock); free(config.wizard); - config.wizard = strdup(""); + config.wizard = strdup(page); config_save(); pthread_mutex_unlock(&global_lock); return 0; } +static int +wizard_cancel + ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) +{ + return wizard_page(perm, opaque, op, args, resp, ""); +} + +static int +wizard_start + ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) +{ + return wizard_page(perm, opaque, op, args, resp, "hello"); +} + void api_wizard_init ( void ) { @@ -74,6 +88,7 @@ api_wizard_init ( void ) { "wizard/status/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_status }, { "wizard/mapping/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_mapping }, { "wizard/mapping/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_mapping }, + { "wizard/start", ACCESS_ADMIN, wizard_start, NULL }, { "wizard/cancel", ACCESS_ADMIN, wizard_cancel, NULL }, { NULL }, }; diff --git a/src/webui/static/app/acleditor.js b/src/webui/static/app/acleditor.js index 0afc2c8c6..2c803a26e 100644 --- a/src/webui/static/app/acleditor.js +++ b/src/webui/static/app/acleditor.js @@ -21,6 +21,7 @@ tvheadend.acleditor = function(panel, index) 'channel_tag_exclude,channel_tag,comment'; tvheadend.idnode_grid(panel, { + id: 'access_entry', url: 'api/access/entry', titleS: _('Access Entry'), titleP: _('Access Entries'), diff --git a/src/webui/static/app/chconf.js b/src/webui/static/app/chconf.js index 73527ec3c..d42c06711 100644 --- a/src/webui/static/app/chconf.js +++ b/src/webui/static/app/chconf.js @@ -193,6 +193,7 @@ tvheadend.channel_tab = function(panel, index) }; tvheadend.idnode_grid(panel, { + id: 'channels', url: 'api/channel', all: 1, comet: 'channel', diff --git a/src/webui/static/app/config.js b/src/webui/static/app/config.js index 2710ef3ef..ae5303f9d 100644 --- a/src/webui/static/app/config.js +++ b/src/webui/static/app/config.js @@ -4,6 +4,25 @@ tvheadend.baseconf = function(panel, index) { + var wizardButton = { + name: 'wizard', + builder: function() { + return new Ext.Toolbar.Button({ + tooltip: _('Start initial configuration wizard'), + iconCls: 'wizard', + text: _('Start wizard') + }); + }, + callback: function(conf) { + tvheadend.Ajax({ + url: 'api/wizard/start', + success: function() { + window.location.reload(); + } + }); + } + }; + tvheadend.idnode_simple(panel, { url: 'api/config', title: _('Base'), @@ -11,6 +30,7 @@ tvheadend.baseconf = function(panel, index) { tabIndex: index, comet: 'config', labelWidth: 250, + tbar: [wizardButton], postsave: function(data, abuttons) { var l = data['uilevel']; if (l >= 0) { diff --git a/src/webui/static/app/ext.css b/src/webui/static/app/ext.css index 0de9fa4f7..67816ebe3 100644 --- a/src/webui/static/app/ext.css +++ b/src/webui/static/app/ext.css @@ -596,6 +596,9 @@ background-image: url(../icons/arrow_right.png) !important; } +.finish { + background-image: url(../icons/accept.png) !important; +} .x-linked { display: inline-block; @@ -682,6 +685,15 @@ color: white; } +.x-wizard-icon { + float: right; +} + +.x-wizard-description { + margin: 5px; + font: normal 12px arial, tahoma, helvetica, sans-serif; +} + /* Table styles for webUI help */ .hts-doc-text table, .hts-doc-text th, .hts-doc-text td { diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index 444cd0c24..d538a05bc 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -1129,6 +1129,8 @@ tvheadend.idnode_editor = function(_uilevel, item, conf) }); build(); + if (conf.build) + conf.build(conf, panel); return panel; }; @@ -1141,7 +1143,7 @@ tvheadend.idnode_editor_win = function(_uilevel, item, conf) var width = p.fixedWidth; var w = new Ext.ux.Window({ title: conf.winTitle, - iconCls: 'edit', + iconCls: conf.iconCls || 'edit', layout: 'fit', autoWidth: width ? false : true, autoHeight: true, @@ -1929,6 +1931,7 @@ tvheadend.idnode_grid = function(panel, conf) } var dpanel = new Ext.Panel({ + id: conf.id || null, border: false, header: false, layout: 'fit', @@ -2473,6 +2476,7 @@ tvheadend.idnode_tree = function(panel, conf) } var dpanel = new Ext.Panel({ + id: conf.id || null, border: false, header: false, layout: 'fit', @@ -2703,6 +2707,7 @@ tvheadend.idnode_simple = function(panel, conf) } var dpanel = new Ext.Panel({ + id: conf.id || null, border: false, header: false, layout: 'fit', diff --git a/src/webui/static/app/mpegts.js b/src/webui/static/app/mpegts.js index a60da9b98..410faefa3 100644 --- a/src/webui/static/app/mpegts.js +++ b/src/webui/static/app/mpegts.js @@ -61,6 +61,7 @@ tvheadend.networks = function(panel, index) } tvheadend.idnode_grid(panel, { + id: 'mpegts_network', url: 'api/mpegts/network', titleS: _('Network'), titleP: _('Networks'), diff --git a/src/webui/static/app/status.js b/src/webui/static/app/status.js index 930a3821e..a77a16a3e 100644 --- a/src/webui/static/app/status.js +++ b/src/webui/static/app/status.js @@ -476,6 +476,7 @@ tvheadend.status_streams = function(panel, index) } var dpanel = new Ext.Panel({ + id: 'status_streams', border: false, header: false, layout: 'fit', diff --git a/src/webui/static/app/tvadapters.js b/src/webui/static/app/tvadapters.js index 08c8366e3..19a428d4c 100644 --- a/src/webui/static/app/tvadapters.js +++ b/src/webui/static/app/tvadapters.js @@ -1,6 +1,7 @@ tvheadend.tvadapters = function(panel, index) { tvheadend.idnode_tree(panel, { + id: 'tvadapters', url: 'api/hardware/tree', title: _('TV adapters'), iconCls: 'tvCards', diff --git a/src/webui/static/app/wizard.js b/src/webui/static/app/wizard.js index 4f663af28..745ca1fa5 100644 --- a/src/webui/static/app/wizard.js +++ b/src/webui/static/app/wizard.js @@ -5,6 +5,13 @@ tvheadend.wizard_start = function(page) { var w = null; + var tabMapping = { + hello: 'access_entry', + network: 'mpegts_network', + input: 'tvadapters', + status: 'status_streams', + mapping: 'channels', + } function cancel(conf) { tvheadend.Ajax({ @@ -26,6 +33,17 @@ tvheadend.wizard_start = function(page) { return null; } + function getvalue(data, prefix) { + var m = data.params; + var l = prefix.length; + for (var i = 0; i < m.length; i++) { + var id = m[i].id; + if (id === prefix) + return m[i].value; + } + return null; + } + function newpage(conf, prefix) { var p = getparam(conf.fullData, prefix); if (p) @@ -46,12 +64,28 @@ tvheadend.wizard_start = function(page) { }); buttons.splice(0, 0, prevBtn); } + + function pbuild(conf, panel) { + var data = conf.fullData; + var icon = getvalue(data, 'icon'); + var text = getvalue(data, 'description'); + var c = ''; + if (icon) + c += ''; + c += '
' + text + '
'; + var p = new Ext.Panel({ + width: 570, + html: c + }); + panel.insert(0, p); + } function build(d) { d = json_decode(d); var m = d[0]; var last = getparam(m, 'page_next_') === null; tvheadend.idnode_editor_win('basic', m, { + build: pbuild, fullData: m, url: 'api/wizard/' + page, winTitle: m.caption, @@ -68,7 +102,7 @@ tvheadend.wizard_start = function(page) { buildbtn: buildbtn, labelWidth: 250, saveText: last ? _('Finish') : _('Save & Next'), - saveIconCls: last ? 'exit' : 'next', + saveIconCls: last ? 'finish' : 'next', cancel: cancel, uilevel: 'expert', help: function() { @@ -78,6 +112,18 @@ tvheadend.wizard_start = function(page) { } tvheadend.wizard = page; + + if (page in tabMapping) { + var i = Ext.getCmp(tabMapping[page]); + var c = i ? i.ownerCt : null; + while (c) { + if ('activeTab' in c) + c.setActiveTab(i); + i = c; + c = c.ownerCt; + } + } + tvheadend.Ajax({ url: 'api/wizard/' + page + '/load', params: { diff --git a/src/wizard.c b/src/wizard.c index 66366dc4e..962cb0603 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -31,17 +31,32 @@ static const void *empty_get(void *o) return &prop_sbuf_ptr; } -#define SPECIAL_PROP(idval) { \ +static const void *icon_get(void *o) +{ + strcpy(prop_sbuf, "docresources/tvheadendlogo.png"); + return &prop_sbuf_ptr; +} + +#define SPECIAL_PROP(idval, getfcn) { \ .type = PT_STR, \ .id = idval, \ .name = "", \ - .get = empty_get, \ + .get = getfcn, \ .opts = PO_RDONLY | PO_NOUI \ } -#define PREV_BUTTON(page) SPECIAL_PROP("page_prev_" STRINGIFY(page)) -#define NEXT_BUTTON(page) SPECIAL_PROP("page_next_" STRINGIFY(page)) -#define LAST_BUTTON() SPECIAL_PROP("page_last") +#define PREV_BUTTON(page) SPECIAL_PROP("page_prev_" STRINGIFY(page), empty_get) +#define NEXT_BUTTON(page) SPECIAL_PROP("page_next_" STRINGIFY(page), empty_get) +#define LAST_BUTTON() SPECIAL_PROP("page_last", empty_get) +#define ICON() SPECIAL_PROP("icon", icon_get) +#define DESCRIPTION(page) SPECIAL_PROP("description", wizard_description_##page) + +#define DESCRIPTION_FCN(page, desc) \ +static const void *wizard_description_##page(void *o) \ +{ \ + static const char *t = desc; \ + return &t; \ +} /* * @@ -80,15 +95,52 @@ static int hello_set_network(void *o, const void *v) return 0; } +DESCRIPTION_FCN(hello, N_("\ +Enter allowed network (like 192.168.1.0/24) and user logins for administrator and ordinary user. \ +If the username is empty, anonymous access will be allowed.\ +")) + wizard_page_t *wizard_hello(void) { + static const property_group_t groups[] = { + { + .name = N_("Network access"), + .number = 1, + }, + { + .name = N_("Administrator login"), + .number = 2, + }, + { + .name = N_("User login"), + .number = 3, + }, + {} + }; static const property_t props[] = { { .type = PT_STR, .id = "network", - .name = N_("Network (like 192.168.1.0/24)"), + .name = N_("Allowed network"), .get = hello_get_network, .set = hello_set_network, + .group = 1 + }, + { + .type = PT_STR, + .id = "admin_username", + .name = N_("Admin username"), + .get = hello_get_network, + .set = hello_set_network, + .group = 2 + }, + { + .type = PT_STR, + .id = "admin_password", + .name = N_("Admin password"), + .get = hello_get_network, + .set = hello_set_network, + .group = 2 }, { .type = PT_STR, @@ -96,6 +148,7 @@ wizard_page_t *wizard_hello(void) .name = N_("Username"), .get = hello_get_network, .set = hello_set_network, + .group = 3 }, { .type = PT_STR, @@ -103,13 +156,19 @@ wizard_page_t *wizard_hello(void) .name = N_("Password"), .get = hello_get_network, .set = hello_set_network, + .group = 3 }, + ICON(), + DESCRIPTION(hello), NEXT_BUTTON(network), {} }; - wizard_page_t *page = page_init("wizard_hello", N_("Welcome - Tvheadend - your TV streaming server and video recorder")); + wizard_page_t *page = + page_init("wizard_hello", + N_("Welcome - Tvheadend - your TV streaming server and video recorder")); idclass_t *ic = (idclass_t *)page->idnode.in_class; ic->ic_properties = props; + ic->ic_groups = groups; return page; } @@ -117,6 +176,11 @@ wizard_page_t *wizard_hello(void) * Network settings */ +DESCRIPTION_FCN(network, N_("\ +Create networks.\ +")) + + wizard_page_t *wizard_network(void) { static const property_t props[] = { @@ -141,6 +205,8 @@ wizard_page_t *wizard_network(void) .get = hello_get_network, .set = hello_set_network, }, + ICON(), + DESCRIPTION(network), PREV_BUTTON(hello), NEXT_BUTTON(input), {} @@ -155,6 +221,11 @@ wizard_page_t *wizard_network(void) * Input settings */ +DESCRIPTION_FCN(input, N_("\ +Assign inputs to networks.\ +")) + + wizard_page_t *wizard_input(void) { static const property_t props[] = { @@ -179,6 +250,8 @@ wizard_page_t *wizard_input(void) .get = hello_get_network, .set = hello_set_network, }, + ICON(), + DESCRIPTION(input), PREV_BUTTON(network), NEXT_BUTTON(status), {} @@ -193,6 +266,11 @@ wizard_page_t *wizard_input(void) * Status */ +DESCRIPTION_FCN(status, N_("\ +Show the scan status.\ +")) + + wizard_page_t *wizard_status(void) { static const property_t props[] = { @@ -210,6 +288,8 @@ wizard_page_t *wizard_status(void) .get = hello_get_network, .set = hello_set_network, }, + ICON(), + DESCRIPTION(status), PREV_BUTTON(input), NEXT_BUTTON(mapping), {} @@ -224,6 +304,11 @@ wizard_page_t *wizard_status(void) * Service Mapping */ +DESCRIPTION_FCN(mapping, N_("\ +Do the service mapping to channels.\ +")) + + wizard_page_t *wizard_mapping(void) { static const property_t props[] = { @@ -234,6 +319,8 @@ wizard_page_t *wizard_mapping(void) .get = hello_get_network, .set = hello_set_network, }, + ICON(), + DESCRIPTION(mapping), PREV_BUTTON(status), LAST_BUTTON(), {}