', style, v, text
- );
- }
});
//vim: ts=4:sw=4:nu:fdc=4:nospell
@@ -481,14 +471,14 @@ Ext.extend(Ext.ux.grid.ProgressColumn, Ext.util.Observable, {
Ext.ns('Ext.ux.grid');
// add RegExp.escape if it has not been already added
-if('function' !== typeof RegExp.escape) {
- RegExp.escape = function(s) {
- if('string' !== typeof s) {
- return s;
- }
- // Note: if pasting from forum, precede ]/\ with backslash manually
- return s.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1');
- }; // eo function escape
+if ('function' !== typeof RegExp.escape) {
+ RegExp.escape = function(s) {
+ if ('string' !== typeof s) {
+ return s;
+ }
+ // Note: if pasting from forum, precede ]/\ with backslash manually
+ return s.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1');
+ }; // eo function escape
}
/**
@@ -497,389 +487,388 @@ if('function' !== typeof RegExp.escape) {
* @param {Object} config A config object
*/
Ext.ux.grid.RowActions = function(config) {
- Ext.apply(this, config);
+ Ext.apply(this, config);
- // {{{
- this.addEvents(
- /**
- * @event beforeaction
- * Fires before action event. Return false to cancel the subsequent action event.
- * @param {Ext.grid.GridPanel} grid
- * @param {Ext.data.Record} record Record corresponding to row clicked
- * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
- * @param {Integer} rowIndex Index of clicked grid row
- * @param {Integer} colIndex Index of clicked grid column that contains all action icons
- */
- 'beforeaction'
- /**
- * @event action
- * Fires when icon is clicked
- * @param {Ext.grid.GridPanel} grid
- * @param {Ext.data.Record} record Record corresponding to row clicked
- * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
- * @param {Integer} rowIndex Index of clicked grid row
- * @param {Integer} colIndex Index of clicked grid column that contains all action icons
- */
- ,'action'
- /**
- * @event beforegroupaction
- * Fires before group action event. Return false to cancel the subsequent groupaction event.
- * @param {Ext.grid.GridPanel} grid
- * @param {Array} records Array of records in this group
- * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
- * @param {String} groupId Identifies the group clicked
- */
- ,'beforegroupaction'
- /**
- * @event groupaction
- * Fires when icon in a group header is clicked
- * @param {Ext.grid.GridPanel} grid
- * @param {Array} records Array of records in this group
- * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
- * @param {String} groupId Identifies the group clicked
- */
- ,'groupaction'
- );
- // }}}
+ // {{{
+ this.addEvents(
+ /**
+ * @event beforeaction
+ * Fires before action event. Return false to cancel the subsequent action event.
+ * @param {Ext.grid.GridPanel} grid
+ * @param {Ext.data.Record} record Record corresponding to row clicked
+ * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
+ * @param {Integer} rowIndex Index of clicked grid row
+ * @param {Integer} colIndex Index of clicked grid column that contains all action icons
+ */
+ 'beforeaction'
+ /**
+ * @event action
+ * Fires when icon is clicked
+ * @param {Ext.grid.GridPanel} grid
+ * @param {Ext.data.Record} record Record corresponding to row clicked
+ * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
+ * @param {Integer} rowIndex Index of clicked grid row
+ * @param {Integer} colIndex Index of clicked grid column that contains all action icons
+ */
+ , 'action'
+ /**
+ * @event beforegroupaction
+ * Fires before group action event. Return false to cancel the subsequent groupaction event.
+ * @param {Ext.grid.GridPanel} grid
+ * @param {Array} records Array of records in this group
+ * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
+ * @param {String} groupId Identifies the group clicked
+ */
+ , 'beforegroupaction'
+ /**
+ * @event groupaction
+ * Fires when icon in a group header is clicked
+ * @param {Ext.grid.GridPanel} grid
+ * @param {Array} records Array of records in this group
+ * @param {String} action Identifies the action icon clicked. Equals to icon css class name.
+ * @param {String} groupId Identifies the group clicked
+ */
+ , 'groupaction'
+ );
+ // }}}
- // call parent
- Ext.ux.grid.RowActions.superclass.constructor.call(this);
+ // call parent
+ Ext.ux.grid.RowActions.superclass.constructor.call(this);
};
Ext.extend(Ext.ux.grid.RowActions, Ext.util.Observable, {
+ // configuration options
+ // {{{
+ /**
+ * @cfg {Array} actions Mandatory. Array of action configuration objects. The action
+ * configuration object recognizes the following options:
+ *
+ * -
+ * {Function} callback (optional). Function to call if the action icon is clicked.
+ * This function is called with same signature as action event and in its original scope.
+ * If you need to call it in different scope or with another signature use
+ * createCallback or createDelegate functions. Works for statically defined actions. Use
+ * callbacks configuration options for store bound actions.
+ *
+ * -
+ * {Function} cb Shortcut for callback.
+ *
+ * -
+ * {String} iconIndex Optional, however either iconIndex or iconCls must be
+ * configured. Field name of the field of the grid store record that contains
+ * css class of the icon to show. If configured, shown icons can vary depending
+ * of the value of this field.
+ *
+ * -
+ * {String} iconCls CSS class of the icon to show. It is ignored if iconIndex is
+ * configured. Use this if you want static icons that are not base on the values in the record.
+ *
+ * -
+ * {Boolean} hide Optional. True to hide this action while still have a space in
+ * the grid column allocated to it. IMO, it doesn't make too much sense, use hideIndex instead.
+ *
+ * -
+ * {String} hideIndex Optional. Field name of the field of the grid store record that
+ * contains hide flag (falsie [null, '', 0, false, undefined] to show, anything else to hide).
+ *
+ * -
+ * {String} qtipIndex Optional. Field name of the field of the grid store record that
+ * contains tooltip text. If configured, the tooltip texts are taken from the store.
+ *
+ * -
+ * {String} tooltip Optional. Tooltip text to use as icon tooltip. It is ignored if
+ * qtipIndex is configured. Use this if you want static tooltips that are not taken from the store.
+ *
+ * -
+ * {String} qtip Synonym for tooltip
+ *
+ * -
+ * {String} textIndex Optional. Field name of the field of the grids store record
+ * that contains text to display on the right side of the icon. If configured, the text
+ * shown is taken from record.
+ *
+ * -
+ * {String} text Optional. Text to display on the right side of the icon. Use this
+ * if you want static text that are not taken from record. Ignored if textIndex is set.
+ *
+ * -
+ * {String} style Optional. Style to apply to action icon container.
+ *
+ *
+ */
- // configuration options
- // {{{
- /**
- * @cfg {Array} actions Mandatory. Array of action configuration objects. The action
- * configuration object recognizes the following options:
- *
- * -
- * {Function} callback (optional). Function to call if the action icon is clicked.
- * This function is called with same signature as action event and in its original scope.
- * If you need to call it in different scope or with another signature use
- * createCallback or createDelegate functions. Works for statically defined actions. Use
- * callbacks configuration options for store bound actions.
- *
- * -
- * {Function} cb Shortcut for callback.
- *
- * -
- * {String} iconIndex Optional, however either iconIndex or iconCls must be
- * configured. Field name of the field of the grid store record that contains
- * css class of the icon to show. If configured, shown icons can vary depending
- * of the value of this field.
- *
- * -
- * {String} iconCls CSS class of the icon to show. It is ignored if iconIndex is
- * configured. Use this if you want static icons that are not base on the values in the record.
- *
- * -
- * {Boolean} hide Optional. True to hide this action while still have a space in
- * the grid column allocated to it. IMO, it doesn't make too much sense, use hideIndex instead.
- *
- * -
- * {String} hideIndex Optional. Field name of the field of the grid store record that
- * contains hide flag (falsie [null, '', 0, false, undefined] to show, anything else to hide).
- *
- * -
- * {String} qtipIndex Optional. Field name of the field of the grid store record that
- * contains tooltip text. If configured, the tooltip texts are taken from the store.
- *
- * -
- * {String} tooltip Optional. Tooltip text to use as icon tooltip. It is ignored if
- * qtipIndex is configured. Use this if you want static tooltips that are not taken from the store.
- *
- * -
- * {String} qtip Synonym for tooltip
- *
- * -
- * {String} textIndex Optional. Field name of the field of the grids store record
- * that contains text to display on the right side of the icon. If configured, the text
- * shown is taken from record.
- *
- * -
- * {String} text Optional. Text to display on the right side of the icon. Use this
- * if you want static text that are not taken from record. Ignored if textIndex is set.
- *
- * -
- * {String} style Optional. Style to apply to action icon container.
- *
- *
- */
+ /**
+ * @cfg {String} actionEvent Event to trigger actions, e.g. click, dblclick, mouseover (defaults to 'click')
+ */
+ actionEvent: 'click'
+ /**
+ * @cfg {Boolean} autoWidth true to calculate field width for iconic actions only (defaults to true).
+ * If true, the width is calculated as {@link #widthSlope} * number of actions + {@link #widthIntercept}.
+ */
+ , autoWidth: true
- /**
- * @cfg {String} actionEvent Event to trigger actions, e.g. click, dblclick, mouseover (defaults to 'click')
- */
- actionEvent:'click'
- /**
- * @cfg {Boolean} autoWidth true to calculate field width for iconic actions only (defaults to true).
- * If true, the width is calculated as {@link #widthSlope} * number of actions + {@link #widthIntercept}.
- */
- ,autoWidth:true
+ /**
+ * @cfg {String} dataIndex - Do not touch!
+ * @private
+ */
+ , dataIndex: ''
- /**
- * @cfg {String} dataIndex - Do not touch!
- * @private
- */
- ,dataIndex:''
+ /**
+ * @cfg {Boolean} editable - Do not touch!
+ * Must be false to prevent errors in editable grids
+ */
+ , editable: false
- /**
- * @cfg {Boolean} editable - Do not touch!
- * Must be false to prevent errors in editable grids
- */
- ,editable:false
+ /**
+ * @cfg {Array} groupActions Array of action to use for group headers of grouping grids.
+ * These actions support static icons, texts and tooltips same way as {@link #actions}. There is one
+ * more action config option recognized:
+ *
+ * -
+ * {String} align Set it to 'left' to place action icon next to the group header text.
+ * (defaults to undefined = icons are placed at the right side of the group header.
+ *
+ *
+ */
- /**
- * @cfg {Array} groupActions Array of action to use for group headers of grouping grids.
- * These actions support static icons, texts and tooltips same way as {@link #actions}. There is one
- * more action config option recognized:
- *
- * -
- * {String} align Set it to 'left' to place action icon next to the group header text.
- * (defaults to undefined = icons are placed at the right side of the group header.
- *
- *
- */
+ /**
+ * @cfg {Object} callbacks iconCls keyed object that contains callback functions. For example:
+ *
+ * callbacks:{
+ * 'icon-open':function(...) {...}
+ * ,'icon-save':function(...) {...}
+ * }
+ *
+ */
- /**
- * @cfg {Object} callbacks iconCls keyed object that contains callback functions. For example:
- *
- * callbacks:{
- * 'icon-open':function(...) {...}
- * ,'icon-save':function(...) {...}
- * }
- *
- */
+ /**
+ * @cfg {String} header Actions column header
+ */
+ , header: ''
- /**
- * @cfg {String} header Actions column header
- */
- ,header:''
+ /**
+ * @cfg {Boolean} isColumn
+ * Tell ColumnModel that we are column. Do not touch!
+ * @private
+ */
+ , isColumn: true
- /**
- * @cfg {Boolean} isColumn
- * Tell ColumnModel that we are column. Do not touch!
- * @private
- */
- ,isColumn:true
+ /**
+ * @cfg {Boolean} keepSelection
+ * Set it to true if you do not want action clicks to affect selected row(s) (defaults to false).
+ * By default, when user clicks an action icon the clicked row is selected and the action events are fired.
+ * If this option is true then the current selection is not affected, only the action events are fired.
+ */
+ , keepSelection: false
- /**
- * @cfg {Boolean} keepSelection
- * Set it to true if you do not want action clicks to affect selected row(s) (defaults to false).
- * By default, when user clicks an action icon the clicked row is selected and the action events are fired.
- * If this option is true then the current selection is not affected, only the action events are fired.
- */
- ,keepSelection:false
+ /**
+ * @cfg {Boolean} menuDisabled No sense to display header menu for this column
+ * @private
+ */
+ , menuDisabled: true
- /**
- * @cfg {Boolean} menuDisabled No sense to display header menu for this column
- * @private
- */
- ,menuDisabled:true
+ /**
+ * @cfg {Boolean} sortable Usually it has no sense to sort by this column
+ * @private
+ */
+ , sortable: false
- /**
- * @cfg {Boolean} sortable Usually it has no sense to sort by this column
- * @private
- */
- ,sortable:false
+ /**
+ * @cfg {String} tplGroup Template for group actions
+ * @private
+ */
+ , tplGroup:
+ '
'
+ + ' ux-action-right '
+ + '{cls}" style="{style}" qtip="{qtip}">{text}
'
+ + ''
- /**
- * @cfg {String} tplGroup Template for group actions
- * @private
- */
- ,tplGroup:
- '
'
- +' ux-action-right '
- +'{cls}" style="{style}" qtip="{qtip}">{text}
'
- +''
+ /**
+ * @cfg {String} tplRow Template for row actions
+ * @private
+ */
+ , tplRow:
+ '
'
+ + '
'
+ + ''
+ + 'ux-row-action-text" style="{hide}{style}" qtip="{qtip}">'
+ + '{text}
'
+ + ''
+ + '
'
- /**
- * @cfg {String} tplRow Template for row actions
- * @private
- */
- ,tplRow:
- '
'
- +'
'
- +''
- +'ux-row-action-text" style="{hide}{style}" qtip="{qtip}">'
- +'{text}
'
- +''
- +'
'
+ /**
+ * @cfg {String} hideMode How to hide hidden icons. Valid values are: 'visibility' and 'display'
+ * (defaluts to 'visibility'). If the mode is visibility the hidden icon is not visible but there
+ * is still blank space occupied by the icon. In display mode, the visible icons are shifted taking
+ * the space of the hidden icon.
+ */
+ , hideMode: 'visibility'
- /**
- * @cfg {String} hideMode How to hide hidden icons. Valid values are: 'visibility' and 'display'
- * (defaluts to 'visibility'). If the mode is visibility the hidden icon is not visible but there
- * is still blank space occupied by the icon. In display mode, the visible icons are shifted taking
- * the space of the hidden icon.
- */
- ,hideMode:'visibility'
+ /**
+ * @cfg {Number} widthIntercept Constant used for auto-width calculation (defaults to 4).
+ * See {@link #autoWidth} for explanation.
+ */
+ , widthIntercept: 4
- /**
- * @cfg {Number} widthIntercept Constant used for auto-width calculation (defaults to 4).
- * See {@link #autoWidth} for explanation.
- */
- ,widthIntercept:4
+ /**
+ * @cfg {Number} widthSlope Constant used for auto-width calculation (defaults to 21).
+ * See {@link #autoWidth} for explanation.
+ */
+ , widthSlope: 21
+ // }}}
- /**
- * @cfg {Number} widthSlope Constant used for auto-width calculation (defaults to 21).
- * See {@link #autoWidth} for explanation.
- */
- ,widthSlope:21
- // }}}
+ // methods
+ // {{{
+ /**
+ * Init function
+ * @param {Ext.grid.GridPanel} grid Grid this plugin is in
+ */
+ , init: function(grid) {
+ this.grid = grid;
- // methods
- // {{{
- /**
- * Init function
- * @param {Ext.grid.GridPanel} grid Grid this plugin is in
- */
- ,init:function(grid) {
- this.grid = grid;
-
- // the actions column must have an id for Ext 3.x
- this.id = this.id || Ext.id();
+ // the actions column must have an id for Ext 3.x
+ this.id = this.id || Ext.id();
- // for Ext 3.x compatibility
- var lookup = grid.getColumnModel().lookup;
- delete(lookup[undefined]);
- lookup[this.id] = this;
+ // for Ext 3.x compatibility
+ var lookup = grid.getColumnModel().lookup;
+ delete(lookup[undefined]);
+ lookup[this.id] = this;
- // {{{
- // setup template
- if(!this.tpl) {
- this.tpl = this.processActions(this.actions);
+ // {{{
+ // setup template
+ if (!this.tpl) {
+ this.tpl = this.processActions(this.actions);
- } // eo template setup
- // }}}
+ } // eo template setup
+ // }}}
- // calculate width
- if(this.autoWidth) {
- this.width = this.widthSlope * this.actions.length + this.widthIntercept;
- this.fixed = true;
- }
+ // calculate width
+ if (this.autoWidth) {
+ this.width = this.widthSlope * this.actions.length + this.widthIntercept;
+ this.fixed = true;
+ }
- // body click handler
- var view = grid.getView();
- var cfg = {scope:this};
- cfg[this.actionEvent] = this.onClick;
- grid.afterRender = grid.afterRender.createSequence(function() {
- view.mainBody.on(cfg);
- grid.on('destroy', this.purgeListeners, this);
- }, this);
+ // body click handler
+ var view = grid.getView();
+ var cfg = {scope: this};
+ cfg[this.actionEvent] = this.onClick;
+ grid.afterRender = grid.afterRender.createSequence(function() {
+ view.mainBody.on(cfg);
+ grid.on('destroy', this.purgeListeners, this);
+ }, this);
- // setup renderer
- if(!this.renderer) {
- this.renderer = function(value, cell, record, row, col, store) {
- cell.css += (cell.css ? ' ' : '') + 'ux-row-action-cell';
- return this.tpl.apply(this.getData(value, cell, record, row, col, store));
- }.createDelegate(this);
- }
+ // setup renderer
+ if (!this.renderer) {
+ this.renderer = function(value, cell, record, row, col, store) {
+ cell.css += (cell.css ? ' ' : '') + 'ux-row-action-cell';
+ return this.tpl.apply(this.getData(value, cell, record, row, col, store));
+ }.createDelegate(this);
+ }
- // actions in grouping grids support
- if(view.groupTextTpl && this.groupActions) {
- view.interceptMouse = view.interceptMouse.createInterceptor(function(e) {
- if(e.getTarget('.ux-grow-action-item')) {
- return false;
- }
- });
- view.groupTextTpl =
- '
' + view.groupTextTpl +'
'
- +this.processActions(this.groupActions, this.tplGroup).apply()
- ;
- }
+ // actions in grouping grids support
+ if (view.groupTextTpl && this.groupActions) {
+ view.interceptMouse = view.interceptMouse.createInterceptor(function(e) {
+ if (e.getTarget('.ux-grow-action-item')) {
+ return false;
+ }
+ });
+ view.groupTextTpl =
+ '
' + view.groupTextTpl + '
'
+ + this.processActions(this.groupActions, this.tplGroup).apply()
+ ;
+ }
- // cancel click
- if(true === this.keepSelection) {
- grid.processEvent = grid.processEvent.createInterceptor(function(name, e) {
- if('mousedown' === name) {
- return !this.getAction(e);
- }
- }, this);
- }
-
- } // eo function init
- // }}}
- // {{{
- /**
- * Returns data to apply to template. Override this if needed.
- * @param {Mixed} value
- * @param {Object} cell object to set some attributes of the grid cell
- * @param {Ext.data.Record} record from which the data is extracted
- * @param {Number} row row index
- * @param {Number} col col index
- * @param {Ext.data.Store} store object from which the record is extracted
- * @return {Object} data to apply to template
- */
- ,getData:function(value, cell, record, row, col, store) {
- return record.data || {};
- } // eo function getData
- // }}}
- // {{{
- /**
- * Processes actions configs and returns template.
- * @param {Array} actions
- * @param {String} template Optional. Template to use for one action item.
- * @return {String}
- * @private
- */
- ,processActions:function(actions, template) {
- var acts = [];
+ // cancel click
+ if (true === this.keepSelection) {
+ grid.processEvent = grid.processEvent.createInterceptor(function(name, e) {
+ if ('mousedown' === name) {
+ return !this.getAction(e);
+ }
+ }, this);
+ }
- // actions loop
- Ext.each(actions, function(a, i) {
- // save callback
- if(a.iconCls && 'function' === typeof (a.callback || a.cb)) {
- this.callbacks = this.callbacks || {};
- this.callbacks[a.iconCls] = a.callback || a.cb;
- }
+ } // eo function init
+ // }}}
+ // {{{
+ /**
+ * Returns data to apply to template. Override this if needed.
+ * @param {Mixed} value
+ * @param {Object} cell object to set some attributes of the grid cell
+ * @param {Ext.data.Record} record from which the data is extracted
+ * @param {Number} row row index
+ * @param {Number} col col index
+ * @param {Ext.data.Store} store object from which the record is extracted
+ * @return {Object} data to apply to template
+ */
+ , getData: function(value, cell, record, row, col, store) {
+ return record.data || {};
+ } // eo function getData
+ // }}}
+ // {{{
+ /**
+ * Processes actions configs and returns template.
+ * @param {Array} actions
+ * @param {String} template Optional. Template to use for one action item.
+ * @return {String}
+ * @private
+ */
+ , processActions: function(actions, template) {
+ var acts = [];
- // data for intermediate template
- var o = {
- cls:a.iconIndex ? '{' + a.iconIndex + '}' : (a.iconCls ? a.iconCls : '')
- ,qtip:a.qtipIndex ? '{' + a.qtipIndex + '}' : (a.tooltip || a.qtip ? a.tooltip || a.qtip : '')
- ,text:a.textIndex ? '{' + a.textIndex + '}' : (a.text ? a.text : '')
- ,hide:a.hideIndex
- ? '
'
- + ('display' === this.hideMode ? 'display:none' :'visibility:hidden') + ';'
- : (a.hide ? ('display' === this.hideMode ? 'display:none' :'visibility:hidden;') : '')
- ,align:a.align || 'right'
- ,style:a.style ? a.style : ''
- };
- acts.push(o);
+ // actions loop
+ Ext.each(actions, function(a, i) {
+ // save callback
+ if (a.iconCls && 'function' === typeof (a.callback || a.cb)) {
+ this.callbacks = this.callbacks || {};
+ this.callbacks[a.iconCls] = a.callback || a.cb;
+ }
- }, this); // eo actions loop
+ // data for intermediate template
+ var o = {
+ cls: a.iconIndex ? '{' + a.iconIndex + '}' : (a.iconCls ? a.iconCls : '')
+ , qtip: a.qtipIndex ? '{' + a.qtipIndex + '}' : (a.tooltip || a.qtip ? a.tooltip || a.qtip : '')
+ , text: a.textIndex ? '{' + a.textIndex + '}' : (a.text ? a.text : '')
+ , hide: a.hideIndex
+ ? '
'
+ + ('display' === this.hideMode ? 'display:none' : 'visibility:hidden') + ';'
+ : (a.hide ? ('display' === this.hideMode ? 'display:none' : 'visibility:hidden;') : '')
+ , align: a.align || 'right'
+ , style: a.style ? a.style : ''
+ };
+ acts.push(o);
- var xt = new Ext.XTemplate(template || this.tplRow);
- return new Ext.XTemplate(xt.apply({actions:acts}));
+ }, this); // eo actions loop
- } // eo function processActions
- // }}}
- ,getAction:function(e) {
- var action = false;
- var t = e.getTarget('.ux-row-action-item');
- if(t) {
- action = t.className.replace(/ux-row-action-item /, '');
- if(action) {
- action = action.replace(/ ux-row-action-text/, '');
- action = action.trim();
- }
- }
- return action;
- } // eo function getAction
- // {{{
- /**
- * Grid body actionEvent event handler
- * @private
- */
- ,onClick:function(e, target) {
+ var xt = new Ext.XTemplate(template || this.tplRow);
+ return new Ext.XTemplate(xt.apply({actions: acts}));
- var view = this.grid.getView();
+ } // eo function processActions
+ // }}}
+ , getAction: function(e) {
+ var action = false;
+ var t = e.getTarget('.ux-row-action-item');
+ if (t) {
+ action = t.className.replace(/ux-row-action-item /, '');
+ if (action) {
+ action = action.replace(/ ux-row-action-text/, '');
+ action = action.trim();
+ }
+ }
+ return action;
+ } // eo function getAction
+ // {{{
+ /**
+ * Grid body actionEvent event handler
+ * @private
+ */
+ , onClick: function(e, target) {
- // handle row action click
- var row = e.getTarget('.x-grid3-row');
- var col = view.findCellIndex(target.parentNode.parentNode);
- var action = this.getAction(e);
+ var view = this.grid.getView();
+
+ // handle row action click
+ var row = e.getTarget('.x-grid3-row');
+ var col = view.findCellIndex(target.parentNode.parentNode);
+ var action = this.getAction(e);
// var t = e.getTarget('.ux-row-action-item');
// if(t) {
@@ -890,55 +879,55 @@ Ext.extend(Ext.ux.grid.RowActions, Ext.util.Observable, {
// action = action.trim();
// }
// }
- if(false !== row && false !== col && false !== action) {
- var record = this.grid.store.getAt(row.rowIndex);
+ if (false !== row && false !== col && false !== action) {
+ var record = this.grid.store.getAt(row.rowIndex);
- // call callback if any
- if(this.callbacks && 'function' === typeof this.callbacks[action]) {
- this.callbacks[action](this.grid, record, action, row.rowIndex, col);
- }
+ // call callback if any
+ if (this.callbacks && 'function' === typeof this.callbacks[action]) {
+ this.callbacks[action](this.grid, record, action, row.rowIndex, col);
+ }
- // fire events
- if(true !== this.eventsSuspended && false === this.fireEvent('beforeaction', this.grid, record, action, row.rowIndex, col)) {
- return;
- }
- else if(true !== this.eventsSuspended) {
- this.fireEvent('action', this.grid, record, action, row.rowIndex, col);
- }
+ // fire events
+ if (true !== this.eventsSuspended && false === this.fireEvent('beforeaction', this.grid, record, action, row.rowIndex, col)) {
+ return;
+ }
+ else if (true !== this.eventsSuspended) {
+ this.fireEvent('action', this.grid, record, action, row.rowIndex, col);
+ }
- }
+ }
- // handle group action click
- t = e.getTarget('.ux-grow-action-item');
- if(t) {
- // get groupId
- var group = view.findGroup(target);
- var groupId = group ? group.id.replace(/ext-gen[0-9]+-gp-/, '') : null;
+ // handle group action click
+ t = e.getTarget('.ux-grow-action-item');
+ if (t) {
+ // get groupId
+ var group = view.findGroup(target);
+ var groupId = group ? group.id.replace(/ext-gen[0-9]+-gp-/, '') : null;
- // get matching records
- var records;
- if(groupId) {
- var re = new RegExp(RegExp.escape(groupId));
- records = this.grid.store.queryBy(function(r) {
- return r._groupId.match(re);
- });
- records = records ? records.items : [];
- }
- action = t.className.replace(/ux-grow-action-item (ux-action-right )*/, '');
+ // get matching records
+ var records;
+ if (groupId) {
+ var re = new RegExp(RegExp.escape(groupId));
+ records = this.grid.store.queryBy(function(r) {
+ return r._groupId.match(re);
+ });
+ records = records ? records.items : [];
+ }
+ action = t.className.replace(/ux-grow-action-item (ux-action-right )*/, '');
- // call callback if any
- if('function' === typeof this.callbacks[action]) {
- this.callbacks[action](this.grid, records, action, groupId);
- }
+ // call callback if any
+ if ('function' === typeof this.callbacks[action]) {
+ this.callbacks[action](this.grid, records, action, groupId);
+ }
- // fire events
- if(true !== this.eventsSuspended && false === this.fireEvent('beforegroupaction', this.grid, records, action, groupId)) {
- return false;
- }
- this.fireEvent('groupaction', this.grid, records, action, groupId);
- }
- } // eo function onClick
- // }}}
+ // fire events
+ if (true !== this.eventsSuspended && false === this.fireEvent('beforegroupaction', this.grid, records, action, groupId)) {
+ return false;
+ }
+ this.fireEvent('groupaction', this.grid, records, action, groupId);
+ }
+ } // eo function onClick
+ // }}}
});
@@ -964,251 +953,250 @@ Ext.reg('rowactions', Ext.ux.grid.RowActions);
*
* License details: http://www.gnu.org/licenses/lgpl.html
*/
-
+
/*global Ext */
// add RegExp.escape if it has not been already added
-if('function' !== typeof RegExp.escape) {
- RegExp.escape = function(s) {
- if('string' !== typeof s) {
- return s;
- }
- // Note: if pasting from forum, precede ]/\ with backslash manually
- return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
- }; // eo function escape
+if ('function' !== typeof RegExp.escape) {
+ RegExp.escape = function(s) {
+ if ('string' !== typeof s) {
+ return s;
+ }
+ // Note: if pasting from forum, precede ]/\ with backslash manually
+ return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+ }; // eo function escape
}
// create namespace
Ext.ns('Ext.ux.form');
-
+
/**
*
* @class Ext.ux.form.LovCombo
* @extends Ext.form.ComboBox
*/
Ext.ux.form.LovCombo = Ext.extend(Ext.form.ComboBox, {
-
- // {{{
- // configuration options
- /**
- * @cfg {String} checkField name of field used to store checked state.
- * It is automatically added to existing fields.
- * Change it only if it collides with your normal field.
- */
- checkField:'checked'
-
- /**
- * @cfg {String} separator separator to use between values and texts
- */
- ,separator:','
-
- /**
- * @cfg {String/Array} tpl Template for items.
- * Change it only if you know what you are doing.
- */
- // }}}
// {{{
- ,initComponent:function() {
-
- // template with checkbox
- if(!this.tpl) {
- this.tpl =
- '
'
- +''
- +'

'
- +'
{' + (this.displayField || 'text' )+ '}
'
- +'
'
- +''
- ;
- }
-
+ // configuration options
+ /**
+ * @cfg {String} checkField name of field used to store checked state.
+ * It is automatically added to existing fields.
+ * Change it only if it collides with your normal field.
+ */
+ checkField: 'checked'
+
+ /**
+ * @cfg {String} separator separator to use between values and texts
+ */
+ , separator: ','
+
+ /**
+ * @cfg {String/Array} tpl Template for items.
+ * Change it only if you know what you are doing.
+ */
+ // }}}
+ // {{{
+ , initComponent: function() {
+
+ // template with checkbox
+ if (!this.tpl) {
+ this.tpl =
+ '
'
+ + ''
+ + '

'
+ + '
{' + (this.displayField || 'text') + '}
'
+ + '
'
+ + ''
+ ;
+ }
+
// call parent
Ext.ux.form.LovCombo.superclass.initComponent.apply(this, arguments);
- // install internal event handlers
- this.on({
- scope:this
- ,beforequery:this.onBeforeQuery
- ,blur:this.onRealBlur
- });
+ // install internal event handlers
+ this.on({
+ scope: this
+ , beforequery: this.onBeforeQuery
+ , blur: this.onRealBlur
+ });
+
+ // remove selection from input field
+ this.onLoad = this.onLoad.createSequence(function() {
+ if (this.el) {
+ var v = this.el.dom.value;
+ this.el.dom.value = '';
+ this.el.dom.value = v;
+ }
+ });
- // remove selection from input field
- this.onLoad = this.onLoad.createSequence(function() {
- if(this.el) {
- var v = this.el.dom.value;
- this.el.dom.value = '';
- this.el.dom.value = v;
- }
- });
-
} // e/o function initComponent
// }}}
- // {{{
- /**
- * Disables default tab key bahavior
- * @private
- */
- ,initEvents:function() {
- Ext.ux.form.LovCombo.superclass.initEvents.apply(this, arguments);
+ // {{{
+ /**
+ * Disables default tab key bahavior
+ * @private
+ */
+ , initEvents: function() {
+ Ext.ux.form.LovCombo.superclass.initEvents.apply(this, arguments);
- // disable default tab handling - does no good
- this.keyNav.tab = false;
+ // disable default tab handling - does no good
+ this.keyNav.tab = false;
- } // eo function initEvents
- // }}}
- // {{{
- /**
- * clears value
- */
- ,clearValue:function() {
- this.value = '';
- this.setRawValue(this.value);
- this.store.clearFilter();
- this.store.each(function(r) {
- r.set(this.checkField, false);
- }, this);
- if(this.hiddenField) {
- this.hiddenField.value = '';
- }
- this.applyEmptyText();
- } // eo function clearValue
- // }}}
- // {{{
- /**
- * @return {String} separator (plus space) separated list of selected displayFields
- * @private
- */
- ,getCheckedDisplay:function() {
- var re = new RegExp(this.separator, "g");
- return this.getCheckedValue(this.displayField).replace(re, this.separator + ' ');
- } // eo function getCheckedDisplay
- // }}}
- // {{{
- /**
- * @return {String} separator separated list of selected valueFields
- * @private
- */
- ,getCheckedValue:function(field) {
- field = field || this.valueField;
- var c = [];
+ } // eo function initEvents
+ // }}}
+ // {{{
+ /**
+ * clears value
+ */
+ , clearValue: function() {
+ this.value = '';
+ this.setRawValue(this.value);
+ this.store.clearFilter();
+ this.store.each(function(r) {
+ r.set(this.checkField, false);
+ }, this);
+ if (this.hiddenField) {
+ this.hiddenField.value = '';
+ }
+ this.applyEmptyText();
+ } // eo function clearValue
+ // }}}
+ // {{{
+ /**
+ * @return {String} separator (plus space) separated list of selected displayFields
+ * @private
+ */
+ , getCheckedDisplay: function() {
+ var re = new RegExp(this.separator, "g");
+ return this.getCheckedValue(this.displayField).replace(re, this.separator + ' ');
+ } // eo function getCheckedDisplay
+ // }}}
+ // {{{
+ /**
+ * @return {String} separator separated list of selected valueFields
+ * @private
+ */
+ , getCheckedValue: function(field) {
+ field = field || this.valueField;
+ var c = [];
- // store may be filtered so get all records
- var snapshot = this.store.snapshot || this.store.data;
+ // store may be filtered so get all records
+ var snapshot = this.store.snapshot || this.store.data;
- snapshot.each(function(r) {
- if(r.get(this.checkField)) {
- c.push(r.get(field));
- }
- }, this);
+ snapshot.each(function(r) {
+ if (r.get(this.checkField)) {
+ c.push(r.get(field));
+ }
+ }, this);
- return c.join(this.separator);
- } // eo function getCheckedValue
- // }}}
- // {{{
- /**
- * beforequery event handler - handles multiple selections
- * @param {Object} qe query event
- * @private
- */
- ,onBeforeQuery:function(qe) {
- qe.query = qe.query.replace(new RegExp(this.getCheckedDisplay() + '[ ' + this.separator + ']*'), '');
- } // eo function onBeforeQuery
- // }}}
- // {{{
- /**
- * blur event handler - runs only when real blur event is fired
- */
- ,onRealBlur:function() {
- this.list.hide();
- var rv = this.getRawValue();
- var rva = rv.split(new RegExp(RegExp.escape(this.separator) + ' *'));
- var va = [];
- var snapshot = this.store.snapshot || this.store.data;
+ return c.join(this.separator);
+ } // eo function getCheckedValue
+ // }}}
+ // {{{
+ /**
+ * beforequery event handler - handles multiple selections
+ * @param {Object} qe query event
+ * @private
+ */
+ , onBeforeQuery: function(qe) {
+ qe.query = qe.query.replace(new RegExp(this.getCheckedDisplay() + '[ ' + this.separator + ']*'), '');
+ } // eo function onBeforeQuery
+ // }}}
+ // {{{
+ /**
+ * blur event handler - runs only when real blur event is fired
+ */
+ , onRealBlur: function() {
+ this.list.hide();
+ var rv = this.getRawValue();
+ var rva = rv.split(new RegExp(RegExp.escape(this.separator) + ' *'));
+ var va = [];
+ var snapshot = this.store.snapshot || this.store.data;
- // iterate through raw values and records and check/uncheck items
- Ext.each(rva, function(v) {
- snapshot.each(function(r) {
- if(v === r.get(this.displayField)) {
- va.push(r.get(this.valueField));
- }
- }, this);
- }, this);
- this.setValue(va.join(this.separator));
- this.store.clearFilter();
- } // eo function onRealBlur
- // }}}
- // {{{
- /**
- * Combo's onSelect override
- * @private
- * @param {Ext.data.Record} record record that has been selected in the list
- * @param {Number} index index of selected (clicked) record
- */
- ,onSelect:function(record, index) {
- if(this.fireEvent('beforeselect', this, record, index) !== false){
+ // iterate through raw values and records and check/uncheck items
+ Ext.each(rva, function(v) {
+ snapshot.each(function(r) {
+ if (v === r.get(this.displayField)) {
+ va.push(r.get(this.valueField));
+ }
+ }, this);
+ }, this);
+ this.setValue(va.join(this.separator));
+ this.store.clearFilter();
+ } // eo function onRealBlur
+ // }}}
+ // {{{
+ /**
+ * Combo's onSelect override
+ * @private
+ * @param {Ext.data.Record} record record that has been selected in the list
+ * @param {Number} index index of selected (clicked) record
+ */
+ , onSelect: function(record, index) {
+ if (this.fireEvent('beforeselect', this, record, index) !== false) {
- // toggle checked field
- record.set(this.checkField, !record.get(this.checkField));
+ // toggle checked field
+ record.set(this.checkField, !record.get(this.checkField));
- // display full list
- if(this.store.isFiltered()) {
- this.doQuery(this.allQuery);
- }
+ // display full list
+ if (this.store.isFiltered()) {
+ this.doQuery(this.allQuery);
+ }
- // set (update) value and fire event
- this.setValue(this.getCheckedValue());
+ // set (update) value and fire event
+ this.setValue(this.getCheckedValue());
this.fireEvent('select', this, record, index);
}
- } // eo function onSelect
- // }}}
- // {{{
- /**
- * Sets the value of the LovCombo
- * @param {Mixed} v value
- */
- ,setValue:function(v) {
- if(v) {
- v = '' + v;
- if(this.valueField) {
- this.store.clearFilter();
- this.store.each(function(r) {
- var checked = !(!v.match(
- '(^|' + this.separator + ')' + RegExp.escape(r.get(this.valueField))
- +'(' + this.separator + '|$)'))
- ;
+ } // eo function onSelect
+ // }}}
+ // {{{
+ /**
+ * Sets the value of the LovCombo
+ * @param {Mixed} v value
+ */
+ , setValue: function(v) {
+ if (v) {
+ v = '' + v;
+ if (this.valueField) {
+ this.store.clearFilter();
+ this.store.each(function(r) {
+ var checked = !(!v.match(
+ '(^|' + this.separator + ')' + RegExp.escape(r.get(this.valueField))
+ + '(' + this.separator + '|$)'))
+ ;
- r.set(this.checkField, checked);
- }, this);
- this.value = this.getCheckedValue();
- this.setRawValue(this.getCheckedDisplay());
- if(this.hiddenField) {
- this.hiddenField.value = this.value;
- }
- }
- else {
- this.value = v;
- this.setRawValue(v);
- if(this.hiddenField) {
- this.hiddenField.value = v;
- }
- }
- if(this.el) {
- this.el.removeClass(this.emptyClass);
- }
- }
- else {
- this.clearValue();
- }
- } // eo function setValue
- // }}}
- // {{{
- /**
- * Selects all items
- */
- ,selectAll:function() {
- this.store.each(function(record){
+ r.set(this.checkField, checked);
+ }, this);
+ this.value = this.getCheckedValue();
+ this.setRawValue(this.getCheckedDisplay());
+ if (this.hiddenField) {
+ this.hiddenField.value = this.value;
+ }
+ }
+ else {
+ this.value = v;
+ this.setRawValue(v);
+ if (this.hiddenField) {
+ this.hiddenField.value = v;
+ }
+ }
+ if (this.el) {
+ this.el.removeClass(this.emptyClass);
+ }
+ }
+ else {
+ this.clearValue();
+ }
+ } // eo function setValue
+ // }}}
+ // {{{
+ /**
+ * Selects all items
+ */
+ , selectAll: function() {
+ this.store.each(function(record) {
// toggle checked field
record.set(this.checkField, true);
}, this);
@@ -1217,17 +1205,17 @@ Ext.ux.form.LovCombo = Ext.extend(Ext.form.ComboBox, {
this.doQuery(this.allQuery);
this.setValue(this.getCheckedValue());
} // eo full selectAll
- // }}}
- // {{{
- /**
- * Deselects all items. Synonym for clearValue
- */
- ,deselectAll:function() {
- this.clearValue();
+ // }}}
+ // {{{
+ /**
+ * Deselects all items. Synonym for clearValue
+ */
+ , deselectAll: function() {
+ this.clearValue();
} // eo full deselectAll
- // }}}
+ // }}}
}); // eo extend
-
+
// register xtype
-Ext.reg('lovcombo', Ext.ux.form.LovCombo);
+Ext.reg('lovcombo', Ext.ux.form.LovCombo);
diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js
index 8c7108d1..f6648609 100644
--- a/src/webui/static/app/idnode.js
+++ b/src/webui/static/app/idnode.js
@@ -3,303 +3,306 @@
*/
tvheadend.idnode_enum_stores = {}
-tvheadend.idnode_get_enum = function ( conf )
+tvheadend.idnode_get_enum = function(conf)
{
- /* Build key */
- var key = conf.url;
- if (conf.params)
- key += '?' + Ext.util.JSON.encode(conf.params);
- if (conf.event)
- key += '+' + conf.event;
+ /* Build key */
+ var key = conf.url;
+ if (conf.params)
+ key += '?' + Ext.util.JSON.encode(conf.params);
+ if (conf.event)
+ key += '+' + conf.event;
- /* Use cached */
- if (key in tvheadend.idnode_enum_stores)
- return tvheadend.idnode_enum_stores[key];
+ /* Use cached */
+ if (key in tvheadend.idnode_enum_stores)
+ return tvheadend.idnode_enum_stores[key];
- /* Build combobox */
- var st = new Ext.data.JsonStore({
- root : conf.root || 'entries',
- url : conf.url,
- baseParams : conf.params || {},
- fields : conf.fields || [ 'key', 'val' ],
- id : conf.id || 'key',
- autoLoad : true,
- sortInfo : {
- field : 'val',
- direction : 'ASC'
- }
- });
- tvheadend.idnode_enum_stores[key] = st;
-
- /* Event to update */
- if (conf.event) {
- tvheadend.comet.on(conf.event, function(){
- st.reload();
+ /* Build combobox */
+ var st = new Ext.data.JsonStore({
+ root: conf.root || 'entries',
+ url: conf.url,
+ baseParams: conf.params || {},
+ fields: conf.fields || ['key', 'val'],
+ id: conf.id || 'key',
+ autoLoad: true,
+ sortInfo: {
+ field: 'val',
+ direction: 'ASC'
+ }
});
- }
+ tvheadend.idnode_enum_stores[key] = st;
- return st;
-}
+ /* Event to update */
+ if (conf.event) {
+ tvheadend.comet.on(conf.event, function() {
+ st.reload();
+ });
+ }
+
+ return st;
+};
json_decode = function(d)
{
- if (d && d.responseText) {
- d = Ext.util.JSON.decode(d.responseText)
- if (d.entries)
- d = d.entries;
- if (d.nodes)
- d = d.nodes;
- } else {
- d = []
- }
- return d;
-}
+ if (d && d.responseText) {
+ d = Ext.util.JSON.decode(d.responseText);
+ if (d.entries)
+ d = d.entries;
+ if (d.nodes)
+ d = d.nodes;
+ } else {
+ d = [];
+ }
+ return d;
+};
/*
* Build enum data store
*/
tvheadend.idnode_enum_store = function(f)
{
- var store = null;
+ var store = null;
- /* API fetch */
- if (f.enum.type == 'api') {
- return tvheadend.idnode_get_enum({
- url : 'api/' + f.enum.uri,
- params : f.enum.params,
- event : f.enum.event
- });
- }
-
- switch (f.type) {
- case 'str':
- if (f.enum.length > 0 && f.enum[0] instanceof Object)
- store = new Ext.data.JsonStore({
- id : 'key',
- fields : [ 'key', 'val' ],
- data : f.enum,
+ /* API fetch */
+ if (f.enum.type === 'api') {
+ return tvheadend.idnode_get_enum({
+ url: 'api/' + f.enum.uri,
+ params: f.enum.params,
+ event: f.enum.event
});
- else
- store = f.enum;
- break;
- case 'int':
- case 'u32':
- case 'u16':
- case 'dbl':
- var data = null;
- if (f.enum.length > 0 && f.enum[0] instanceof Object) {
- data = f.enum;
- } else {
- data = []
- for ( i = 0; i < f.enum.length; i++ )
- data.push({ key: i, val: f.enum[i]});
- }
- store = new Ext.data.JsonStore({
- id : 'key',
- fields : [ 'key', 'val' ],
- data : data
- });
- break;
- }
- return store;
-}
-
-tvheadend.IdNodeField = function (conf)
-{
- /*
- * Properties
- */
- this.id = conf.id;
- this.text = conf.caption || this.id;
- this.type = conf.type;
- this.list = conf.list;
- this.rdonly = conf.rdonly;
- this.wronly = conf.wronly;
- this.wronce = conf.wronce;
- this.hidden = conf.hidden || conf.advanced;
- this.enum = conf.enum;
- this.store = null;
- if (this.enum)
- this.store = tvheadend.idnode_enum_store(this);
- this.ordered = false;
-
- /*
- * Methods
- */
-
- this.column = function ()
- {
- var w = 300;
- var ftype = 'string';
- if (this.type == 'int' || this.type == 'u32' ||
- this.type == 'u16' || this.type == 'dbl') {
- ftype = 'numeric';
- w = 80;
- } else if (this.type == 'bool') {
- ftype = 'boolean';
- w = 60;
}
- if (this.enum || this.list)
- w = 300;
- return {
- width : w,
- dataIndex: this.id,
- header : this.text,
- editor : this.editor({create: false}),
- renderer : this.renderer(),
- hidden : this.hidden,
- filter : {
- type : ftype,
- dataIndex : this.id
- }
- };
- }
-
- this.renderer = function ()
- {
- if (!this.store)
- return null;
-
- var st = this.store;
- return function (v) {
- if (st && st instanceof Ext.data.JsonStore) {
- var t = []
- var d;
- if (v.push)
- d = v;
- else
- d = [ v ];
- for (var i = 0; i < d.length; i++) {
- var r = st.find('key', d[i]);
- if (r != -1) {
- var nv = st.getAt(r).get('val');
- if (nv)
- t.push(nv);
- }
- }
- v = t.join(',');
- }
- return v;
- };
- }
-
- this.editor = function (conf)
- {
- var cons = null;
-
- /* Editable? */
- var d = this.rdonly;
- if (this.wronly && !conf.create)
- d = false;
-
- /* Basic */
- var c = {
- fieldLabel : this.text,
- name : this.id,
- value : conf.value || null,
- disabled : d,
- width : 300,
- };
-
- /* ComboBox */
- if (this.enum) {
- cons = Ext.form.ComboBox;
- if (this.list)
- cons = Ext.ux.form.LovCombo;
-
- /* Combo settings */
- c['mode'] = 'local';
- c['valueField'] = 'key';
- c['displayField'] = 'val';
- c['store'] = this.store;
- c['typeAhead'] = true;
- c['forceSelection'] = false;
- c['triggerAction'] = 'all',
- c['emptyText'] = 'Select ' + this.text + ' ...';
-
- /* Single */
- } else {
- switch (this.type) {
- case 'bool':
- cons = Ext.form.Checkbox;
- break;
+ switch (f.type) {
+ case 'str':
+ if (f.enum.length > 0 && f.enum[0] instanceof Object)
+ store = new Ext.data.JsonStore({
+ id: 'key',
+ fields: ['key', 'val'],
+ data: f.enum
+ });
+ else
+ store = f.enum;
+ break;
case 'int':
case 'u32':
case 'u16':
case 'dbl':
- cons = Ext.form.NumberField;
- break;
-
- default:
- cons = Ext.form.TextField;
- break;
- }
+ var data = null;
+ if (f.enum.length > 0 && f.enum[0] instanceof Object) {
+ data = f.enum;
+ } else {
+ data = [];
+ for (i = 0; i < f.enum.length; i++)
+ data.push({key: i, val: f.enum[i]});
+ }
+ store = new Ext.data.JsonStore({
+ id: 'key',
+ fields: ['key', 'val'],
+ data: data
+ });
+ break;
}
+ return store;
+};
- return new cons(c);
- }
-}
+tvheadend.IdNodeField = function(conf)
+{
+ /*
+ * Properties
+ */
+ this.id = conf.id;
+ this.text = conf.caption || this.id;
+ this.type = conf.type;
+ this.list = conf.list;
+ this.rdonly = conf.rdonly;
+ this.wronly = conf.wronly;
+ this.wronce = conf.wronce;
+ this.hidden = conf.hidden || conf.advanced;
+ this.enum = conf.enum;
+ this.store = null;
+ if (this.enum)
+ this.store = tvheadend.idnode_enum_store(this);
+ this.ordered = false;
+
+ /*
+ * Methods
+ */
+
+ this.column = function()
+ {
+ var w = 300;
+ var ftype = 'string';
+ if (this.type === 'int' || this.type === 'u32' ||
+ this.type === 'u16' || this.type === 'dbl') {
+ ftype = 'numeric';
+ w = 80;
+ } else if (this.type === 'bool') {
+ ftype = 'boolean';
+ w = 60;
+ }
+ if (this.enum || this.list)
+ w = 300;
+ return {
+ width: w,
+ dataIndex: this.id,
+ header: this.text,
+ editor: this.editor({create: false}),
+ renderer: this.renderer(),
+ hidden: this.hidden,
+ filter: {
+ type: ftype,
+ dataIndex: this.id
+ }
+ };
+ };
+
+ this.renderer = function()
+ {
+ if (!this.store)
+ return null;
+
+ var st = this.store;
+ return function(v) {
+ if (st && st instanceof Ext.data.JsonStore) {
+ var t = [];
+ var d;
+ if (v.push)
+ d = v;
+ else
+ d = [v];
+ for (var i = 0; i < d.length; i++) {
+ var r = st.find('key', d[i]);
+ if (r !== -1) {
+ var nv = st.getAt(r).get('val');
+ if (nv)
+ t.push(nv);
+ }
+ }
+ v = t.join(',');
+ }
+ return v;
+ };
+ };
+
+ this.editor = function(conf)
+ {
+ var cons = null;
+
+ /* Editable? */
+ var d = this.rdonly;
+ if (this.wronly && !conf.create)
+ d = false;
+
+ /* Basic */
+ var c = {
+ fieldLabel: this.text,
+ name: this.id,
+ value: conf.value || null,
+ disabled: d,
+ width: 300
+ };
+
+ /* ComboBox */
+ if (this.enum) {
+ cons = Ext.form.ComboBox;
+ if (this.list)
+ cons = Ext.ux.form.LovCombo;
+
+ /* Combo settings */
+ c['mode'] = 'local';
+ c['valueField'] = 'key';
+ c['displayField'] = 'val';
+ c['store'] = this.store;
+ c['typeAhead'] = true;
+ c['forceSelection'] = false;
+ c['triggerAction'] = 'all',
+ c['emptyText'] = 'Select ' + this.text + ' ...';
+
+ /* Single */
+ } else {
+ switch (this.type) {
+ case 'bool':
+ cons = Ext.form.Checkbox;
+ break;
+
+ case 'int':
+ case 'u32':
+ case 'u16':
+ case 'dbl':
+ cons = Ext.form.NumberField;
+ break;
+
+ default:
+ cons = Ext.form.TextField;
+ break;
+ }
+ }
+
+ return new cons(c);
+ };
+};
/*
* IdNode
*/
-tvheadend.IdNode = function (conf)
+tvheadend.IdNode = function(conf)
{
- /*
- * Properties
- */
- this.clazz = conf.class;
- this.text = conf.caption || this.clazz;
- this.props = conf.props;
- this.order = [];
- this.fields = [];
- for (var i = 0; i < this.props.length; i++) {
- this.fields.push(new tvheadend.IdNodeField(this.props[i]));
- }
- var o = [];
- if (conf.order)
- o = conf.order.split(',');
- if (o) {
- while (o.length < this.fields.length)
- o.push(null);
- for (var i = 0; i < o.length; i++) {
- this.order[i] = null;
- if (o[i]) {
- for (var j = 0; j < this.fields.length; j++) {
- if (this.fields[j].id == o[i]) {
- this.order[i] = this.fields[j];
- this.fields[j].ordered = true;
- break;
- }
- }
- }
+ /*
+ * Properties
+ */
+ this.clazz = conf.class;
+ this.text = conf.caption || this.clazz;
+ this.props = conf.props;
+ this.order = [];
+ this.fields = [];
+ for (var i = 0; i < this.props.length; i++) {
+ this.fields.push(new tvheadend.IdNodeField(this.props[i]));
}
- for (var i = 0; i < o.length; i++) {
- if (this.order[i] == null) {
- for (var j = 0; j < this.fields.length; j++) {
- if (!this.fields[j].ordered) {
- this.fields[j].ordered = true;
- this.order[i] = this.fields[j];
- break;
- }
+ var o = [];
+ if (conf.order)
+ o = conf.order.split(',');
+ if (o) {
+ while (o.length < this.fields.length)
+ o.push(null);
+ for (var i = 0; i < o.length; i++) {
+ this.order[i] = null;
+ if (o[i]) {
+ for (var j = 0; j < this.fields.length; j++) {
+ if (this.fields[j].id === o[i]) {
+ this.order[i] = this.fields[j];
+ this.fields[j].ordered = true;
+ break;
+ }
+ }
+ }
+ }
+ for (var i = 0; i < o.length; i++) {
+ if (this.order[i] == null) {
+ for (var j = 0; j < this.fields.length; j++) {
+ if (!this.fields[j].ordered) {
+ this.fields[j].ordered = true;
+ this.order[i] = this.fields[j];
+ break;
+ }
+ }
+ }
}
- }
}
- }
- /*
- * Methods
- */
+ /*
+ * Methods
+ */
- this.length = function () {
- return this.fields.length;
- }
-
- this.field = function ( index ) {
- if (this.order) return this.order[index]; else return this.fields[index];
- }
-}
+ this.length = function() {
+ return this.fields.length;
+ };
+
+ this.field = function(index) {
+ if (this.order)
+ return this.order[index];
+ else
+ return this.fields[index];
+ };
+};
/*
@@ -307,205 +310,208 @@ tvheadend.IdNode = function (conf)
*/
tvheadend.idnode_editor_field = function(f, create)
{
- var d = f.rdonly || false;
- if (f.wronly && !create) d = false;
- var value = f.value;
- if (value == null)
- value = f.default;
-
- /* Enumerated (combobox) type */
- if (f.enum) {
- var cons = Ext.form.ComboBox;
- if (f.list)
- cons = Ext.ux.form.LovCombo;
- var st = tvheadend.idnode_enum_store(f);
- var r = new cons({
- fieldLabel : f.caption,
- name : f.id,
- value : value,
- disabled : d,
- width : 300,
- mode : 'local',
- valueField : 'key',
- displayField : 'val',
- store : st,
- typeAhead : true, // TODO: this does strange things in multi
- forceSelection : false,
- triggerAction : 'all',
- emptyText :'Select ' + f.caption +' ...',
- listeners : {
- beforequery: function(qe){
- delete qe.combo.lastQuery;
+ var d = f.rdonly || false;
+ if (f.wronly && !create)
+ d = false;
+ var value = f.value;
+ if (value == null)
+ value = f.default;
+
+ /* Enumerated (combobox) type */
+ if (f.enum) {
+ var cons = Ext.form.ComboBox;
+ if (f.list)
+ cons = Ext.ux.form.LovCombo;
+ var st = tvheadend.idnode_enum_store(f);
+ var r = new cons({
+ fieldLabel: f.caption,
+ name: f.id,
+ value: value,
+ disabled: d,
+ width: 300,
+ mode: 'local',
+ valueField: 'key',
+ displayField: 'val',
+ store: st,
+ typeAhead: true, // TODO: this does strange things in multi
+ forceSelection: false,
+ triggerAction: 'all',
+ emptyText: 'Select ' + f.caption + ' ...',
+ listeners: {
+ beforequery: function(qe) {
+ delete qe.combo.lastQuery;
+ }
+ }
+ });
+ if (st.on) {
+ var fn = function() {
+ st.un('load', fn);
+ r.setValue(value); // HACK: to get extjs to display properly
+ };
+ st.on('load', fn);
}
- }
- });
- if (st.on) {
- var fn = function() {
- st.un('load', fn);
- r.setValue(value); // HACK: to get extjs to display properly
- };
- st.on('load', fn);
+ return r;
+ /* TODO: listeners for regexp?
+ listeners : {
+ keyup: function() {
+ this.store.filter('val', this.getRawValue(), true, false);
+ },
+ beforequery: function(queryEvent) {
+ queryEvent.combo.onLoad();
+ // prevent doQuery from firing and clearing out my filter.
+ return false;
+ }
+ }
+ */
}
- return r;
- /* TODO: listeners for regexp?
- listeners : {
- keyup: function() {
- this.store.filter('val', this.getRawValue(), true, false);
- },
- beforequery: function(queryEvent) {
- queryEvent.combo.onLoad();
- // prevent doQuery from firing and clearing out my filter.
- return false;
- }
+
+ /* Singular */
+ switch (f.type) {
+ case 'str':
+ return new Ext.form.TextField({
+ fieldLabel: f.caption,
+ name: f.id,
+ value: value,
+ disabled: d,
+ width: 300
+ });
+ break;
+
+ case 'bool':
+ return new Ext.ux.form.XCheckbox({
+ fieldLabel: f.caption,
+ name: f.id,
+ checked: value,
+ disabled: d
+ });
+ break;
+
+ case 'int':
+ case 'u32':
+ case 'u16':
+ case 'dbl':
+ return new Ext.form.NumberField({
+ fieldLabel: f.caption,
+ name: f.id,
+ value: value,
+ disabled: d,
+ width: 300
+ });
+ break;
}
- */
- }
-
- /* Singular */
- switch(f.type) {
- case 'str':
- return new Ext.form.TextField({
- fieldLabel : f.caption,
- name : f.id,
- value : value,
- disabled : d,
- width : 300
- });
- break;
-
- case 'bool':
- return new Ext.ux.form.XCheckbox({
- fieldLabel : f.caption,
- name : f.id,
- checked : value,
- disabled : d
- });
- break;
-
- case 'int':
- case 'u32':
- case 'u16':
- case 'dbl':
- return new Ext.form.NumberField({
- fieldLabel : f.caption,
- name : f.id,
- value : value,
- disabled : d,
- width : 300
- });
- break;
- }
- return null;
-}
+ return null;
+};
/*
* ID node editor form fields
*/
-tvheadend.idnode_editor_form = function ( d, panel )
+tvheadend.idnode_editor_form = function(d, panel)
{
- var af = [];
- var rf = [];
- var df = [];
+ var af = [];
+ var rf = [];
+ var df = [];
- /* Fields */
- for (var i = 0; i < d.length; i++) {
- var f = tvheadend.idnode_editor_field(d[i]);
- if (!f) continue;
- if (d[i].rdonly)
- rf.push(f)
- else if (d[i].advanced)
- af.push(f);
- else
- df.push(f);
- }
- if (df.length) {
- panel.add(new Ext.form.FieldSet({
- title : 'Basic Settings',
- autoHeight : true,
- autoWidth : true,
- collapsible : true,
- collapsed : false,
- items : df
- }));
- }
- if (af.length) {
- panel.add(new Ext.form.FieldSet({
- title : 'Advanced Settings',
- autoHeight : true,
- autoWidth : true,
- collapsible : true,
- collapsed : false,//true,
- items : af
- }));
- }
- if (rf.length) {
- panel.add(new Ext.form.FieldSet({
- title : 'Read-only Info',
- autoHeight : true,
- autoWidth : true,
- collapsible : true,
- collapsed : false,//true,
- items : rf
- }));
- }
- panel.doLayout();
-}
+ /* Fields */
+ for (var i = 0; i < d.length; i++) {
+ var f = tvheadend.idnode_editor_field(d[i]);
+ if (!f)
+ continue;
+ if (d[i].rdonly)
+ rf.push(f);
+ else if (d[i].advanced)
+ af.push(f);
+ else
+ df.push(f);
+ }
+ if (df.length) {
+ panel.add(new Ext.form.FieldSet({
+ title: 'Basic Settings',
+ autoHeight: true,
+ autoWidth: true,
+ collapsible: true,
+ collapsed: false,
+ items: df
+ }));
+ }
+ if (af.length) {
+ panel.add(new Ext.form.FieldSet({
+ title: 'Advanced Settings',
+ autoHeight: true,
+ autoWidth: true,
+ collapsible: true,
+ collapsed: false, //true,
+ items: af
+ }));
+ }
+ if (rf.length) {
+ panel.add(new Ext.form.FieldSet({
+ title: 'Read-only Info',
+ autoHeight: true,
+ autoWidth: true,
+ collapsible: true,
+ collapsed: false, //true,
+ items: rf
+ }));
+ }
+ panel.doLayout();
+};
/*
* ID node editor panel
*/
tvheadend.idnode_editor = function(item, conf)
{
- var panel = null;
- var buttons = [];
+ var panel = null;
+ var buttons = [];
- /* Buttons */
- var saveBtn = new Ext.Button({
- text : 'Save',
- handler : function() {
- var node = panel.getForm().getFieldValues();
- node.uuid = item.uuid;
- Ext.Ajax.request({
- url : 'api/idnode/save',
- params : {
- node: Ext.encode(node)
- },
- success : function(d) {
- if (conf.win) conf.win.hide();
+ /* Buttons */
+ var saveBtn = new Ext.Button({
+ text: 'Save',
+ handler: function() {
+ var node = panel.getForm().getFieldValues();
+ node.uuid = item.uuid;
+ Ext.Ajax.request({
+ url: 'api/idnode/save',
+ params: {
+ node: Ext.encode(node)
+ },
+ success: function(d) {
+ if (conf.win)
+ conf.win.hide();
+ }
+ });
}
- });
- }
- });
- buttons.push(saveBtn);
-
- if (conf.help) {
- var helpBtn = new Ext.Button({
- text : 'Help',
- handler : conf.help
});
- buttons.push(helpBtn);
- }
+ buttons.push(saveBtn);
- panel = new Ext.FormPanel({
- title : conf.title || null,
- frame : true,
- border : true,
- bodyStyle : 'padding: 5px',
- labelAlign : 'left',
- labelWidth : 200,
- autoWidth : true,
- autoHeight : !conf.fixedHeight,
- width : 600,
- //defaults: {width: 330},
- defaultType : 'textfield',
- buttonAlign : 'left',
- buttons : buttons
- });
+ if (conf.help) {
+ var helpBtn = new Ext.Button({
+ text: 'Help',
+ handler: conf.help
+ });
+ buttons.push(helpBtn);
+ }
- tvheadend.idnode_editor_form(item.props || item.params, panel);
+ panel = new Ext.FormPanel({
+ title: conf.title || null,
+ frame: true,
+ border: true,
+ bodyStyle: 'padding: 5px',
+ labelAlign: 'left',
+ labelWidth: 200,
+ autoWidth: true,
+ autoHeight: !conf.fixedHeight,
+ width: 600,
+ //defaults: {width: 330},
+ defaultType: 'textfield',
+ buttonAlign: 'left',
+ buttons: buttons
+ });
- return panel;
-}
+ tvheadend.idnode_editor_form(item.props || item.params, panel);
+
+ return panel;
+};
/*
@@ -513,139 +519,139 @@ tvheadend.idnode_editor = function(item, conf)
*/
tvheadend.idnode_create = function(conf)
{
- var puuid = null;
- var panel = null;
- var pclass = null;
+ var puuid = null;
+ var panel = null;
+ var pclass = null;
- /* Buttons */
- var saveBtn = new Ext.Button({
- tooltip : 'Create new entry',
- text : 'Create',
- hidden : true,
- handler : function(){
- params = conf.create.params || {}
- if (puuid)
- params['uuid'] = puuid;
- if (pclass)
- params['class'] = pclass
- params['conf'] = Ext.encode(panel.getForm().getFieldValues());
- Ext.Ajax.request({
- url : conf.create.url || conf.url + '/create',
- params : params,
- success : function(d) {
- win.close();
+ /* Buttons */
+ var saveBtn = new Ext.Button({
+ tooltip: 'Create new entry',
+ text: 'Create',
+ hidden: true,
+ handler: function() {
+ params = conf.create.params || {};
+ if (puuid)
+ params['uuid'] = puuid;
+ if (pclass)
+ params['class'] = pclass;
+ params['conf'] = Ext.encode(panel.getForm().getFieldValues());
+ Ext.Ajax.request({
+ url: conf.create.url || conf.url + '/create',
+ params: params,
+ success: function(d) {
+ win.close();
+ }
+ });
}
- });
- }
- });
- var undoBtn = new Ext.Button({
- tooltip : 'Cancel operation',
- text : 'Cancel',
- handler : function(){
- win.close();
- }
- });
-
- /* Form */
- panel = new Ext.FormPanel({
- frame : true,
- border : true,
- bodyStyle : 'padding: 5px',
- labelAlign : 'left',
- labelWidth : 200,
- autoWidth : true,
- autoHeight : true,
- defaultType : 'textfield',
- buttonAlign : 'left',
- items : [],
- buttons : [ undoBtn, saveBtn ]
- });
-
- /* Create window */
- win = new Ext.Window({
- title : 'Add ' + conf.titleS,
- layout : 'fit',
- autoWidth : true,
- autoHeight : true,
- plain : true,
- items : panel
- });
-
-
- /* Do we need to first select a class? */
- if (conf.select) {
- var store = conf.select.store;
- if (!store) {
- store = new Ext.data.JsonStore({
- root : 'entries',
- url : conf.select.url || conf.url,
- baseParams : conf.select.params,
- fields : [ conf.select.valueField, conf.select.displayField ]
- });
- }
- var select = null;
- if (conf.select.propField) {
- select = function (s, n, o) {
- var r = store.getAt(s.selectedIndex);
- if (r) {
- var d = r.get(conf.select.propField);
- if (d) {
- pclass = r.get(conf.select.valueField);
- win.setTitle('Add ' + s.lastSelectionText);
- panel.remove(s);
- tvheadend.idnode_editor_form(d, panel);
- saveBtn.setVisible(true);
- }
+ });
+ var undoBtn = new Ext.Button({
+ tooltip: 'Cancel operation',
+ text: 'Cancel',
+ handler: function() {
+ win.close();
}
- }
- } else {
- select = function (s, n, o) {
- params = conf.select.clazz.params || {};
- params['uuid'] = puuid = n.id;
- Ext.Ajax.request({
- url : conf.select.clazz.url || conf.select.url || conf.url,
- success : function(d) {
- panel.remove(s);
- d = json_decode(d);
- tvheadend.idnode_editor_form(d.props, panel);
- saveBtn.setVisible(true);
- },
- params : params
+ });
+
+ /* Form */
+ panel = new Ext.FormPanel({
+ frame: true,
+ border: true,
+ bodyStyle: 'padding: 5px',
+ labelAlign: 'left',
+ labelWidth: 200,
+ autoWidth: true,
+ autoHeight: true,
+ defaultType: 'textfield',
+ buttonAlign: 'left',
+ items: [],
+ buttons: [undoBtn, saveBtn]
+ });
+
+ /* Create window */
+ win = new Ext.Window({
+ title: 'Add ' + conf.titleS,
+ layout: 'fit',
+ autoWidth: true,
+ autoHeight: true,
+ plain: true,
+ items: panel
+ });
+
+
+ /* Do we need to first select a class? */
+ if (conf.select) {
+ var store = conf.select.store;
+ if (!store) {
+ store = new Ext.data.JsonStore({
+ root: 'entries',
+ url: conf.select.url || conf.url,
+ baseParams: conf.select.params,
+ fields: [conf.select.valueField, conf.select.displayField]
+ });
+ }
+ var select = null;
+ if (conf.select.propField) {
+ select = function(s, n, o) {
+ var r = store.getAt(s.selectedIndex);
+ if (r) {
+ var d = r.get(conf.select.propField);
+ if (d) {
+ pclass = r.get(conf.select.valueField);
+ win.setTitle('Add ' + s.lastSelectionText);
+ panel.remove(s);
+ tvheadend.idnode_editor_form(d, panel);
+ saveBtn.setVisible(true);
+ }
+ }
+ };
+ } else {
+ select = function(s, n, o) {
+ params = conf.select.clazz.params || {};
+ params['uuid'] = puuid = n.id;
+ Ext.Ajax.request({
+ url: conf.select.clazz.url || conf.select.url || conf.url,
+ success: function(d) {
+ panel.remove(s);
+ d = json_decode(d);
+ tvheadend.idnode_editor_form(d.props, panel);
+ saveBtn.setVisible(true);
+ },
+ params: params
+ });
+ };
+ }
+
+ /* Parent selector */
+ var combo = new Ext.form.ComboBox({
+ fieldLabel: conf.select.label,
+ grow: true,
+ editable: false,
+ allowBlank: false,
+ displayField: conf.select.displayField,
+ valueField: conf.select.valueField,
+ mode: 'remote',
+ triggerAction: 'all',
+ store: store,
+ listeners: {
+ select: select
+ }
});
- };
- }
- /* Parent selector */
- var combo = new Ext.form.ComboBox({
- fieldLabel : conf.select.label,
- grow : true,
- editable : false,
- allowBlank : false,
- displayField : conf.select.displayField,
- valueField : conf.select.valueField,
- mode : 'remote',
- triggerAction : 'all',
- store : store,
- listeners : {
- select : select
- }
- });
-
- panel.add(combo);
- win.show();
- } else {
- Ext.Ajax.request({
- url : conf.url + '/class',
- params : conf.params,
- success : function(d) {
- d = json_decode(d);
- tvheadend.idnode_editor_form(d.props, panel);
- saveBtn.setVisible(true);
+ panel.add(combo);
win.show();
- }
- });
- }
-}
+ } else {
+ Ext.Ajax.request({
+ url: conf.url + '/class',
+ params: conf.params,
+ success: function(d) {
+ d = json_decode(d);
+ tvheadend.idnode_editor_form(d.props, panel);
+ saveBtn.setVisible(true);
+ win.show();
+ }
+ });
+ }
+};
/*
@@ -653,502 +659,506 @@ tvheadend.idnode_create = function(conf)
*/
tvheadend.idnode_grid = function(panel, conf)
{
- function build (d)
- {
- var columns = conf.lcol || [];
- var filters = [];
- var fields = [];
- var buttons = [];
- var plugins = conf.plugins || [];
- var saveBtn = null;
- var undoBtn = null;
- var addBtn = null;
- var delBtn = null;
- var upBtn = null;
- var downBtn = null;
- var editBtn = null;
+ function build(d)
+ {
+ var columns = conf.lcol || [];
+ var filters = [];
+ var fields = [];
+ var buttons = [];
+ var plugins = conf.plugins || [];
+ var saveBtn = null;
+ var undoBtn = null;
+ var addBtn = null;
+ var delBtn = null;
+ var upBtn = null;
+ var downBtn = null;
+ var editBtn = null;
- /* Model */
- var idnode = new tvheadend.IdNode(d);
- for (var i = 0; i < idnode.length(); i++) {
- var f = idnode.field(i);
- var c = f.column();
- fields.push(f.id);
- columns.push(c);
- if (c.filter)
- filters.push(c.filter);
- }
-
- /* Right-hand columns */
- if (conf.rcol)
- for (i = 0; i < conf.rcol.length; i++)
- columns.push(conf.rcol[i])
-
- /* Filters */
- var filter = new Ext.ux.grid.GridFilters({
- encode : true,
- local : false,
- filters : filters
- });
-
- var sort = null;
- if (conf.sort)
- sort = conf.sort;
-
- /* Store */
- var store = new Ext.data.JsonStore({
- root : 'entries',
- url : conf.url + '/grid',
- autoLoad : true,
- id : 'uuid',
- totalProperty : 'total',
- fields : fields,
- remoteSort : true,
- pruneModifiedRecords : true,
- sortInfo : sort
- });
-
- /* Model */
- var sortable = true;
- if (conf.move)
- sortable = false;
- var model = new Ext.grid.ColumnModel({
- defaultSortable : sortable,
- columns : columns
- });
-
- /* Selection */
- var select = new Ext.grid.RowSelectionModel({
- singleSelect : false
- });
-
- /* Event handlers */
- store.on('update', function(s, r, o){
- var d = (s.getModifiedRecords().length == 0);
- undoBtn.setDisabled(d);
- saveBtn.setDisabled(d);
- });
- select.on('selectionchange', function(s){
- if (delBtn)
- delBtn.setDisabled(s.getCount() == 0);
- if (upBtn) {
- upBtn.setDisabled(s.getCount() == 0);
- downBtn.setDisabled(s.getCount() == 0);
- }
- editBtn.setDisabled(s.getCount() != 1);
- if (conf.selected)
- conf.selected(s);
- });
-
- /* Top bar */
- saveBtn = new Ext.Toolbar.Button({
- tooltip : 'Save pending changes (marked with red border)',
- iconCls : 'save',
- text : 'Save',
- disabled : true,
- handler : function(){
- var mr = store.getModifiedRecords();
- var out = new Array();
- for (var x = 0; x < mr.length; x++) {
- v = mr[x].getChanges();
- out[x] = v;
- out[x].uuid = mr[x].id;
+ /* Model */
+ var idnode = new tvheadend.IdNode(d);
+ for (var i = 0; i < idnode.length(); i++) {
+ var f = idnode.field(i);
+ var c = f.column();
+ fields.push(f.id);
+ columns.push(c);
+ if (c.filter)
+ filters.push(c.filter);
}
- Ext.Ajax.request({
- url : 'api/idnode/save',
- params : {
- node: Ext.encode(out)
- },
- success : function(d)
- {
- if (!auto.getValue()) store.reload();
- }
+
+ /* Right-hand columns */
+ if (conf.rcol)
+ for (i = 0; i < conf.rcol.length; i++)
+ columns.push(conf.rcol[i]);
+
+ /* Filters */
+ var filter = new Ext.ux.grid.GridFilters({
+ encode: true,
+ local: false,
+ filters: filters
});
- }
- });
- buttons.push(saveBtn);
- undoBtn = new Ext.Toolbar.Button({
- tooltip : 'Revert pending changes (marked with red border)',
- iconCls : 'undo',
- text : 'Undo',
- disabled : true,
- handler : function() {
- store.rejectChanges();
- }
- });
- buttons.push(undoBtn);
- buttons.push('-');
- if (conf.add) {
- addBtn = new Ext.Toolbar.Button({
- tooltip : 'Add a new entry',
- iconCls : 'add',
- text : 'Add',
- disabled : false,
- handler : function() {
- tvheadend.idnode_create(conf.add);
- }
- });
- buttons.push(addBtn);
- }
- if (conf.del) {
- delBtn = new Ext.Toolbar.Button({
- tooltip : 'Delete selected entries',
- iconCls : 'remove',
- text : 'Delete',
- disabled : true,
- handler : function() {
- var r = select.getSelections();
- if (r && r.length > 0) {
- var uuids = []
- for ( var i = 0; i < r.length; i++ )
- uuids.push(r[i].id)
- Ext.Ajax.request({
- url : 'api/idnode/delete',
- params : {
- uuid: Ext.encode(uuids)
- },
- success : function(d)
- {
- if (!auto.getValue()) store.reload();
- }
- });
- }
- }
- });
- buttons.push(delBtn);
- }
- if (conf.move) {
- upBtn = new Ext.Toolbar.Button({
- tooltip : 'Move selected entries up',
- iconCls : 'moveup',
- text : 'Move Up',
- disabled : true,
- handler : function() {
- var r = select.getSelections();
- if (r && r.length > 0) {
- var uuids = []
- for ( var i = 0; i < r.length; i++ )
- uuids.push(r[i].id)
- Ext.Ajax.request({
- url : 'api/idnode/moveup',
- params : {
- uuid: Ext.encode(uuids)
- },
- success : function(d)
- {
- store.reload();
- }
- });
- }
- }
- });
- buttons.push(upBtn);
- downBtn = new Ext.Toolbar.Button({
- tooltip : 'Move selected entries down',
- iconCls : 'movedown',
- text : 'Move Down',
- disabled : true,
- handler : function() {
- var r = select.getSelections();
- if (r && r.length > 0) {
- var uuids = []
- for ( var i = 0; i < r.length; i++ )
- uuids.push(r[i].id)
- Ext.Ajax.request({
- url : 'api/idnode/movedown',
- params : {
- uuid: Ext.encode(uuids)
- },
- success : function(d)
- {
- store.reload();
- }
- });
- }
- }
- });
- buttons.push(downBtn);
- }
- if (conf.add || conf.del || conf.move)
- buttons.push('-');
- editBtn = new Ext.Toolbar.Button({
- tooltip : 'Edit selected entry',
- iconCls : 'edit',
- text : 'Edit',
- disabled : true,
- handler : function() {
- var r = select.getSelected();
- if (r) {
- if (conf.edittree) {
- var p = tvheadend.idnode_tree({
- url : 'api/idnode/tree',
- params : {
- 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/load',
- params : {
- uuid: r.id
- },
- success : function(d)
- {
- d = json_decode(d);
- var w = null;
- var c = { win: w };
- var p = tvheadend.idnode_editor(d[0], c);
- w = new Ext.Window({
- title : 'Edit ' + conf.titleS,
- layout : 'fit',
- autoWidth : true,
- autoHeight : true,
- plain : true,
- items : p
+
+ var sort = null;
+ if (conf.sort)
+ sort = conf.sort;
+
+ /* Store */
+ var store = new Ext.data.JsonStore({
+ root: 'entries',
+ url: conf.url + '/grid',
+ autoLoad: true,
+ id: 'uuid',
+ totalProperty: 'total',
+ fields: fields,
+ remoteSort: true,
+ pruneModifiedRecords: true,
+ sortInfo: sort
+ });
+
+ /* Model */
+ var sortable = true;
+ if (conf.move)
+ sortable = false;
+ var model = new Ext.grid.ColumnModel({
+ defaultSortable: sortable,
+ columns: columns
+ });
+
+ /* Selection */
+ var select = new Ext.grid.RowSelectionModel({
+ singleSelect: false
+ });
+
+ /* Event handlers */
+ store.on('update', function(s, r, o) {
+ var d = (s.getModifiedRecords().length === 0);
+ undoBtn.setDisabled(d);
+ saveBtn.setDisabled(d);
+ });
+ select.on('selectionchange', function(s) {
+ if (delBtn)
+ delBtn.setDisabled(s.getCount() === 0);
+ if (upBtn) {
+ upBtn.setDisabled(s.getCount() === 0);
+ downBtn.setDisabled(s.getCount() === 0);
+ }
+ editBtn.setDisabled(s.getCount() !== 1);
+ if (conf.selected)
+ conf.selected(s);
+ });
+
+ /* Top bar */
+ saveBtn = new Ext.Toolbar.Button({
+ tooltip: 'Save pending changes (marked with red border)',
+ iconCls: 'save',
+ text: 'Save',
+ disabled: true,
+ handler: function() {
+ var mr = store.getModifiedRecords();
+ var out = new Array();
+ for (var x = 0; x < mr.length; x++) {
+ v = mr[x].getChanges();
+ out[x] = v;
+ out[x].uuid = mr[x].id;
+ }
+ Ext.Ajax.request({
+ url: 'api/idnode/save',
+ params: {
+ node: Ext.encode(out)
+ },
+ success: function(d)
+ {
+ if (!auto.getValue())
+ store.reload();
+ }
});
- c.win = w;
- w.show();
- }
+ }
+ });
+ buttons.push(saveBtn);
+ undoBtn = new Ext.Toolbar.Button({
+ tooltip: 'Revert pending changes (marked with red border)',
+ iconCls: 'undo',
+ text: 'Undo',
+ disabled: true,
+ handler: function() {
+ store.rejectChanges();
+ }
+ });
+ buttons.push(undoBtn);
+ buttons.push('-');
+ if (conf.add) {
+ addBtn = new Ext.Toolbar.Button({
+ tooltip: 'Add a new entry',
+ iconCls: 'add',
+ text: 'Add',
+ disabled: false,
+ handler: function() {
+ tvheadend.idnode_create(conf.add);
+ }
});
- }
+ buttons.push(addBtn);
}
- }
- });
- buttons.push(editBtn);
+ if (conf.del) {
+ delBtn = new Ext.Toolbar.Button({
+ tooltip: 'Delete selected entries',
+ iconCls: 'remove',
+ text: 'Delete',
+ disabled: true,
+ handler: function() {
+ var r = select.getSelections();
+ if (r && r.length > 0) {
+ var uuids = [];
+ for (var i = 0; i < r.length; i++)
+ uuids.push(r[i].id);
+ Ext.Ajax.request({
+ url: 'api/idnode/delete',
+ params: {
+ uuid: Ext.encode(uuids)
+ },
+ success: function(d)
+ {
+ if (!auto.getValue())
+ store.reload();
+ }
+ });
+ }
+ }
+ });
+ buttons.push(delBtn);
+ }
+ if (conf.move) {
+ upBtn = new Ext.Toolbar.Button({
+ tooltip: 'Move selected entries up',
+ iconCls: 'moveup',
+ text: 'Move Up',
+ disabled: true,
+ handler: function() {
+ var r = select.getSelections();
+ if (r && r.length > 0) {
+ var uuids = [];
+ for (var i = 0; i < r.length; i++)
+ uuids.push(r[i].id);
+ Ext.Ajax.request({
+ url: 'api/idnode/moveup',
+ params: {
+ uuid: Ext.encode(uuids)
+ },
+ success: function(d)
+ {
+ store.reload();
+ }
+ });
+ }
+ }
+ });
+ buttons.push(upBtn);
+ downBtn = new Ext.Toolbar.Button({
+ tooltip: 'Move selected entries down',
+ iconCls: 'movedown',
+ text: 'Move Down',
+ disabled: true,
+ handler: function() {
+ var r = select.getSelections();
+ if (r && r.length > 0) {
+ var uuids = [];
+ for (var i = 0; i < r.length; i++)
+ uuids.push(r[i].id);
+ Ext.Ajax.request({
+ url: 'api/idnode/movedown',
+ params: {
+ uuid: Ext.encode(uuids)
+ },
+ success: function(d)
+ {
+ store.reload();
+ }
+ });
+ }
+ }
+ });
+ buttons.push(downBtn);
+ }
+ if (conf.add || conf.del || conf.move)
+ buttons.push('-');
+ editBtn = new Ext.Toolbar.Button({
+ tooltip: 'Edit selected entry',
+ iconCls: 'edit',
+ text: 'Edit',
+ disabled: true,
+ handler: function() {
+ var r = select.getSelected();
+ if (r) {
+ if (conf.edittree) {
+ var p = tvheadend.idnode_tree({
+ url: 'api/idnode/tree',
+ params: {
+ 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/load',
+ params: {
+ uuid: r.id
+ },
+ success: function(d)
+ {
+ d = json_decode(d);
+ var w = null;
+ var c = {win: w};
+ var p = tvheadend.idnode_editor(d[0], c);
+ w = new Ext.Window({
+ title: 'Edit ' + conf.titleS,
+ layout: 'fit',
+ autoWidth: true,
+ autoHeight: true,
+ plain: true,
+ items: p
+ });
+ c.win = w;
+ w.show();
+ }
+ });
+ }
+ }
+ }
+ });
+ buttons.push(editBtn);
- /* Hide Mode */
- if (conf.hidemode) {
- var hidemode = new Ext.form.ComboBox({
- width : 100,
- displayField : 'val',
- valueField : 'key',
- store : new Ext.data.ArrayStore({
- id : 0,
- fields : [ 'key', 'val' ],
- data : [ ['default', 'Parent disabled'],
- ['all', 'All' ],
- ['none', 'None' ] ],
- }),
- value : 'default',
- mode : 'local',
- forceSelection : false,
- triggerAction : 'all',
- listeners : {
- select : function (s, r) {
- store.baseParams.hidemode = r.id;
+ /* Hide Mode */
+ if (conf.hidemode) {
+ var hidemode = new Ext.form.ComboBox({
+ width: 100,
+ displayField: 'val',
+ valueField: 'key',
+ store: new Ext.data.ArrayStore({
+ id: 0,
+ fields: ['key', 'val'],
+ data: [['default', 'Parent disabled'],
+ ['all', 'All'],
+ ['none', 'None']]
+ }),
+ value: 'default',
+ mode: 'local',
+ forceSelection: false,
+ triggerAction: 'all',
+ listeners: {
+ select: function(s, r) {
+ store.baseParams.hidemode = r.id;
+ page.changePage(0);
+ store.reload();
+ }
+ }
+ });
+ buttons.push('-');
+ buttons.push('Hide:');
+ buttons.push(hidemode);
+ }
+ var page = new Ext.PagingToolbar({
+ store: store,
+ pageSize: 50,
+ displayInfo: true,
+ displayMsg: conf.titleP + ' {0} - {1} of {2}',
+ width: 50
+ });
+
+ /* Extra buttons */
+ if (conf.tbar) {
+ buttons.push('-');
+ for (i = 0; i < conf.tbar.length; i++) {
+ if (conf.tbar[i].callback) {
+ conf.tbar[i].handler = function(b, e) {
+ this.callback(this, e, store, select);
+ };
+ }
+ buttons.push(conf.tbar[i]);
+ }
+ }
+
+ /* Help */
+ if (conf.help) {
+ buttons.push('->');
+ buttons.push({
+ text: 'Help',
+ handler: conf.help
+ });
+ }
+
+ /* Grid Panel */
+ var auto = new Ext.form.Checkbox({
+ checked: true,
+ listeners: {
+ check: function(s, c) {
+ if (c)
+ store.reload();
+ }
+ }
+ });
+ var count = new Ext.form.ComboBox({
+ width: 50,
+ displayField: 'val',
+ valueField: 'key',
+ store: new Ext.data.ArrayStore({
+ id: 0,
+ fields: ['key', 'val'],
+ data: [[25, '25'], [50, '50'], [100, '100'],
+ [200, '200'], [9999999999, 'All']]
+ }),
+ value: 50,
+ mode: 'local',
+ forceSelection: false,
+ triggerAction: 'all',
+ listeners: {
+ select: function(s, r) {
+ if (r !== page.pageSize) {
+ page.pageSize = r.id;
+ page.changePage(0);
+ store.reload();
+ // TODO: currently setting pageSize=-1 to disable paging confuses
+ // the UI elements, and I don't know how to sort that!
+ }
+ }
+ }
+ });
+ var page = new Ext.PagingToolbar({
+ store: store,
+ pageSize: 50,
+ displayInfo: true,
+ displayMsg: conf.titleP + ' {0} - {1} of {2}',
+ emptyMsg: 'No ' + conf.titleP.toLowerCase() + ' to display',
+ items: ['-', 'Auto-refresh', auto,
+ '->', '-', 'Per page', count]
+ });
+ plugins.push(filter);
+ var grid = new Ext.grid.EditorGridPanel({
+ stateful: true,
+ stateId: conf.url,
+ stripeRows: true,
+ title: conf.titleP,
+ store: store,
+ cm: model,
+ selModel: select,
+ plugins: plugins,
+ viewConfig: {
+ forceFit: true
+ },
+ tbar: buttons,
+ bbar: page
+ });
+ grid.on('filterupdate', function() {
page.changePage(0);
- store.reload();
- }
- }
- });
- buttons.push('-');
- buttons.push('Hide:');
- buttons.push(hidemode);
- }
- var page = new Ext.PagingToolbar({
- store : store,
- pageSize : 50,
- displayInfo : true,
- displayMsg : conf.titleP + ' {0} - {1} of {2}',
- width : 50,
- });
+ });
- /* Extra buttons */
- if (conf.tbar) {
- buttons.push('-')
- for (i = 0; i < conf.tbar.length; i++) {
- if (conf.tbar[i].callback) {
- conf.tbar[i].handler = function (b, e) {
- this.callback(this, e, store, select);
- }
- }
- buttons.push(conf.tbar[i])
- }
+ if (conf.tabIndex != null)
+ panel.insert(conf.tabIndex, grid);
+ else
+ panel.add(grid);
+
+ /* Add comet listeners */
+ var update = function(o) {
+ if (auto.getValue())
+ store.reload();
+ };
+ if (conf.comet)
+ tvheadend.comet.on(conf.comet, update);
+ tvheadend.comet.on('idnodeUpdated', update);
+ tvheadend.comet.on('idnodeDeleted', update);
}
- /* Help */
- if (conf.help) {
- buttons.push('->');
- buttons.push({
- text : 'Help',
- handler : conf.help
- });
+ /* Request data */
+ if (!conf.fields) {
+ Ext.Ajax.request({
+ url: conf.url + '/class',
+ success: function(d)
+ {
+ var d = json_decode(d);
+ build(d);
+ }
+ });
+ } else {
+ build(conf.fields);
}
+};
- /* Grid Panel */
- var auto = new Ext.form.Checkbox({
- checked : true,
- listeners : {
- check : function ( s, c ) {
- if (c) store.reload();
- }
- }
- });
- var count = new Ext.form.ComboBox({
- width : 50,
- displayField : 'val',
- valueField : 'key',
- store : new Ext.data.ArrayStore({
- id : 0,
- fields : [ 'key', 'val' ],
- data : [[25, '25'], [50, '50'], [100, '100'],
- [200, '200'], [9999999999, 'All']]
- }),
- value : 50,
- mode : 'local',
- forceSelection : false,
- triggerAction : 'all',
- listeners : {
- select : function (s, r) {
- if (r != page.pageSize) {
- page.pageSize = r.id;
- page.changePage(0);
- store.reload();
- // TODO: currently setting pageSize=-1 to disable paging confuses
- // the UI elements, and I don't know how to sort that!
- }
- }
- }
- });
- var page = new Ext.PagingToolbar({
- store : store,
- pageSize : 50,
- displayInfo : true,
- displayMsg : conf.titleP + ' {0} - {1} of {2}',
- emptyMsg : 'No ' + conf.titleP.toLowerCase() + ' to display',
- items : [ '-', 'Auto-refresh', auto,
- '->', '-', 'Per page', count ]
- });
- plugins.push(filter);
- var grid = new Ext.grid.EditorGridPanel({
- stateful : true,
- stateId : conf.url,
- stripeRows : true,
- title : conf.titleP,
- store : store,
- cm : model,
- selModel : select,
- plugins : plugins,
- viewConfig : {
- forceFit : true
- },
- tbar : buttons,
- bbar : page
- });
- grid.on('filterupdate', function() {
- page.changePage(0);
- });
-
- if (conf.tabIndex != null)
- panel.insert(conf.tabIndex, grid);
- else
- panel.add(grid);
-
- /* Add comet listeners */
- var update = function(o) {
- if (auto.getValue())
- store.reload();
- };
- if (conf.comet)
- tvheadend.comet.on(conf.comet, update);
- tvheadend.comet.on('idnodeUpdated', update);
- tvheadend.comet.on('idnodeDeleted', update);
- }
-
- /* Request data */
- if (!conf.fields) {
- Ext.Ajax.request({
- url : conf.url + '/class',
- success : function(d)
- {
- var d = json_decode(d);
- build(d);
- }
- });
- } else {
- build(conf.fields);
- }
-}
-
-tvheadend.idnode_tree = function (conf)
+tvheadend.idnode_tree = function(conf)
{
- var current = null;
- var params = conf.params || {};
- var loader = new Ext.tree.TreeLoader({
- dataUrl : conf.url,
- baseParams : params,
- preloadChildren : conf.preload,
- nodeParameter : 'uuid'
- });
-
- var tree = new Ext.tree.TreePanel({
- loader : loader,
- flex : 1,
- border : false,
- animate : false,
- root : new Ext.tree.AsyncTreeNode({
- id : conf.root || 'root',
- text : conf.title || ''
- }),
- listeners : {
- click: function(n) {
- if(current)
- panel.remove(current);
- if(!n.isRoot)
- current = panel.add(new tvheadend.idnode_editor(n.attributes, {
- title : 'Parameters',
- fixedHeight : true,
- help : conf.help || null,
- }));
- panel.doLayout();
- }
- }
- });
-
- if (conf.comet) {
- tvheadend.comet.on(conf.comet, function(o) {
- if (o.reload)
- tree.getRootNode().reload();
+ var current = null;
+ var params = conf.params || {};
+ var loader = new Ext.tree.TreeLoader({
+ dataUrl: conf.url,
+ baseParams: params,
+ preloadChildren: conf.preload,
+ nodeParameter: 'uuid'
});
- }
- // TODO: top-level reload
- tvheadend.comet.on('idnodeUpdated', function(o) {
- var n = tree.getNodeById(o.uuid);
- if (n) {
- if (o.text) n.setText(o.text);
- tree.getRootNode().reload();
- // cannot get this to properly reload children and maintain state
+ var tree = new Ext.tree.TreePanel({
+ loader: loader,
+ flex: 1,
+ border: false,
+ animate: false,
+ root: new Ext.tree.AsyncTreeNode({
+ id: conf.root || 'root',
+ text: conf.title || ''
+ }),
+ listeners: {
+ click: function(n) {
+ if (current)
+ panel.remove(current);
+ if (!n.isRoot)
+ current = panel.add(new tvheadend.idnode_editor(n.attributes, {
+ title: 'Parameters',
+ fixedHeight: true,
+ help: conf.help || null
+ }));
+ panel.doLayout();
+ }
+ }
+ });
+
+ if (conf.comet) {
+ tvheadend.comet.on(conf.comet, function(o) {
+ if (o.reload)
+ tree.getRootNode().reload();
+ });
}
- });
- var panel = new Ext.Panel({
- title : conf.title || '',
- layout : 'hbox',
- flex : 1,
- padding : 5,
- border : false,
- layoutConfig : {
- align : 'stretch'
- },
- items: [ tree ]
- });
+ // TODO: top-level reload
+ tvheadend.comet.on('idnodeUpdated', function(o) {
+ var n = tree.getNodeById(o.uuid);
+ if (n) {
+ if (o.text)
+ n.setText(o.text);
+ tree.getRootNode().reload();
+ // cannot get this to properly reload children and maintain state
+ }
+ });
+
+ var panel = new Ext.Panel({
+ title: conf.title || '',
+ layout: 'hbox',
+ flex: 1,
+ padding: 5,
+ border: false,
+ layoutConfig: {
+ align: 'stretch'
+ },
+ items: [tree]
+ });
- tree.on('beforerender', function() {
- // To be honest this isn't quite right, but it'll do
- tree.expandAll();
- });
+ tree.on('beforerender', function() {
+ // To be honest this isn't quite right, but it'll do
+ tree.expandAll();
+ });
- return panel;
-}
+ return panel;
+};
diff --git a/src/webui/static/app/iptv.js b/src/webui/static/app/iptv.js
index d5fc6e19..83609b35 100644
--- a/src/webui/static/app/iptv.js
+++ b/src/webui/static/app/iptv.js
@@ -3,316 +3,316 @@
*/
tvheadend.iptv = function(adapterId) {
- var servicetypeStore = new Ext.data.JsonStore({
- root : 'entries',
- id : 'val',
- url : '/iptv/services',
- baseParams : {
- op : 'servicetypeList'
- },
- fields : [ 'val', 'str' ],
- autoLoad : false,
- sortInfo : {
- field : 'channelname',
- direction : 'ASC'
- }
- });
+ var servicetypeStore = new Ext.data.JsonStore({
+ root: 'entries',
+ id: 'val',
+ url: '/iptv/services',
+ baseParams: {
+ op: 'servicetypeList'
+ },
+ fields: ['val', 'str'],
+ autoLoad: false,
+ sortInfo: {
+ field: 'channelname',
+ direction: 'ASC'
+ }
+ });
- var fm = Ext.form;
+ var fm = Ext.form;
- var actions = new Ext.ux.grid.RowActions({
- header : '',
- dataIndex : 'actions',
- width : 45,
- actions : [ {
- iconCls : 'info',
- qtip : 'Detailed information about service',
- cb : function(grid, record, action, row, col) {
- Ext.Ajax.request({
- url : "servicedetails/" + record.id,
- success : function(response, options) {
- r = Ext.util.JSON.decode(response.responseText);
- tvheadend.showTransportDetails(r);
- }
- })
- }
- } ]
- });
+ var actions = new Ext.ux.grid.RowActions({
+ header: '',
+ dataIndex: 'actions',
+ width: 45,
+ actions: [{
+ iconCls: 'info',
+ qtip: 'Detailed information about service',
+ cb: function(grid, record, action, row, col) {
+ Ext.Ajax.request({
+ url: "servicedetails/" + record.id,
+ success: function(response, options) {
+ r = Ext.util.JSON.decode(response.responseText);
+ tvheadend.showTransportDetails(r);
+ }
+ });
+ }
+ }]
+ });
- var cm = new Ext.grid.ColumnModel({
- defaultSortable: true,
- columns : [
- {
- xtype: 'checkcolumn',
- header : "Enabled",
- dataIndex : 'enabled',
- width : 45
- },
- {
- header : "Channel name",
- dataIndex : 'channelname',
- width : 150,
- renderer : function(value, metadata, record, row, col, store) {
- return value ? value
- : '
Unmapped';
- },
- editor : new fm.ComboBox({
- store : tvheadend.channels,
- allowBlank : true,
- typeAhead : true,
- minChars : 2,
- lazyRender : true,
- triggerAction : 'all',
- mode : 'local',
- displayField : 'name'
- })
- },
- {
- header : "Interface",
- dataIndex : 'interface',
- width : 100,
- renderer : function(value, metadata, record, row, col, store) {
- return value ? value : '
Unset';
- },
- editor : new fm.TextField({
- allowBlank : false
- })
- },
- {
- header : "Group",
- dataIndex : 'group',
- width : 100,
- renderer : function(value, metadata, record, row, col, store) {
- return value ? value : '
Unset';
- },
- editor : new fm.TextField({
- allowBlank : false
- })
- },
- {
- header : "UDP Port",
- dataIndex : 'port',
- width : 60,
- editor : new fm.NumberField({
- minValue : 1,
- maxValue : 65535
- })
- },
- {
- header : "Service ID",
- dataIndex : 'sid',
- width : 50,
- hidden : true
- },
- {
- header : 'Service Type',
- width : 100,
- dataIndex : 'stype',
- hidden : true,
- editor : new fm.ComboBox({
- valueField : 'val',
- displayField : 'str',
- forceSelection : false,
- editable : false,
- mode : 'local',
- triggerAction : 'all',
- store : servicetypeStore
- }),
- renderer : function(value, metadata, record, row, col, store) {
- var val = value ? servicetypeStore.getById(value) : null;
- return val ? val.get('str')
- : '
Unset';
- }
- }, {
- header : "PMT PID",
- dataIndex : 'pmt',
- width : 50,
- hidden : true
- }, {
- header : "PCR PID",
- dataIndex : 'pcr',
- width : 50,
- hidden : true
- }, actions ]});
+ var cm = new Ext.grid.ColumnModel({
+ defaultSortable: true,
+ columns: [
+ {
+ xtype: 'checkcolumn',
+ header: "Enabled",
+ dataIndex: 'enabled',
+ width: 45
+ },
+ {
+ header: "Channel name",
+ dataIndex: 'channelname',
+ width: 150,
+ renderer: function(value, metadata, record, row, col, store) {
+ return value ? value
+ : '
Unmapped';
+ },
+ editor: new fm.ComboBox({
+ store: tvheadend.channels,
+ allowBlank: true,
+ typeAhead: true,
+ minChars: 2,
+ lazyRender: true,
+ triggerAction: 'all',
+ mode: 'local',
+ displayField: 'name'
+ })
+ },
+ {
+ header: "Interface",
+ dataIndex: 'interface',
+ width: 100,
+ renderer: function(value, metadata, record, row, col, store) {
+ return value ? value : '
Unset';
+ },
+ editor: new fm.TextField({
+ allowBlank: false
+ })
+ },
+ {
+ header: "Group",
+ dataIndex: 'group',
+ width: 100,
+ renderer: function(value, metadata, record, row, col, store) {
+ return value ? value : '
Unset';
+ },
+ editor: new fm.TextField({
+ allowBlank: false
+ })
+ },
+ {
+ header: "UDP Port",
+ dataIndex: 'port',
+ width: 60,
+ editor: new fm.NumberField({
+ minValue: 1,
+ maxValue: 65535
+ })
+ },
+ {
+ header: "Service ID",
+ dataIndex: 'sid',
+ width: 50,
+ hidden: true
+ },
+ {
+ header: 'Service Type',
+ width: 100,
+ dataIndex: 'stype',
+ hidden: true,
+ editor: new fm.ComboBox({
+ valueField: 'val',
+ displayField: 'str',
+ forceSelection: false,
+ editable: false,
+ mode: 'local',
+ triggerAction: 'all',
+ store: servicetypeStore
+ }),
+ renderer: function(value, metadata, record, row, col, store) {
+ var val = value ? servicetypeStore.getById(value) : null;
+ return val ? val.get('str')
+ : '
Unset';
+ }
+ }, {
+ header: "PMT PID",
+ dataIndex: 'pmt',
+ width: 50,
+ hidden: true
+ }, {
+ header: "PCR PID",
+ dataIndex: 'pcr',
+ width: 50,
+ hidden: true
+ }, actions]});
- var rec = Ext.data.Record.create([ 'id', 'enabled', 'channelname',
- 'interface', 'group', 'port', 'sid', 'pmt', 'pcr', 'stype' ]);
+ var rec = Ext.data.Record.create(['id', 'enabled', 'channelname',
+ 'interface', 'group', 'port', 'sid', 'pmt', 'pcr', 'stype']);
- var store = new Ext.data.JsonStore({
- root : 'entries',
- fields : rec,
- url : "iptv/services",
- autoLoad : true,
- id : 'id',
- baseParams : {
- op : "get"
- },
- listeners : {
- 'update' : function(s, r, o) {
- d = s.getModifiedRecords().length == 0
- saveBtn.setDisabled(d);
- rejectBtn.setDisabled(d);
- }
- }
- });
+ var store = new Ext.data.JsonStore({
+ root: 'entries',
+ fields: rec,
+ url: "iptv/services",
+ autoLoad: true,
+ id: 'id',
+ baseParams: {
+ op: "get"
+ },
+ listeners: {
+ 'update': function(s, r, o) {
+ d = s.getModifiedRecords().length === 0
+ saveBtn.setDisabled(d);
+ rejectBtn.setDisabled(d);
+ }
+ }
+ });
- /*
- var storeReloader = new Ext.util.DelayedTask(function() {
- store.reload()
- });
+ /*
+ var storeReloader = new Ext.util.DelayedTask(function() {
+ store.reload()
+ });
+
+ tvheadend.comet.on('dvbService', function(m) {
+ storeReloader.delay(500);
+ });
+ */
- tvheadend.comet.on('dvbService', function(m) {
- storeReloader.delay(500);
- });
- */
+ function addRecord() {
+ Ext.Ajax.request({
+ url: "iptv/services",
+ params: {
+ op: "create"
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Server Error',
+ 'Unable to generate new record');
+ },
+ success: function(response, options) {
+ var responseData = Ext.util.JSON.decode(response.responseText);
+ var p = new rec(responseData, responseData.id);
+ grid.stopEditing();
+ store.insert(0, p);
+ grid.startEditing(0, 0);
+ }
+ });
+ }
+ ;
- function addRecord() {
- Ext.Ajax.request({
- url : "iptv/services",
- params : {
- op : "create"
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Server Error',
- 'Unable to generate new record');
- },
- success : function(response, options) {
- var responseData = Ext.util.JSON.decode(response.responseText);
- var p = new rec(responseData, responseData.id);
- grid.stopEditing();
- store.insert(0, p);
- grid.startEditing(0, 0);
- }
- })
- }
- ;
+ function delSelected() {
+ var selectedKeys = grid.selModel.selections.keys;
+ if (selectedKeys.length > 0) {
+ Ext.MessageBox.confirm('Message',
+ 'Do you really want to delete selection?', deleteRecord);
+ }
+ else {
+ Ext.MessageBox.alert('Message',
+ 'Please select at least one item to delete');
+ }
+ }
+ ;
- function delSelected() {
- var selectedKeys = grid.selModel.selections.keys;
- if (selectedKeys.length > 0) {
- Ext.MessageBox.confirm('Message',
- 'Do you really want to delete selection?', deleteRecord);
- }
- else {
- Ext.MessageBox.alert('Message',
- 'Please select at least one item to delete');
- }
- }
- ;
+ function deleteRecord(btn) {
+ if (btn === 'yes') {
+ var selectedKeys = grid.selModel.selections.keys;
- function deleteRecord(btn) {
- if (btn == 'yes') {
- var selectedKeys = grid.selModel.selections.keys;
+ Ext.Ajax.request({
+ url: "iptv/services",
+ params: {
+ op: "delete",
+ entries: Ext.encode(selectedKeys)
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Server Error', 'Unable to delete');
+ },
+ success: function(response, options) {
+ store.reload();
+ }
+ });
+ }
+ }
- Ext.Ajax.request({
- url : "iptv/services",
- params : {
- op : "delete",
- entries : Ext.encode(selectedKeys)
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Server Error', 'Unable to delete');
- },
- success : function(response, options) {
- store.reload();
- }
- })
- }
- }
+ function saveChanges() {
+ var mr = store.getModifiedRecords();
+ var out = new Array();
+ for (var x = 0; x < mr.length; x++) {
+ v = mr[x].getChanges();
+ out[x] = v;
+ out[x].id = mr[x].id;
+ }
- function saveChanges() {
- var mr = store.getModifiedRecords();
- var out = new Array();
- for ( var x = 0; x < mr.length; x++) {
- v = mr[x].getChanges();
- out[x] = v;
- out[x].id = mr[x].id;
- }
+ Ext.Ajax.request({
+ url: "iptv/services",
+ params: {
+ op: "update",
+ entries: Ext.encode(out)
+ },
+ success: function(response, options) {
+ store.commitChanges();
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Message', response.statusText);
+ }
+ });
+ }
- Ext.Ajax.request({
- url : "iptv/services",
- params : {
- op : "update",
- entries : Ext.encode(out)
- },
- success : function(response, options) {
- store.commitChanges();
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Message', response.statusText);
- }
- });
- }
+ var delButton = new Ext.Toolbar.Button({
+ tooltip: 'Delete one or more selected rows',
+ iconCls: 'remove',
+ text: 'Delete selected services',
+ handler: delSelected,
+ disabled: true
+ });
- var delButton = new Ext.Toolbar.Button({
- tooltip : 'Delete one or more selected rows',
- iconCls : 'remove',
- text : 'Delete selected services',
- handler : delSelected,
- disabled : true
- });
+ var saveBtn = new Ext.Toolbar.Button({
+ tooltip: 'Save any changes made (Changed cells have red borders).',
+ iconCls: 'save',
+ text: "Save changes",
+ handler: saveChanges,
+ disabled: true
+ });
- var saveBtn = new Ext.Toolbar.Button({
- tooltip : 'Save any changes made (Changed cells have red borders).',
- iconCls : 'save',
- text : "Save changes",
- handler : saveChanges,
- disabled : true
- });
+ var rejectBtn = new Ext.Toolbar.Button({
+ tooltip: 'Revert any changes made (Changed cells have red borders).',
+ iconCls: 'undo',
+ text: "Revert changes",
+ handler: function() {
+ store.rejectChanges();
+ },
+ disabled: true
+ });
- var rejectBtn = new Ext.Toolbar.Button({
- tooltip : 'Revert any changes made (Changed cells have red borders).',
- iconCls : 'undo',
- text : "Revert changes",
- handler : function() {
- store.rejectChanges();
- },
- disabled : true
- });
+ var selModel = new Ext.grid.RowSelectionModel({
+ singleSelect: false
+ });
- var selModel = new Ext.grid.RowSelectionModel({
- singleSelect : false
- });
+ var grid = new Ext.grid.EditorGridPanel({
+ stripeRows: true,
+ title: 'IPTV',
+ iconCls: 'iptv',
+ plugins: [actions],
+ store: store,
+ clicksToEdit: 2,
+ cm: cm,
+ viewConfig: {
+ forceFit: true
+ },
+ selModel: selModel,
+ tbar: [
+ {
+ tooltip: 'Create a new entry on the server. '
+ + 'The new entry is initially disabled so it must be enabled '
+ + 'before it start taking effect.',
+ iconCls: 'add',
+ text: 'Add service',
+ handler: addRecord
+ }, '-', delButton, '-', saveBtn, rejectBtn, '->',
+ {
+ text: 'Help',
+ handler: function() {
+ new tvheadend.help('IPTV', 'config_iptv.html');
+ }
+ }]
+ });
- var grid = new Ext.grid.EditorGridPanel({
- stripeRows : true,
- title : 'IPTV',
- iconCls : 'iptv',
- plugins : [ actions ],
- store : store,
- clicksToEdit : 2,
- cm : cm,
- viewConfig : {
- forceFit : true
- },
- selModel : selModel,
- tbar : [
- {
- tooltip : 'Create a new entry on the server. '
- + 'The new entry is initially disabled so it must be enabled '
- + 'before it start taking effect.',
- iconCls : 'add',
- text : 'Add service',
- handler : addRecord
- }, '-', delButton, '-', saveBtn, rejectBtn, '->',
- {
- text : 'Help',
- handler : function() {
- new tvheadend.help('IPTV', 'config_iptv.html');
- }
- } ]
- });
+ store.on('update', function(s, r, o) {
+ d = s.getModifiedRecords().length === 0;
+ saveBtn.setDisabled(d);
+ rejectBtn.setDisabled(d);
+ });
- store.on('update', function(s, r, o) {
- d = s.getModifiedRecords().length == 0
- saveBtn.setDisabled(d);
- rejectBtn.setDisabled(d);
- });
+ selModel.on('selectionchange', function(self) {
+ delButton.setDisabled(self.getCount() === 0);
+ });
- selModel.on('selectionchange', function(self) {
- delButton.setDisabled(self.getCount() == 0);
- });
-
- return grid;
-}
+ return grid;
+};
diff --git a/src/webui/static/app/mpegts.js b/src/webui/static/app/mpegts.js
index 3249bbec..920ccd3e 100644
--- a/src/webui/static/app/mpegts.js
+++ b/src/webui/static/app/mpegts.js
@@ -3,270 +3,271 @@
*/
tvheadend.network_builders = new Ext.data.JsonStore({
- url : 'api/mpegts/network/builders',
- root : 'entries',
- fields : [ 'class', 'caption', 'props' ],
- id : 'class',
- autoLoad : true,
+ url: 'api/mpegts/network/builders',
+ root: 'entries',
+ fields: ['class', 'caption', 'props'],
+ id: 'class',
+ autoLoad: true
});
tvheadend.network_list = new Ext.data.JsonStore({
- url : 'api/idnode/load',
- baseParams : { class : 'mpegts_network', enum: 1 },
- root : 'entries',
- fields : [ 'key', 'val' ],
- id : 'key',
- autoLoad : true,
+ url: 'api/idnode/load',
+ baseParams: {class: 'mpegts_network', enum: 1},
+ root: 'entries',
+ fields: ['key', 'val'],
+ id: 'key',
+ autoLoad: true
});
tvheadend.comet.on('mpegts_network', function() {
- // TODO: Might be a bit excessive
- tvheadend.network_builders.reload();
- tvheadend.network_list.reload();
+ // TODO: Might be a bit excessive
+ tvheadend.network_builders.reload();
+ tvheadend.network_list.reload();
});
tvheadend.networks = function(panel)
{
- tvheadend.idnode_grid(panel, {
- url : 'api/mpegts/network',
- comet : 'mpegts_network',
- titleS : 'Network',
- titleP : 'Networks',
- tabIndex : 1,
- add : {
- titleS : 'Network',
- select : {
- label : 'Type',
- store : tvheadend.network_builders,
- displayField : 'caption',
- valueField : 'class',
- propField : 'props',
- },
- create : {
- url : 'api/mpegts/network/create'
- }
- },
- del : true,
- sort : {
- field : 'networkname',
- direction : 'ASC'
- }
- });
-}
+ tvheadend.idnode_grid(panel, {
+ url: 'api/mpegts/network',
+ comet: 'mpegts_network',
+ titleS: 'Network',
+ titleP: 'Networks',
+ tabIndex: 1,
+ add: {
+ titleS: 'Network',
+ select: {
+ label: 'Type',
+ store: tvheadend.network_builders,
+ displayField: 'caption',
+ valueField: 'class',
+ propField: 'props'
+ },
+ create: {
+ url: 'api/mpegts/network/create'
+ }
+ },
+ del: true,
+ sort: {
+ field: 'networkname',
+ direction: 'ASC'
+ }
+ });
+};
tvheadend.muxes = function(panel)
{
- tvheadend.idnode_grid(panel, {
- url : 'api/mpegts/mux',
- comet : 'mpegts_mux',
- titleS : 'Mux',
- titleP : 'Muxes',
- tabIndex : 2,
- hidemode : true,
- add : {
- titleS : 'Mux',
- select : {
- label : 'Network',
- store : tvheadend.network_list,
- valueField : 'key',
- displayField : 'val',
- clazz : {
- url : 'api/mpegts/network/mux_class'
+ tvheadend.idnode_grid(panel, {
+ url: 'api/mpegts/mux',
+ comet: 'mpegts_mux',
+ titleS: 'Mux',
+ titleP: 'Muxes',
+ tabIndex: 2,
+ hidemode: true,
+ add: {
+ titleS: 'Mux',
+ select: {
+ label: 'Network',
+ store: tvheadend.network_list,
+ valueField: 'key',
+ displayField: 'val',
+ clazz: {
+ url: 'api/mpegts/network/mux_class'
+ }
+ },
+ create: {
+ url: 'api/mpegts/network/mux_create'
+ }
+ },
+ del: true,
+ lcol: [
+ {
+ width: 50,
+ header: 'Play',
+ renderer: function(v, o, r) {
+ return "
Play";
+ }
+ }
+ ],
+ sort: {
+ field: 'name',
+ direction: 'ASC'
}
- },
- create : {
- url : 'api/mpegts/network/mux_create',
- }
- },
- del : true,
- lcol : [
- {
- width : 50,
- header : 'Play',
- renderer : function(v, o, r) {
- return "
Play";
+ });
+};
+
+tvheadend.show_service_streams = function(data) {
+ var i, j;
+ var html = '';
+
+ function hexstr(d) {
+ return ('0000' + d.toString(16)).slice(-4);
+ }
+
+ function hexstr6(d) {
+ return ('000000' + d.toString(16)).slice(-6);
+ }
+
+ function fixstr(d) {
+ var r = d.toString();
+ var l = r.length;
+ var i;
+ for (i = l; i < 5; i++) {
+ r = ' ' + r;
}
- }
- ],
- sort : {
- field : 'name',
- direction : 'ASC'
+ return r;
}
- });
-}
-tvheadend.show_service_streams = function ( data ) {
- var i, j;
- var html = '';
+ function header( ) {
+ html += '
';
+ html += 'Index | ';
+ html += 'PID | ';
+ html += 'Type | ';
+ html += 'Language | ';
+ html += 'Details | ';
+ html += '';
- function hexstr ( d ) {
- return ('0000' + d.toString(16)).slice(-4);
- }
-
- function hexstr6 ( d ) {
- return ('000000' + d.toString(16)).slice(-6);
- }
-
- function fixstr ( d ) {
- var r = d.toString();
- var l = r.length;
- var i;
- for (i = l; i < 5; i++) {
- r = ' ' + r;
}
- return r;
- }
- function header ( ) {
- html += '';
- html += 'Index | ';
- html += 'PID | ';
- html += 'Type | ';
- html += 'Language | ';
- html += 'Details | ';
- html += '';
-
- }
-
- function single ( s ) {
- html += '' + s + ' |
';
- }
-
- function stream ( s ) {
- var d = ' ';
- var p = '0x' + hexstr(s.pid) + ' / ' + fixstr(s.pid);
-
- html += '';
- html += '' + (s.index > 0 ? s.index : ' ') + ' | ';
- html += '' + p + ' | ';
- html += '' + s.type + ' | ';
- html += '' + (s.language || ' ') + ' | '
- if (s.type == 'CA') {
- d = 'CAIDS: ';
- for (j = 0; j < s.caids.length; j++) {
- if (j > 0) d += ', ';
- d += hexstr(s.caids[j].caid) + ':';
- d += hexstr6(s.caids[j].provider);
- }
+ function single(s) {
+ html += '
' + s + ' |
';
}
- html += '' + d + ' | ';
- html += '';
- }
- header();
+ function stream(s) {
+ var d = ' ';
+ var p = '0x' + hexstr(s.pid) + ' / ' + fixstr(s.pid);
- if (data.streams.length) {
- for (i = 0; i < data.streams.length; i++)
- stream(data.streams[i]);
- } else
- single('None');
+ html += '';
+ html += '' + (s.index > 0 ? s.index : ' ') + ' | ';
+ html += '' + p + ' | ';
+ html += '' + s.type + ' | ';
+ html += '' + (s.language || ' ') + ' | ';
+ if (s.type === 'CA') {
+ d = 'CAIDS: ';
+ for (j = 0; j < s.caids.length; j++) {
+ if (j > 0)
+ d += ', ';
+ d += hexstr(s.caids[j].caid) + ':';
+ d += hexstr6(s.caids[j].provider);
+ }
+ }
+ html += '' + d + ' | ';
+ html += '
';
+ }
- single(' ');
- single('After filtering and reordering (without PCR and PMT)
');
- header();
+ header();
- if (data.fstreams.length)
- for (i = 0; i < data.fstreams.length; i++)
- stream(data.fstreams[i]);
- else
- single('None
');
+ if (data.streams.length) {
+ for (i = 0; i < data.streams.length; i++)
+ stream(data.streams[i]);
+ } else
+ single('None');
- var win = new Ext.Window({
- title : 'Service details for ' + data.name,
- layout : 'fit',
- width : 650,
- height : 400,
- plain : true,
- bodyStyle : 'padding: 5px',
- html : html,
- autoScroll: true,
- autoShow: true
- });
- win.show();
-}
+ single(' ');
+ single('After filtering and reordering (without PCR and PMT)
');
+ header();
+
+ if (data.fstreams.length)
+ for (i = 0; i < data.fstreams.length; i++)
+ stream(data.fstreams[i]);
+ else
+ single('None
');
+
+ var win = new Ext.Window({
+ title: 'Service details for ' + data.name,
+ layout: 'fit',
+ width: 650,
+ height: 400,
+ plain: true,
+ bodyStyle: 'padding: 5px',
+ html: html,
+ autoScroll: true,
+ autoShow: true
+ });
+ win.show();
+};
tvheadend.services = function(panel)
{
- var mapButton = new Ext.Toolbar.Button({
- tooltip : 'Map services to channels',
- iconCls : 'clone',
- text : 'Map All',
- callback : tvheadend.service_mapper,
- disabled : false,
- });
- var selected = function (s)
- {
- if (s.getCount() > 0)
- mapButton.setText('Map Selected')
- else
- mapButton.setText('Map All')
- }
- var actions = new Ext.ux.grid.RowActions({
- header : '',
- width : 10,
- actions : [ {
- iconCls : 'info',
- qtip : 'Detailed stream info',
- cb : function ( grid, rec, act, row, col ) {
- Ext.Ajax.request({
- url : 'api/service/streams',
- params : {
- uuid : rec.id
- },
- success : function (r, o) {
- var d = Ext.util.JSON.decode(r.responseText);
- tvheadend.show_service_streams(d);
- }
- });
- }
- } ]
- });
- tvheadend.idnode_grid(panel, {
- url : 'api/mpegts/service',
- comet : 'service',
- titleS : 'Service',
- titleP : 'Services',
- tabIndex : 3,
- hidemode : true,
- add : false,
- del : false,
- selected : selected,
- tbar : [ mapButton ],
- lcol : [
- {
- width : 50,
- header : 'Play',
- renderer : function(v, o, r) {
- return "Play";
+ var mapButton = new Ext.Toolbar.Button({
+ tooltip: 'Map services to channels',
+ iconCls: 'clone',
+ text: 'Map All',
+ callback: tvheadend.service_mapper,
+ disabled: false
+ });
+ var selected = function(s)
+ {
+ if (s.getCount() > 0)
+ mapButton.setText('Map Selected');
+ else
+ mapButton.setText('Map All');
+ };
+ var actions = new Ext.ux.grid.RowActions({
+ header: '',
+ width: 10,
+ actions: [{
+ iconCls: 'info',
+ qtip: 'Detailed stream info',
+ cb: function(grid, rec, act, row, col) {
+ Ext.Ajax.request({
+ url: 'api/service/streams',
+ params: {
+ uuid: rec.id
+ },
+ success: function(r, o) {
+ var d = Ext.util.JSON.decode(r.responseText);
+ tvheadend.show_service_streams(d);
+ }
+ });
+ }
+ }]
+ });
+ tvheadend.idnode_grid(panel, {
+ url: 'api/mpegts/service',
+ comet: 'service',
+ titleS: 'Service',
+ titleP: 'Services',
+ tabIndex: 3,
+ hidemode: true,
+ add: false,
+ del: false,
+ selected: selected,
+ tbar: [mapButton],
+ lcol: [
+ {
+ width: 50,
+ header: 'Play',
+ renderer: function(v, o, r) {
+ return "Play";
+ }
+ },
+ actions
+ ],
+ plugins: [actions],
+ sort: {
+ field: 'svcname',
+ direction: 'ASC'
}
- },
- actions
- ],
- plugins : [ actions ],
- sort : {
- field : 'svcname',
- direction : 'ASC'
- }
- });
-}
+ });
+};
tvheadend.mux_sched = function(panel)
{
- tvheadend.idnode_grid(panel, {
- url : 'api/mpegts/mux_sched',
- comet : 'mpegts_mux_sched',
- titleS : 'Mux Scheduler',
- titleP : 'Mux Schedulers',
- tabIndex : 4,
- hidemode : true,
- add : {
- url : 'api/mpegts/mux_sched',
- titleS : 'Mux Scheduler',
- create : {
- url : 'api/mpegts/mux_sched/create'
- }
- },
- del : true
- });
-}
+ tvheadend.idnode_grid(panel, {
+ url: 'api/mpegts/mux_sched',
+ comet: 'mpegts_mux_sched',
+ titleS: 'Mux Scheduler',
+ titleP: 'Mux Schedulers',
+ tabIndex: 4,
+ hidemode: true,
+ add: {
+ url: 'api/mpegts/mux_sched',
+ titleS: 'Mux Scheduler',
+ create: {
+ url: 'api/mpegts/mux_sched/create'
+ }
+ },
+ del: true
+ });
+};
diff --git a/src/webui/static/app/servicemapper.js b/src/webui/static/app/servicemapper.js
index 39e5575a..f4e8873d 100644
--- a/src/webui/static/app/servicemapper.js
+++ b/src/webui/static/app/servicemapper.js
@@ -4,182 +4,182 @@
tvheadend.service_mapper_status_panel = null;
-tvheadend.service_mapper_status = function ()
+tvheadend.service_mapper_status = function()
{
- var panel;
+ var panel;
- /* Fields */
- var ok = new Ext.form.Label({
- fieldLabel : 'Mapped',
- text : '0'
- });
- var fail = new Ext.form.Label({
- fieldLabel : 'Failed',
- text : '0'
- });
- var ignore = new Ext.form.Label({
- fieldLabel : 'Ignored',
- text : '0'
- });
- var active = new Ext.form.Label({
- width : 200,
- fieldLabel : 'Active',
- text : ''
- });
- var prog = new Ext.ProgressBar({
- text : '0 / 0'
- });
+ /* Fields */
+ var ok = new Ext.form.Label({
+ fieldLabel: 'Mapped',
+ text: '0'
+ });
+ var fail = new Ext.form.Label({
+ fieldLabel: 'Failed',
+ text: '0'
+ });
+ var ignore = new Ext.form.Label({
+ fieldLabel: 'Ignored',
+ text: '0'
+ });
+ var active = new Ext.form.Label({
+ width: 200,
+ fieldLabel: 'Active',
+ text: ''
+ });
+ var prog = new Ext.ProgressBar({
+ text: '0 / 0'
+ });
- /* Panel */
- panel = new Ext.FormPanel({
- method : 'get',
- title : 'Service Mapper',
- frame : true,
- border : true,
- bodyStyle : 'padding: 5px',
- labelAlign : 'left',
- labelWidth : 200,
- width : 400,
- autoHeight : true,
- defaultType : 'textfield',
- buttonAlign : 'left',
- items : [ ok, ignore, fail, active, prog ]
- });
+ /* Panel */
+ panel = new Ext.FormPanel({
+ method: 'get',
+ title: 'Service Mapper',
+ frame: true,
+ border: true,
+ bodyStyle: 'padding: 5px',
+ labelAlign: 'left',
+ labelWidth: 200,
+ width: 400,
+ autoHeight: true,
+ defaultType: 'textfield',
+ buttonAlign: 'left',
+ items: [ok, ignore, fail, active, prog]
+ });
- /* Comet */
- tvheadend.comet.on('servicemapper', function(m) {
- var n = m.ok + m.ignore + m.fail;
- ok.setText('' + m.ok);
- ignore.setText('' + m.ignore);
- fail.setText('' + m.fail);
- active.setText('');
- prog.updateProgress(n / m.total, '' + n + ' / ' + m.total);
+ /* Comet */
+ tvheadend.comet.on('servicemapper', function(m) {
+ var n = m.ok + m.ignore + m.fail;
+ ok.setText('' + m.ok);
+ ignore.setText('' + m.ignore);
+ fail.setText('' + m.fail);
+ active.setText('');
+ prog.updateProgress(n / m.total, '' + n + ' / ' + m.total);
- if (m.active) {
- Ext.Ajax.request({
- url : 'api/idnode/load',
- params : {
- uuid : m.active
- },
- success : function (d) {
- d = Ext.util.JSON.decode(d.responseText);
- try {
- active.setText(d.entries[0].text);
- } catch (e) {
- }
+ if (m.active) {
+ Ext.Ajax.request({
+ url: 'api/idnode/load',
+ params: {
+ uuid: m.active
+ },
+ success: function(d) {
+ d = Ext.util.JSON.decode(d.responseText);
+ try {
+ active.setText(d.entries[0].text);
+ } catch (e) {
+ }
+ }
+ });
}
- });
- }
- });
+ });
- tvheadend.service_mapper_status_panel = panel;
- return panel;
-}
+ tvheadend.service_mapper_status_panel = panel;
+ return panel;
+};
/*
* Start mapping
*/
tvheadend.service_mapper = function(t, e, store, select)
{
- var panel = null;
- var win = null;
+ var panel = null;
+ var win = null;
- /* Form fields */
- var availCheck = new Ext.form.Checkbox({
- name : 'check_availability',
- fieldLabel : 'Check availability',
- checked : false
- });
- var ftaCheck = new Ext.form.Checkbox({
- name : 'encrypted',
- fieldLabel : 'Include encrypted services',
- checked : false,
- // TODO: make dependent on CSA config
- });
- var mergeCheck = new Ext.form.Checkbox({
- name : 'merge_same_name',
- fieldLabel : 'Merge same name',
- checked : false
- });
- var provtagCheck = new Ext.form.Checkbox({
- name : 'provider_tags',
- fieldLabel : 'Create provider tags',
- checked : false
- });
+ /* Form fields */
+ var availCheck = new Ext.form.Checkbox({
+ name: 'check_availability',
+ fieldLabel: 'Check availability',
+ checked: false
+ });
+ var ftaCheck = new Ext.form.Checkbox({
+ name: 'encrypted',
+ fieldLabel: 'Include encrypted services',
+ checked: false
+ // TODO: make dependent on CSA config
+ });
+ var mergeCheck = new Ext.form.Checkbox({
+ name: 'merge_same_name',
+ fieldLabel: 'Merge same name',
+ checked: false
+ });
+ var provtagCheck = new Ext.form.Checkbox({
+ name: 'provider_tags',
+ fieldLabel: 'Create provider tags',
+ checked: false
+ });
- // TODO: provider list
- items = [ availCheck, ftaCheck, mergeCheck, provtagCheck ];
+ // TODO: provider list
+ items = [availCheck, ftaCheck, mergeCheck, provtagCheck];
- /* Form */
- var undoBtn = new Ext.Button({
- text : 'Cancel',
- handler : function () {
- win.close();
- }
- });
-
- var saveBtn = new Ext.Button({
- text : 'Map',
- tooltip : 'Begin mapping',
- handler : function () {
- p = null;
- if (select) {
- var r = select.getSelections();
- if (r.length > 0) {
- var uuids = [];
- for (var i = 0; i < r.length; i++)
- uuids.push(r[i].id);
- p = { uuids: Ext.encode(uuids) };
+ /* Form */
+ var undoBtn = new Ext.Button({
+ text: 'Cancel',
+ handler: function() {
+ win.close();
}
- }
+ });
+
+ var saveBtn = new Ext.Button({
+ text: 'Map',
+ tooltip: 'Begin mapping',
+ handler: function() {
+ p = null;
+ if (select) {
+ var r = select.getSelections();
+ if (r.length > 0) {
+ var uuids = [];
+ for (var i = 0; i < r.length; i++)
+ uuids.push(r[i].id);
+ p = {uuids: Ext.encode(uuids)};
+ }
+ }
- panel.getForm().submit({
- url : 'api/service/mapper/start',
- waitMessage : 'Mapping services...',
- params : p
- });
+ panel.getForm().submit({
+ url: 'api/service/mapper/start',
+ waitMessage: 'Mapping services...',
+ params: p
+ });
- win.hide();
+ win.hide();
- /* Dialog */
- win = new Ext.Window({
- title : 'Service Mapper Status',
- layout : 'fit',
- autoWidth : true,
- autoHeight : true,
- plain : false,
- items : tvheadend.service_mapper_status_panel
- // TODO: buttons
- });
- win.show();
- }
- });
+ /* Dialog */
+ win = new Ext.Window({
+ title: 'Service Mapper Status',
+ layout: 'fit',
+ autoWidth: true,
+ autoHeight: true,
+ plain: false,
+ items: tvheadend.service_mapper_status_panel
+ // TODO: buttons
+ });
+ win.show();
+ }
+ });
- panel = new Ext.FormPanel({
- method : 'post',
- frame : true,
- border : true,
- bodyStyle : 'padding: 5px',
- labelAlign : 'left',
- labelWidth : 200,
- autoWidth : true,
- autoHeight : true,
- defaultType : 'textfield',
- buttonAlign : 'left',
- items : items,
- buttons : [ undoBtn, saveBtn ]
- });
-
- /* Create window */
- win = new Ext.Window({
- title : 'Map services',
- layout : 'fit',
- autoWidth : true,
- autoHeight : true,
- plain : true,
- items : panel
- });
+ panel = new Ext.FormPanel({
+ method: 'post',
+ frame: true,
+ border: true,
+ bodyStyle: 'padding: 5px',
+ labelAlign: 'left',
+ labelWidth: 200,
+ autoWidth: true,
+ autoHeight: true,
+ defaultType: 'textfield',
+ buttonAlign: 'left',
+ items: items,
+ buttons: [undoBtn, saveBtn]
+ });
- win.show();
-}
+ /* Create window */
+ win = new Ext.Window({
+ title: 'Map services',
+ layout: 'fit',
+ autoWidth: true,
+ autoHeight: true,
+ plain: true,
+ items: panel
+ });
+
+ win.show();
+};
diff --git a/src/webui/static/app/status.js b/src/webui/static/app/status.js
index 546f59bf..80d328f7 100644
--- a/src/webui/static/app/status.js
+++ b/src/webui/static/app/status.js
@@ -3,147 +3,148 @@
*/
tvheadend.status_subs = function() {
- tvheadend.subsStore = new Ext.data.JsonStore({
- root : 'entries',
- totalProperty : 'totalCount',
- fields : [ {
- name : 'id'
- }, {
- name : 'hostname'
- }, {
- name : 'username'
- }, {
- name : 'title'
- }, {
- name : 'channel'
- }, {
- name : 'service'
- }, {
- name : 'state'
- }, {
- name : 'errors'
- }, {
- name : 'in'
- }, {
- name : 'out'
- }, {
- name : 'start',
- type : 'date',
- dateFormat : 'U' /* unix time */
- } ],
- url : 'api/status/subscriptions',
- autoLoad : true,
- id : 'id'
- });
+ tvheadend.subsStore = new Ext.data.JsonStore({
+ root: 'entries',
+ totalProperty: 'totalCount',
+ fields: [{
+ name: 'id'
+ }, {
+ name: 'hostname'
+ }, {
+ name: 'username'
+ }, {
+ name: 'title'
+ }, {
+ name: 'channel'
+ }, {
+ name: 'service'
+ }, {
+ name: 'state'
+ }, {
+ name: 'errors'
+ }, {
+ name: 'in'
+ }, {
+ name: 'out'
+ }, {
+ name: 'start',
+ type: 'date',
+ dateFormat: 'U' /* unix time */
+ }],
+ url: 'api/status/subscriptions',
+ autoLoad: true,
+ id: 'id'
+ });
- tvheadend.comet.on('subscriptions', function(m) {
+ tvheadend.comet.on('subscriptions', function(m) {
- if (m.reload != null) tvheadend.subsStore.reload();
+ if (m.reload != null)
+ tvheadend.subsStore.reload();
- if (m.updateEntry != null) {
- r = tvheadend.subsStore.getById(m.id)
- if (typeof r === 'undefined') {
- tvheadend.subsStore.reload();
- return;
- }
+ if (m.updateEntry != null) {
+ r = tvheadend.subsStore.getById(m.id);
+ if (typeof r === 'undefined') {
+ tvheadend.subsStore.reload();
+ return;
+ }
- r.data.channel = m.channel;
- r.data.service = m.service;
- r.data.state = m.state;
- r.data.errors = m.errors;
- r.data.in = m.in;
- r.data.out = m.out;
+ r.data.channel = m.channel;
+ r.data.service = m.service;
+ r.data.state = m.state;
+ r.data.errors = m.errors;
+ r.data.in = m.in;
+ r.data.out = m.out;
- tvheadend.subsStore.afterEdit(r);
- tvheadend.subsStore.fireEvent('updated', tvheadend.subsStore, r,
- Ext.data.Record.COMMIT);
- }
- });
+ tvheadend.subsStore.afterEdit(r);
+ tvheadend.subsStore.fireEvent('updated', tvheadend.subsStore, r,
+ Ext.data.Record.COMMIT);
+ }
+ });
- function renderDate(value) {
- var dt = new Date(value);
- return dt.format('D j M H:i');
- }
+ function renderDate(value) {
+ var dt = new Date(value);
+ return dt.format('D j M H:i');
+ }
- function renderBw(value, item, store) {
- var txt = parseInt(value / 125);
- var href = 'javascript:tvheadend.subscription_bw_monitor(' + store.id + ');';
- return '' + txt + '';
- }
+ function renderBw(value, item, store) {
+ var txt = parseInt(value / 125);
+ var href = 'javascript:tvheadend.subscription_bw_monitor(' + store.id + ');';
+ return '' + txt + '';
+ }
- var subsCm = new Ext.grid.ColumnModel([{
- width : 50,
- id : 'hostname',
- header : "Hostname",
- dataIndex : 'hostname'
- }, {
- width : 50,
- id : 'username',
- header : "Username",
- dataIndex : 'username'
- }, {
- width : 80,
- id : 'title',
- header : "Title",
- dataIndex : 'title'
- }, {
- width : 50,
- id : 'channel',
- header : "Channel",
- dataIndex : 'channel'
- }, {
- width : 200,
- id : 'service',
- header : "Service",
- dataIndex : 'service',
- }, {
- width : 50,
- id : 'start',
- header : "Start",
- dataIndex : 'start',
- renderer : renderDate
- }, {
- width : 50,
- id : 'state',
- header : "State",
- dataIndex : 'state'
- }, {
- width : 50,
- id : 'errors',
- header : "Errors",
- dataIndex : 'errors'
- }, {
- width : 50,
- id : 'in',
- header : "Input (kb/s)",
- dataIndex : 'in',
- renderer: renderBw
- }, {
- width : 50,
- id : 'out',
- header : "Output (kb/s)",
- dataIndex : 'out',
- renderer: renderBw
- } ]);
+ var subsCm = new Ext.grid.ColumnModel([{
+ width: 50,
+ id: 'hostname',
+ header: "Hostname",
+ dataIndex: 'hostname'
+ }, {
+ width: 50,
+ id: 'username',
+ header: "Username",
+ dataIndex: 'username'
+ }, {
+ width: 80,
+ id: 'title',
+ header: "Title",
+ dataIndex: 'title'
+ }, {
+ width: 50,
+ id: 'channel',
+ header: "Channel",
+ dataIndex: 'channel'
+ }, {
+ width: 200,
+ id: 'service',
+ header: "Service",
+ dataIndex: 'service'
+ }, {
+ width: 50,
+ id: 'start',
+ header: "Start",
+ dataIndex: 'start',
+ renderer: renderDate
+ }, {
+ width: 50,
+ id: 'state',
+ header: "State",
+ dataIndex: 'state'
+ }, {
+ width: 50,
+ id: 'errors',
+ header: "Errors",
+ dataIndex: 'errors'
+ }, {
+ width: 50,
+ id: 'in',
+ header: "Input (kb/s)",
+ dataIndex: 'in',
+ renderer: renderBw
+ }, {
+ width: 50,
+ id: 'out',
+ header: "Output (kb/s)",
+ dataIndex: 'out',
+ renderer: renderBw
+ }]);
- var subs = new Ext.grid.GridPanel({
- border: false,
- loadMask : true,
- stripeRows : true,
- disableSelection : true,
- title : 'Subscriptions',
- iconCls : 'eye',
- store : tvheadend.subsStore,
- cm : subsCm,
- flex: 1,
- viewConfig : {
- forceFit : true
- }
- });
- return subs;
-}
+ var subs = new Ext.grid.GridPanel({
+ border: false,
+ loadMask: true,
+ stripeRows: true,
+ disableSelection: true,
+ title: 'Subscriptions',
+ iconCls: 'eye',
+ store: tvheadend.subsStore,
+ cm: subsCm,
+ flex: 1,
+ viewConfig: {
+ forceFit: true
+ }
+ });
+ return subs;
+};
/**
@@ -151,419 +152,421 @@ tvheadend.status_subs = function() {
*/
tvheadend.status_streams = function() {
- tvheadend.streamStatusStore = new Ext.data.JsonStore({
- root : 'entries',
- totalProperty : 'totalCount',
- fields : [ {
- name : 'uuid'
- }, {
- name : 'input'
- }, {
- name : 'username'
- }, {
- name : 'stream'
- }, {
- name : 'subs'
- }, {
- name : 'weight'
- }, {
- name : 'signal'
- }, {
- name : 'ber'
- }, {
- name : 'unc'
- }, {
- name : 'snr'
- }, {
- name : 'bps'
- }, {
- name : 'cc'
- }, {
- name : 'te'
- },
- ],
- url : 'api/status/inputs',
- autoLoad : true,
- id : 'uuid'
- });
+ tvheadend.streamStatusStore = new Ext.data.JsonStore({
+ root: 'entries',
+ totalProperty: 'totalCount',
+ fields: [{
+ name: 'uuid'
+ }, {
+ name: 'input'
+ }, {
+ name: 'username'
+ }, {
+ name: 'stream'
+ }, {
+ name: 'subs'
+ }, {
+ name: 'weight'
+ }, {
+ name: 'signal'
+ }, {
+ name: 'ber'
+ }, {
+ name: 'unc'
+ }, {
+ name: 'snr'
+ }, {
+ name: 'bps'
+ }, {
+ name: 'cc'
+ }, {
+ name: 'te'
+ }
+ ],
+ url: 'api/status/inputs',
+ autoLoad: true,
+ id: 'uuid'
+ });
- tvheadend.comet.on('input_status', function(m){
- if (m.reload != null) tvheadend.streamStatusStore.reload();
- if (m.update != null) {
- var r = tvheadend.streamStatusStore.getById(m.uuid);
- if (r) {
- r.data.subs = m.subs;
- r.data.weight = m.weight;
- r.data.signal = m.signal;
- r.data.ber = m.ber;
- r.data.unc = m.unc;
- r.data.snr = m.snr;
- r.data.bps = m.bps;
- r.data.cc = m.cc;
- r.data.te = m.te;
+ tvheadend.comet.on('input_status', function(m) {
+ if (m.reload != null)
+ tvheadend.streamStatusStore.reload();
+ if (m.update != null) {
+ var r = tvheadend.streamStatusStore.getById(m.uuid);
+ if (r) {
+ r.data.subs = m.subs;
+ r.data.weight = m.weight;
+ r.data.signal = m.signal;
+ r.data.ber = m.ber;
+ r.data.unc = m.unc;
+ r.data.snr = m.snr;
+ r.data.bps = m.bps;
+ r.data.cc = m.cc;
+ r.data.te = m.te;
- tvheadend.streamStatusStore.afterEdit(r);
- tvheadend.streamStatusStore.fireEvent('updated',
- tvheadend.streamStatusStore,
- r,
- Ext.data.Record.COMMIT);
- } else {
- tvheadend.streamStatusStore.reload();
- }
+ tvheadend.streamStatusStore.afterEdit(r);
+ tvheadend.streamStatusStore.fireEvent('updated',
+ tvheadend.streamStatusStore,
+ r,
+ Ext.data.Record.COMMIT);
+ } else {
+ tvheadend.streamStatusStore.reload();
+ }
+ }
+ });
+
+ var signal = new Ext.ux.grid.ProgressColumn({
+ header: "Signal Strength",
+ dataIndex: 'signal',
+ width: 85,
+ textPst: '%',
+ colored: true
+ });
+
+ function renderBw(value, item, store) {
+ var txt = parseInt(value / 1024);
+ var href = "javascript:tvheadend.stream_bw_monitor('" + store.id + "');";
+ return '' + txt + '';
}
- });
- var signal = new Ext.ux.grid.ProgressColumn({
- header : "Signal Strength",
- dataIndex : 'signal',
- width : 85,
- textPst : '%',
- colored : true
- });
-
- function renderBw(value, item, store) {
- var txt = parseInt(value / 1024);
- var href = "javascript:tvheadend.stream_bw_monitor('" + store.id + "');";
- return '' + txt + '';
- }
-
- var cm = new Ext.grid.ColumnModel([{
- width : 100,
- header : "Input",
- dataIndex : 'input'
- },{
- width : 100,
- header : "Stream",
- dataIndex : 'stream'
- },{
- width : 50,
- header : "Subs #",
- dataIndex : 'subs'
- },{
- width : 50,
- header : "Weight",
- dataIndex : 'weight'
- },{
- width : 50,
- header : "Bandwidth (kb/s)",
- dataIndex : 'bps',
- renderer: renderBw
- },{
- width : 50,
- header : "BER",
- dataIndex : 'ber'
- },{
- width : 50,
- header : "Uncorrected BER",
- dataIndex : 'unc'
- },{
- width : 50,
- header : "Transport Error",
- dataIndex : 'te'
- },{
- width : 50,
- header : "Continuity Error",
- dataIndex : 'cc'
- },{
- width : 50,
- header : "SNR",
- dataIndex : 'snr',
- renderer: function(value) {
- if(value > 0) {
- return value.toFixed(1) + " dB";
- } else {
- return 'Unknown';
- }
+ var cm = new Ext.grid.ColumnModel([{
+ width: 100,
+ header: "Input",
+ dataIndex: 'input'
+ }, {
+ width: 100,
+ header: "Stream",
+ dataIndex: 'stream'
+ }, {
+ width: 50,
+ header: "Subs #",
+ dataIndex: 'subs'
+ }, {
+ width: 50,
+ header: "Weight",
+ dataIndex: 'weight'
+ }, {
+ width: 50,
+ header: "Bandwidth (kb/s)",
+ dataIndex: 'bps',
+ renderer: renderBw
+ }, {
+ width: 50,
+ header: "BER",
+ dataIndex: 'ber'
+ }, {
+ width: 50,
+ header: "Uncorrected BER",
+ dataIndex: 'unc'
+ }, {
+ width: 50,
+ header: "Transport Error",
+ dataIndex: 'te'
+ }, {
+ width: 50,
+ header: "Continuity Error",
+ dataIndex: 'cc'
+ }, {
+ width: 50,
+ header: "SNR",
+ dataIndex: 'snr',
+ renderer: function(value) {
+ if (value > 0) {
+ return value.toFixed(1) + " dB";
+ } else {
+ return 'Unknown';
}
+ }
}, signal]);
- var panel = new Ext.grid.GridPanel({
- border: false,
- loadMask : true,
- stripeRows : true,
- disableSelection : true,
- title : 'Stream',
- iconCls : 'hardware',
- store : tvheadend.streamStatusStore,
- cm : cm,
- flex: 1,
- viewConfig : {
- forceFit : true
- }
- });
- return panel;
-}
+ var panel = new Ext.grid.GridPanel({
+ border: false,
+ loadMask: true,
+ stripeRows: true,
+ disableSelection: true,
+ title: 'Stream',
+ iconCls: 'hardware',
+ store: tvheadend.streamStatusStore,
+ cm: cm,
+ flex: 1,
+ viewConfig: {
+ forceFit: true
+ }
+ });
+ return panel;
+};
/**
*
*/
tvheadend.status_conns = function() {
- var store = new Ext.data.JsonStore({
- root : 'entries',
- totalProperty : 'totalCount',
- fields : [ {
- name : 'id'
- }, {
- name : 'type'
- }, {
- name : 'peer'
- }, {
- name : 'user'
- }, {
- name : 'started',
- type : 'date',
- dateFormat : 'U' /* unix time */
- } ],
- url : 'api/status/connections',
- autoLoad : true,
- id : 'id'
- });
+ var store = new Ext.data.JsonStore({
+ root: 'entries',
+ totalProperty: 'totalCount',
+ fields: [{
+ name: 'id'
+ }, {
+ name: 'type'
+ }, {
+ name: 'peer'
+ }, {
+ name: 'user'
+ }, {
+ name: 'started',
+ type: 'date',
+ dateFormat: 'U' /* unix time */
+ }],
+ url: 'api/status/connections',
+ autoLoad: true,
+ id: 'id'
+ });
- tvheadend.comet.on('connections', function(m) {
- if (m.reload != null) store.reload();
- });
+ tvheadend.comet.on('connections', function(m) {
+ if (m.reload != null)
+ store.reload();
+ });
- function renderDate(value) {
- var dt = new Date(value);
- return dt.format('Y-m-d H:i:s');
- }
+ function renderDate(value) {
+ var dt = new Date(value);
+ return dt.format('Y-m-d H:i:s');
+ }
- var cm = new Ext.grid.ColumnModel([{
- width : 50,
- id : 'type',
- header : "Type",
- dataIndex : 'type'
- }, {
- width : 50,
- id : 'peer',
- header : "IP Address",
- dataIndex : 'peer'
- }, {
- width : 50,
- id : 'user',
- header : "Username",
- dataIndex : 'user'
- }, {
- width : 50,
- id : 'started',
- header : "Started",
- dataIndex : 'started',
- renderer : renderDate
- } ]);
+ var cm = new Ext.grid.ColumnModel([{
+ width: 50,
+ id: 'type',
+ header: "Type",
+ dataIndex: 'type'
+ }, {
+ width: 50,
+ id: 'peer',
+ header: "IP Address",
+ dataIndex: 'peer'
+ }, {
+ width: 50,
+ id: 'user',
+ header: "Username",
+ dataIndex: 'user'
+ }, {
+ width: 50,
+ id: 'started',
+ header: "Started",
+ dataIndex: 'started',
+ renderer: renderDate
+ }]);
- var panel = new Ext.grid.GridPanel({
- border: false,
- loadMask : true,
- stripeRows : true,
- disableSelection : true,
- title : 'Connections',
- iconCls : 'eye',
- store : store,
- cm : cm,
- flex: 1,
- viewConfig : {
- forceFit : true
- }
- });
- return panel;
-}
+ var panel = new Ext.grid.GridPanel({
+ border: false,
+ loadMask: true,
+ stripeRows: true,
+ disableSelection: true,
+ title: 'Connections',
+ iconCls: 'eye',
+ store: store,
+ cm: cm,
+ flex: 1,
+ viewConfig: {
+ forceFit: true
+ }
+ });
+ return panel;
+};
tvheadend.status = function() {
- var panel = new Ext.TabPanel({
- title : 'Status',
- autoScroll : true,
- activeTab : 0,
- iconCls : 'eye',
- items : [
- new tvheadend.status_streams,
- new tvheadend.status_subs,
- new tvheadend.status_conns,
- new tvheadend.service_mapper_status
- ]
- });
- return panel;
-}
+ var panel = new Ext.TabPanel({
+ title: 'Status',
+ autoScroll: true,
+ activeTab: 0,
+ iconCls: 'eye',
+ items: [
+ new tvheadend.status_streams,
+ new tvheadend.status_subs,
+ new tvheadend.status_conns,
+ new tvheadend.service_mapper_status
+ ]
+ });
+ return panel;
+};
tvheadend.subscription_bw_monitor = function(id) {
- var inputSeries = new TimeSeries();
+ var inputSeries = new TimeSeries();
var outputSeries = new TimeSeries();
var chart = new SmoothieChart({
- minValue: 0,
- grid: {
- sharpLines: true,
- fillStyle: 'transparent',
- verticalSections: 0,
- millisPerLine: 0
- },
- labels: {
- disabled: false,
- fillStyle: '#000000',
- fontSize: 12
- }
+ minValue: 0,
+ grid: {
+ sharpLines: true,
+ fillStyle: 'transparent',
+ verticalSections: 0,
+ millisPerLine: 0
+ },
+ labels: {
+ disabled: false,
+ fillStyle: '#000000',
+ fontSize: 12
+ }
});
chart.addTimeSeries(inputSeries, {
- strokeStyle: 'rgb(0, 255, 0)',
- fillStyle: 'rgba(0, 255, 0, 0.5)',
- lineWidth: 3
+ strokeStyle: 'rgb(0, 255, 0)',
+ fillStyle: 'rgba(0, 255, 0, 0.5)',
+ lineWidth: 3
});
chart.addTimeSeries(outputSeries, {
- strokeStyle: 'rgb(255, 0, 255)',
- fillStyle: 'rgba(255, 0, 255, 0.5)',
- lineWidth: 3
+ strokeStyle: 'rgb(255, 0, 255)',
+ fillStyle: 'rgba(255, 0, 255, 0.5)',
+ lineWidth: 3
});
-
+
var inputLbl = new Ext.form.Label();
var outputLbl = new Ext.form.Label();
var comprLbl = new Ext.form.Label();
var win = new Ext.Window({
title: 'Bandwidth monitor',
- layout:'fit',
- resizable: false,
- width : 450 + 30,
- height : 150 + 50,
- constrainHeader : true,
- tbar : [inputLbl, '-', outputLbl, '-', comprLbl],
- items: {
- xtype: 'box',
- autoEl: {
- tag: 'canvas',
- width: 450,
- height: 150
- },
- listeners: {
- render: {
- scope: this,
- fn: function(item) {
- chart.streamTo(item.el.dom, 1000);
- }
- },
- resize: {
- scope: this,
- fn: function(item) {
- chart.render(item.el.dom, 1000);
+ layout: 'fit',
+ resizable: false,
+ width: 450 + 30,
+ height: 150 + 50,
+ constrainHeader: true,
+ tbar: [inputLbl, '-', outputLbl, '-', comprLbl],
+ items: {
+ xtype: 'box',
+ autoEl: {
+ tag: 'canvas',
+ width: 450,
+ height: 150
+ },
+ listeners: {
+ render: {
+ scope: this,
+ fn: function(item) {
+ chart.streamTo(item.el.dom, 1000);
}
- }
- }
- }
+ },
+ resize: {
+ scope: this,
+ fn: function(item) {
+ chart.render(item.el.dom, 1000);
+ }
+ }
+ }
+ }
});
var task = {
- interval: 1000,
- run: function() {
- r = tvheadend.subsStore.getById(id);
- if (typeof r === 'undefined') {
- chart.stop();
- Ext.TaskMgr.stop(task);
- return;
- }
+ interval: 1000,
+ run: function() {
+ r = tvheadend.subsStore.getById(id);
+ if (typeof r === 'undefined') {
+ chart.stop();
+ Ext.TaskMgr.stop(task);
+ return;
+ }
- var input = Math.round(r.data.in / 125);
- var output = Math.round(r.data.out / 125);
- var ratio = new Number(r.data.in / r.data.out).toPrecision(3);
+ var input = Math.round(r.data.in / 125);
+ var output = Math.round(r.data.out / 125);
+ var ratio = new Number(r.data.in / r.data.out).toPrecision(3);
- win.setTitle(r.data.channel);
- inputLbl.setText('In: ' + input + ' kb/s');
- outputLbl.setText('Out: ' + output + ' kb/s');
- comprLbl.setText('Compression ratio: ' + ratio);
+ win.setTitle(r.data.channel);
+ inputLbl.setText('In: ' + input + ' kb/s');
+ outputLbl.setText('Out: ' + output + ' kb/s');
+ comprLbl.setText('Compression ratio: ' + ratio);
- inputSeries.append(new Date().getTime(), input);
- outputSeries.append(new Date().getTime(), output);
- }
+ inputSeries.append(new Date().getTime(), input);
+ outputSeries.append(new Date().getTime(), output);
+ }
};
win.on('close', function() {
- chart.stop();
- Ext.TaskMgr.stop(task);
+ chart.stop();
+ Ext.TaskMgr.stop(task);
});
win.show();
-
+
Ext.TaskMgr.start(task);
};
tvheadend.stream_bw_monitor = function(id) {
- var inputSeries = new TimeSeries();
+ var inputSeries = new TimeSeries();
var chart = new SmoothieChart({
- minValue: 0,
- grid: {
- sharpLines: true,
- fillStyle: 'transparent',
- verticalSections: 0,
- millisPerLine: 0
- },
- labels: {
- disabled: false,
- fillStyle: '#000000',
- fontSize: 12
- }
+ minValue: 0,
+ grid: {
+ sharpLines: true,
+ fillStyle: 'transparent',
+ verticalSections: 0,
+ millisPerLine: 0
+ },
+ labels: {
+ disabled: false,
+ fillStyle: '#000000',
+ fontSize: 12
+ }
});
chart.addTimeSeries(inputSeries, {
- strokeStyle: 'rgb(0, 255, 0)',
- fillStyle: 'rgba(0, 255, 0, 0.5)',
- lineWidth: 3
+ strokeStyle: 'rgb(0, 255, 0)',
+ fillStyle: 'rgba(0, 255, 0, 0.5)',
+ lineWidth: 3
});
var inputLbl = new Ext.form.Label();
var win = new Ext.Window({
title: 'Bandwidth monitor',
- layout:'fit',
- resizable: false,
- width : 450 + 30,
- height : 150 + 50,
- constrainHeader : true,
- tbar : [inputLbl],
- items: {
- xtype: 'box',
- autoEl: {
- tag: 'canvas',
- width: 450,
- height: 150
- },
- listeners: {
- render: {
- scope: this,
- fn: function(item) {
- chart.streamTo(item.el.dom, 1000);
- }
- },
- resize: {
- scope: this,
- fn: function(item) {
- chart.render(item.el.dom, 1000);
+ layout: 'fit',
+ resizable: false,
+ width: 450 + 30,
+ height: 150 + 50,
+ constrainHeader: true,
+ tbar: [inputLbl],
+ items: {
+ xtype: 'box',
+ autoEl: {
+ tag: 'canvas',
+ width: 450,
+ height: 150
+ },
+ listeners: {
+ render: {
+ scope: this,
+ fn: function(item) {
+ chart.streamTo(item.el.dom, 1000);
}
- }
- }
- }
+ },
+ resize: {
+ scope: this,
+ fn: function(item) {
+ chart.render(item.el.dom, 1000);
+ }
+ }
+ }
+ }
});
var task = {
- interval: 1000,
- run: function() {
- r = tvheadend.streamStatusStore.getById(id);
- if (typeof r === 'undefined') {
- chart.stop();
- Ext.TaskMgr.stop(task);
- return;
- }
+ interval: 1000,
+ run: function() {
+ r = tvheadend.streamStatusStore.getById(id);
+ if (typeof r === 'undefined') {
+ chart.stop();
+ Ext.TaskMgr.stop(task);
+ return;
+ }
- win.setTitle(r.data.input + ' (' + r.data.stream + ')');
- var input = Math.round(r.data.bps / 1024);
- inputLbl.setText('Input: ' + input + ' kb/s');
- inputSeries.append(new Date().getTime(), input);
- }
+ win.setTitle(r.data.input + ' (' + r.data.stream + ')');
+ var input = Math.round(r.data.bps / 1024);
+ inputLbl.setText('Input: ' + input + ' kb/s');
+ inputSeries.append(new Date().getTime(), input);
+ }
};
win.on('close', function() {
- chart.stop();
- Ext.TaskMgr.stop(task);
+ chart.stop();
+ Ext.TaskMgr.stop(task);
});
win.show();
diff --git a/src/webui/static/app/tableeditor.js b/src/webui/static/app/tableeditor.js
index c36498d8..92782612 100644
--- a/src/webui/static/app/tableeditor.js
+++ b/src/webui/static/app/tableeditor.js
@@ -1,177 +1,177 @@
tvheadend.tableEditor = function(title, dtable, cm, rec, plugins, store,
- helpContent, icon) {
+ helpContent, icon) {
- if (store == null) {
- store = new Ext.data.JsonStore({
- root : 'entries',
- fields : rec,
- url : "tablemgr",
- autoLoad : true,
- id : 'id',
- baseParams : {
- table : dtable,
- op : "get"
- }
- });
- }
+ if (store == null) {
+ store = new Ext.data.JsonStore({
+ root: 'entries',
+ fields: rec,
+ url: "tablemgr",
+ autoLoad: true,
+ id: 'id',
+ baseParams: {
+ table: dtable,
+ op: "get"
+ }
+ });
+ }
- tvheadend.comet.on(dtable, function(m){
- if (m.reload)
- store.reload();
- });
+ tvheadend.comet.on(dtable, function(m) {
+ if (m.reload)
+ store.reload();
+ });
- function addRecord() {
- Ext.Ajax.request({
- url : "tablemgr",
- params : {
- op : "create",
- table : dtable
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Server Error',
- 'Unable to generate new record');
- },
- success : function(response, options) {
- var responseData = Ext.util.JSON.decode(response.responseText);
- var p = new rec(responseData, responseData.id);
- grid.stopEditing();
- store.insert(0, p);
- grid.startEditing(0, 0);
- }
- })
- }
- ;
+ function addRecord() {
+ Ext.Ajax.request({
+ url: "tablemgr",
+ params: {
+ op: "create",
+ table: dtable
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Server Error',
+ 'Unable to generate new record');
+ },
+ success: function(response, options) {
+ var responseData = Ext.util.JSON.decode(response.responseText);
+ var p = new rec(responseData, responseData.id);
+ grid.stopEditing();
+ store.insert(0, p);
+ grid.startEditing(0, 0);
+ }
+ });
+ }
+ ;
- function delSelected() {
- var selectedKeys = grid.selModel.selections.keys;
- if (selectedKeys.length > 0) {
- Ext.MessageBox.confirm('Message',
- 'Do you really want to delete selection?', deleteRecord);
- }
- else {
- Ext.MessageBox.alert('Message',
- 'Please select at least one item to delete');
- }
- }
- ;
+ function delSelected() {
+ var selectedKeys = grid.selModel.selections.keys;
+ if (selectedKeys.length > 0) {
+ Ext.MessageBox.confirm('Message',
+ 'Do you really want to delete selection?', deleteRecord);
+ }
+ else {
+ Ext.MessageBox.alert('Message',
+ 'Please select at least one item to delete');
+ }
+ }
+ ;
- function deleteRecord(btn) {
- if (btn == 'yes') {
- var selectedKeys = grid.selModel.selections.keys;
+ function deleteRecord(btn) {
+ if (btn === 'yes') {
+ var selectedKeys = grid.selModel.selections.keys;
- Ext.Ajax.request({
- url : "tablemgr",
- params : {
- op : "delete",
- table : dtable,
- entries : Ext.encode(selectedKeys)
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Server Error', 'Unable to delete');
- },
- success : function(response, options) {
- }
- })
- }
- }
+ Ext.Ajax.request({
+ url: "tablemgr",
+ params: {
+ op: "delete",
+ table: dtable,
+ entries: Ext.encode(selectedKeys)
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Server Error', 'Unable to delete');
+ },
+ success: function(response, options) {
+ }
+ });
+ }
+ }
- function saveChanges() {
- var mr = store.getModifiedRecords();
- var out = new Array();
- for ( var x = 0; x < mr.length; x++) {
- v = mr[x].getChanges();
- out[x] = v;
- out[x].id = mr[x].id;
- }
+ function saveChanges() {
+ var mr = store.getModifiedRecords();
+ var out = new Array();
+ for (var x = 0; x < mr.length; x++) {
+ v = mr[x].getChanges();
+ out[x] = v;
+ out[x].id = mr[x].id;
+ }
- Ext.Ajax.request({
- url : "tablemgr",
- params : {
- op : "update",
- table : dtable,
- entries : Ext.encode(out)
- },
- success : function(response, options) {
- // Note: this call is mostly redundant (comet update will pick it up anyway)
- store.commitChanges();
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Message', response.statusText);
- }
- });
- }
+ Ext.Ajax.request({
+ url: "tablemgr",
+ params: {
+ op: "update",
+ table: dtable,
+ entries: Ext.encode(out)
+ },
+ success: function(response, options) {
+ // Note: this call is mostly redundant (comet update will pick it up anyway)
+ store.commitChanges();
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Message', response.statusText);
+ }
+ });
+ }
- var selModel = new Ext.grid.RowSelectionModel({
- singleSelect : false
- });
+ var selModel = new Ext.grid.RowSelectionModel({
+ singleSelect: false
+ });
- var delButton = new Ext.Toolbar.Button({
- tooltip : 'Delete one or more selected rows',
- iconCls : 'remove',
- text : 'Delete selected',
- handler : delSelected,
- disabled : true
- });
+ var delButton = new Ext.Toolbar.Button({
+ tooltip: 'Delete one or more selected rows',
+ iconCls: 'remove',
+ text: 'Delete selected',
+ handler: delSelected,
+ disabled: true
+ });
- var saveBtn = new Ext.Toolbar.Button({
- tooltip : 'Save any changes made (Changed cells have red borders)',
- iconCls : 'save',
- text : "Save changes",
- handler : saveChanges,
- disabled : true
- });
+ var saveBtn = new Ext.Toolbar.Button({
+ tooltip: 'Save any changes made (Changed cells have red borders)',
+ iconCls: 'save',
+ text: "Save changes",
+ handler: saveChanges,
+ disabled: true
+ });
- var rejectBtn = new Ext.Toolbar.Button({
- tooltip : 'Revert any changes made (Changed cells have red borders)',
- iconCls : 'undo',
- text : "Revert changes",
- handler : function() {
- store.rejectChanges();
- },
- disabled : true
- });
+ var rejectBtn = new Ext.Toolbar.Button({
+ tooltip: 'Revert any changes made (Changed cells have red borders)',
+ iconCls: 'undo',
+ text: "Revert changes",
+ handler: function() {
+ store.rejectChanges();
+ },
+ disabled: true
+ });
- store.on('update', function(s, r, o) {
- d = s.getModifiedRecords().length == 0
- saveBtn.setDisabled(d);
- rejectBtn.setDisabled(d);
- });
+ store.on('update', function(s, r, o) {
+ d = s.getModifiedRecords().length === 0;
+ saveBtn.setDisabled(d);
+ rejectBtn.setDisabled(d);
+ });
- selModel.on('selectionchange', function(self) {
- if (self.getCount() > 0) {
- delButton.enable();
- }
- else {
- delButton.disable();
- }
- });
+ selModel.on('selectionchange', function(self) {
+ if (self.getCount() > 0) {
+ delButton.enable();
+ }
+ else {
+ delButton.disable();
+ }
+ });
- var grid = new Ext.grid.EditorGridPanel({
- title : title,
- iconCls : icon,
- plugins : plugins,
- store : store,
- clicksToEdit : 2,
- cm : cm,
- viewConfig : {
- forceFit : true
- },
- selModel : selModel,
- stripeRows : true,
- tbar : [
- {
- tooltip : 'Create a new entry on the server. '
- + 'The new entry is initially disabled so it must be enabled '
- + 'before it start taking effect.',
- iconCls : 'add',
- text : 'Add entry',
- handler : addRecord
- }, '-', delButton, '-', saveBtn, rejectBtn, '->', {
- text : 'Help',
- handler : function() {
- new tvheadend.help(title, helpContent);
- }
- } ]
- });
- return grid;
-}
+ var grid = new Ext.grid.EditorGridPanel({
+ title: title,
+ iconCls: icon,
+ plugins: plugins,
+ store: store,
+ clicksToEdit: 2,
+ cm: cm,
+ viewConfig: {
+ forceFit: true
+ },
+ selModel: selModel,
+ stripeRows: true,
+ tbar: [
+ {
+ tooltip: 'Create a new entry on the server. '
+ + 'The new entry is initially disabled so it must be enabled '
+ + 'before it start taking effect.',
+ iconCls: 'add',
+ text: 'Add entry',
+ handler: addRecord
+ }, '-', delButton, '-', saveBtn, rejectBtn, '->', {
+ text: 'Help',
+ handler: function() {
+ new tvheadend.help(title, helpContent);
+ }
+ }]
+ });
+ return grid;
+};
diff --git a/src/webui/static/app/timeshift.js b/src/webui/static/app/timeshift.js
index 02335006..472312eb 100644
--- a/src/webui/static/app/timeshift.js
+++ b/src/webui/static/app/timeshift.js
@@ -1,152 +1,152 @@
tvheadend.timeshift = function() {
- /* ****************************************************************
- * Data
- * ***************************************************************/
+ /* ****************************************************************
+ * Data
+ * ***************************************************************/
- var confreader = new Ext.data.JsonReader(
- {
- root: 'config'
- },
+ var confreader = new Ext.data.JsonReader(
+ {
+ root: 'config'
+ },
[
- 'timeshift_enabled', 'timeshift_ondemand',
- 'timeshift_path',
- 'timeshift_unlimited_period', 'timeshift_max_period',
- 'timeshift_unlimited_size', 'timeshift_max_size'
+ 'timeshift_enabled', 'timeshift_ondemand',
+ 'timeshift_path',
+ 'timeshift_unlimited_period', 'timeshift_max_period',
+ 'timeshift_unlimited_size', 'timeshift_max_size'
]
- );
-
- /* ****************************************************************
- * Fields
- * ***************************************************************/
+ );
- var timeshiftEnabled = new Ext.form.Checkbox({
- fieldLabel: 'Enabled',
- name: 'timeshift_enabled',
- width: 300
- });
+ /* ****************************************************************
+ * Fields
+ * ***************************************************************/
- var timeshiftOndemand = new Ext.form.Checkbox({
- fieldLabel: 'On-Demand',
- name: 'timeshift_ondemand',
- width: 300
- });
+ var timeshiftEnabled = new Ext.form.Checkbox({
+ fieldLabel: 'Enabled',
+ name: 'timeshift_enabled',
+ width: 300
+ });
- var timeshiftPath = new Ext.form.TextField({
- fieldLabel: 'Storage Path',
- name: 'timeshift_path',
- allowBlank: true,
- width: 300
- });
+ var timeshiftOndemand = new Ext.form.Checkbox({
+ fieldLabel: 'On-Demand',
+ name: 'timeshift_ondemand',
+ width: 300
+ });
- var timeshiftMaxPeriod = new Ext.form.NumberField({
- fieldLabel: 'Max. Period (mins)',
- name: 'timeshift_max_period',
- allowBlank: false,
- width: 300
- });
+ var timeshiftPath = new Ext.form.TextField({
+ fieldLabel: 'Storage Path',
+ name: 'timeshift_path',
+ allowBlank: true,
+ width: 300
+ });
- var timeshiftUnlPeriod = new Ext.form.Checkbox({
- fieldLabel: ' (unlimited)',
- name: 'timeshift_unlimited_period',
- Width: 300
- });
+ var timeshiftMaxPeriod = new Ext.form.NumberField({
+ fieldLabel: 'Max. Period (mins)',
+ name: 'timeshift_max_period',
+ allowBlank: false,
+ width: 300
+ });
- var timeshiftMaxSize = new Ext.form.NumberField({
- fieldLabel: 'Max. Size (MB)',
- name: 'timeshift_max_size',
- allowBlank: false,
- width: 300
- });
+ var timeshiftUnlPeriod = new Ext.form.Checkbox({
+ fieldLabel: ' (unlimited)',
+ name: 'timeshift_unlimited_period',
+ Width: 300
+ });
- var timeshiftUnlSize = new Ext.form.Checkbox({
- fieldLabel: ' (unlimited)',
- name: 'timeshift_unlimited_size',
- Width: 300
- });
+ var timeshiftMaxSize = new Ext.form.NumberField({
+ fieldLabel: 'Max. Size (MB)',
+ name: 'timeshift_max_size',
+ allowBlank: false,
+ width: 300
+ });
- /* ****************************************************************
- * Events
- * ***************************************************************/
+ var timeshiftUnlSize = new Ext.form.Checkbox({
+ fieldLabel: ' (unlimited)',
+ name: 'timeshift_unlimited_size',
+ Width: 300
+ });
- timeshiftUnlPeriod.on('check', function(e, c){
- timeshiftMaxPeriod.setDisabled(c);
- });
- timeshiftUnlSize.on('check', function(e, c){
- timeshiftMaxSize.setDisabled(c);
- });
+ /* ****************************************************************
+ * Events
+ * ***************************************************************/
- /* ****************************************************************
- * Form
- * ***************************************************************/
+ timeshiftUnlPeriod.on('check', function(e, c) {
+ timeshiftMaxPeriod.setDisabled(c);
+ });
+ timeshiftUnlSize.on('check', function(e, c) {
+ timeshiftMaxSize.setDisabled(c);
+ });
- var saveButton = new Ext.Button({
- text : "Save configuration",
- tooltip : 'Save changes made to configuration below',
- iconCls : 'save',
- handler : saveChanges
- });
+ /* ****************************************************************
+ * Form
+ * ***************************************************************/
- var helpButton = new Ext.Button({
- text : 'Help',
- handler : function() {
- new tvheadend.help('Timeshift Configuration', 'config_timeshift.html');
+ var saveButton = new Ext.Button({
+ text: "Save configuration",
+ tooltip: 'Save changes made to configuration below',
+ iconCls: 'save',
+ handler: saveChanges
+ });
+
+ var helpButton = new Ext.Button({
+ text: 'Help',
+ handler: function() {
+ new tvheadend.help('Timeshift Configuration', 'config_timeshift.html');
+ }
+ });
+
+ var confpanel = new Ext.FormPanel({
+ title: 'Timeshift',
+ iconCls: 'clock',
+ border: false,
+ bodyStyle: 'padding:15px',
+ labelAlign: 'left',
+ labelWidth: 150,
+ waitMsgTarget: true,
+ reader: confreader,
+ layout: 'form',
+ defaultType: 'textfield',
+ autoHeight: true,
+ items: [
+ timeshiftEnabled, timeshiftOndemand,
+ timeshiftPath,
+ timeshiftMaxPeriod, timeshiftUnlPeriod,
+ timeshiftMaxSize, timeshiftUnlSize
+ ],
+ tbar: [saveButton, '->', helpButton]
+ });
+
+ /* ****************************************************************
+ * Load/Save
+ * ***************************************************************/
+
+ confpanel.on('render', function() {
+ confpanel.getForm().load({
+ url: 'timeshift',
+ params: {
+ 'op': 'loadSettings'
+ },
+ success: function() {
+ confpanel.enable();
+ timeshiftMaxPeriod.setDisabled(timeshiftUnlPeriod.getValue());
+ timeshiftMaxSize.setDisabled(timeshiftUnlSize.getValue());
+ }
+ });
+ });
+
+ function saveChanges() {
+ confpanel.getForm().submit({
+ url: 'timeshift',
+ params: {
+ op: 'saveSettings'
+ },
+ waitMsg: 'Saving Data...',
+ success: function(form, action) {
+ },
+ failure: function(form, action) {
+ Ext.Msg.alert('Save failed', action.result.errormsg);
+ }
+ });
}
- });
- var confpanel = new Ext.FormPanel({
- title : 'Timeshift',
- iconCls : 'clock',
- border : false,
- bodyStyle : 'padding:15px',
- labelAlign : 'left',
- labelWidth : 150,
- waitMsgTarget : true,
- reader : confreader,
- layout : 'form',
- defaultType : 'textfield',
- autoHeight : true,
- items : [
- timeshiftEnabled, timeshiftOndemand,
- timeshiftPath,
- timeshiftMaxPeriod, timeshiftUnlPeriod,
- timeshiftMaxSize, timeshiftUnlSize
- ],
- tbar : [ saveButton, '->', helpButton ]
- });
-
- /* ****************************************************************
- * Load/Save
- * ***************************************************************/
-
- confpanel.on('render', function() {
- confpanel.getForm().load({
- url: 'timeshift',
- params: {
- 'op': 'loadSettings'
- },
- success: function() {
- confpanel.enable();
- timeshiftMaxPeriod.setDisabled(timeshiftUnlPeriod.getValue());
- timeshiftMaxSize.setDisabled(timeshiftUnlSize.getValue());
- }
- });
- });
-
- function saveChanges() {
- confpanel.getForm().submit({
- url : 'timeshift',
- params : {
- op : 'saveSettings',
- },
- waitMsg : 'Saving Data...',
- success : function(form, action) {
- },
- failure : function(form, action) {
- Ext.Msg.alert('Save failed', action.result.errormsg);
- }
- });
- }
-
- return confpanel;
-}
+ return confpanel;
+};
diff --git a/src/webui/static/app/tvadapters.js b/src/webui/static/app/tvadapters.js
index d3353c09..50e32480 100644
--- a/src/webui/static/app/tvadapters.js
+++ b/src/webui/static/app/tvadapters.js
@@ -1,10 +1,10 @@
tvheadend.tvadapters = function() {
- return tvheadend.idnode_tree( {
- url : 'api/hardware/tree',
- title : 'TV adapters',
- comet : 'hardware',
- help : function() {
- new tvheadend.help('TV adapters', 'config_tvadapters.html');
- }
- });
-}
+ return tvheadend.idnode_tree({
+ url: 'api/hardware/tree',
+ title: 'TV adapters',
+ comet: 'hardware',
+ help: function() {
+ new tvheadend.help('TV adapters', 'config_tvadapters.html');
+ }
+ });
+};
diff --git a/src/webui/static/app/tvheadend.js b/src/webui/static/app/tvheadend.js
index dd9806a9..7fe99e4e 100644
--- a/src/webui/static/app/tvheadend.js
+++ b/src/webui/static/app/tvheadend.js
@@ -1,105 +1,105 @@
tvheadend.accessupdate = null;
-tvheadend.capabilties = null;
-tvheadend.conf_chepg = null;
-tvheadend.conf_dvbin = null;
-tvheadend.conf_tsdvr = null;
-tvheadend.conf_csa = null;
+tvheadend.capabilties = null;
+tvheadend.conf_chepg = null;
+tvheadend.conf_dvbin = null;
+tvheadend.conf_tsdvr = null;
+tvheadend.conf_csa = null;
/* State Provider */
Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
- // 7 days from now
- expires : new Date(new Date().getTime()+(1000*60*60*24*7)),
+ // 7 days from now
+ expires: new Date(new Date().getTime() + (1000 * 60 * 60 * 24 * 7))
}));
/**
* Displays a help popup window
*/
tvheadend.help = function(title, pagename) {
- Ext.Ajax.request({
- url : 'docs/' + pagename,
- success : function(result, request) {
+ Ext.Ajax.request({
+ url: 'docs/' + pagename,
+ success: function(result, request) {
- var content = new Ext.Panel({
- autoScroll : true,
- border : false,
- layout : 'fit',
- html : result.responseText
- });
+ var content = new Ext.Panel({
+ autoScroll: true,
+ border: false,
+ layout: 'fit',
+ html: result.responseText
+ });
- var win = new Ext.Window({
- title : 'Help for ' + title,
- layout : 'fit',
- width : 900,
- height : 400,
- constrainHeader : true,
- items : [ content ]
- });
- win.show();
+ var win = new Ext.Window({
+ title: 'Help for ' + title,
+ layout: 'fit',
+ width: 900,
+ height: 400,
+ constrainHeader: true,
+ items: [content]
+ });
+ win.show();
- }
- });
-}
+ }
+ });
+};
/*
* General capabilities
*/
Ext.Ajax.request({
- url: 'capabilities',
- success: function(d)
- {
- if (d && d.responseText)
- tvheadend.capabilities = Ext.util.JSON.decode(d.responseText);
- if (tvheadend.capabilities && tvheadend.accessupdate)
- accessUpdate(tvheadend.accessUpdate);
-
- }
+ url: 'capabilities',
+ success: function(d)
+ {
+ if (d && d.responseText)
+ tvheadend.capabilities = Ext.util.JSON.decode(d.responseText);
+ if (tvheadend.capabilities && tvheadend.accessupdate)
+ accessUpdate(tvheadend.accessUpdate);
+
+ }
});
/**
* Displays a mediaplayer using the html5 video element
*/
tvheadend.VideoPlayer = function(url) {
-
+
var videoPlayer = new tv.ui.VideoPlayer({
- params: {
- resolution: 384
- }
+ params: {
+ resolution: 384
+ }
});
var selectChannel = new Ext.form.ComboBox({
- loadingText : 'Loading...',
- width : 200,
- displayField : 'val',
- store : tvheadend.channels,
- mode : 'local',
- editable : true,
- triggerAction : 'all',
- emptyText : 'Select channel...'
+ loadingText: 'Loading...',
+ width: 200,
+ displayField: 'val',
+ store: tvheadend.channels,
+ mode: 'local',
+ editable: true,
+ triggerAction: 'all',
+ emptyText: 'Select channel...'
});
-
+
selectChannel.on('select', function(c, r) {
- videoPlayer.zapTo(r.id);
+ videoPlayer.zapTo(r.id);
});
var slider = new Ext.Slider({
- width : 135,
- height : 20,
- value : 90,
- increment : 1,
- minValue : 0,
- maxValue : 100
+ width: 135,
+ height: 20,
+ value: 90,
+ increment: 1,
+ minValue: 0,
+ maxValue: 100
});
var sliderLabel = new Ext.form.Label();
sliderLabel.setText("90%");
slider.addListener('change', function() {
- videoPlayer.setVolume(slider.getValue());
- sliderLabel.setText(videoPlayer.getVolume() + '%');
+ videoPlayer.setVolume(slider.getValue());
+ sliderLabel.setText(videoPlayer.getVolume() + '%');
});
var selectResolution = new Ext.form.ComboBox({
width: 150,
- displayField:'name',
+ displayField: 'name',
valueField: 'res',
value: 384,
mode: 'local',
@@ -107,101 +107,101 @@ tvheadend.VideoPlayer = function(url) {
triggerAction: 'all',
emptyText: 'Select resolution...',
store: new Ext.data.SimpleStore({
- fields: ['res','name'],
+ fields: ['res', 'name'],
id: 0,
data: [
- ['288','288p'],
- ['384','384p'],
- ['480','480p'],
- ['576','576p']
+ ['288', '288p'],
+ ['384', '384p'],
+ ['480', '480p'],
+ ['576', '576p']
]
})
});
selectResolution.on('select', function(c, r) {
- videoPlayer.setResolution(r.data.res);
- if(videoPlayer.isIdle())
- return;
-
- var index = selectChannel.selectedIndex;
- if(index < 0)
- return;
-
- var ch = selectChannel.getStore().getAt(index);
- videoPlayer.zapTo(ch.id);
+ videoPlayer.setResolution(r.data.res);
+ if (videoPlayer.isIdle())
+ return;
+
+ var index = selectChannel.selectedIndex;
+ if (index < 0)
+ return;
+
+ var ch = selectChannel.getStore().getAt(index);
+ videoPlayer.zapTo(ch.id);
});
var win = new Ext.Window({
- title : 'Live TV Player',
- layout : 'fit',
- width : 682 + 14,
- height : 384 + 56,
- constrainHeader : true,
- iconCls : 'eye',
- resizable : true,
- tbar : [
- selectChannel,
- '-',
- {
- iconCls : 'control_play',
- tooltip : 'Play',
- handler : function() {
- if(!videoPlayer.isIdle()) { //probobly paused
- videoPlayer.play();
- return;
- }
+ title: 'Live TV Player',
+ layout: 'fit',
+ width: 682 + 14,
+ height: 384 + 56,
+ constrainHeader: true,
+ iconCls: 'eye',
+ resizable: true,
+ tbar: [
+ selectChannel,
+ '-',
+ {
+ iconCls: 'control_play',
+ tooltip: 'Play',
+ handler: function() {
+ if (!videoPlayer.isIdle()) { //probobly paused
+ videoPlayer.play();
+ return;
+ }
- var index = selectChannel.selectedIndex;
- if(index < 0)
- return;
-
- var ch = selectChannel.getStore().getAt(index);
- videoPlayer.zapTo(ch.id);
- }
- },
- {
- iconCls : 'control_pause',
- tooltip : 'Pause',
- handler : function() {
- videoPlayer.pause();
- }
- },
- {
- iconCls : 'control_stop',
- tooltip : 'Stop',
- handler : function() {
- videoPlayer.stop();
- }
- },
- '-',
- {
- iconCls : 'control_fullscreen',
- tooltip : 'Fullscreen',
- handler : function() {
- videoPlayer.fullscreen();
- }
- },
- '-',
- selectResolution,
- '-',
- {
- iconCls : 'control_volume',
- tooltip : 'Volume',
- disabled : true
- }, ],
- items : [videoPlayer]
+ var index = selectChannel.selectedIndex;
+ if (index < 0)
+ return;
+
+ var ch = selectChannel.getStore().getAt(index);
+ videoPlayer.zapTo(ch.id);
+ }
+ },
+ {
+ iconCls: 'control_pause',
+ tooltip: 'Pause',
+ handler: function() {
+ videoPlayer.pause();
+ }
+ },
+ {
+ iconCls: 'control_stop',
+ tooltip: 'Stop',
+ handler: function() {
+ videoPlayer.stop();
+ }
+ },
+ '-',
+ {
+ iconCls: 'control_fullscreen',
+ tooltip: 'Fullscreen',
+ handler: function() {
+ videoPlayer.fullscreen();
+ }
+ },
+ '-',
+ selectResolution,
+ '-',
+ {
+ iconCls: 'control_volume',
+ tooltip: 'Volume',
+ disabled: true
+ }],
+ items: [videoPlayer]
});
-
+
win.on('beforeShow', function() {
- win.getTopToolbar().add(slider);
- win.getTopToolbar().add(new Ext.Toolbar.Spacer());
- win.getTopToolbar().add(new Ext.Toolbar.Spacer());
- win.getTopToolbar().add(new Ext.Toolbar.Spacer());
- win.getTopToolbar().add(sliderLabel);
+ win.getTopToolbar().add(slider);
+ win.getTopToolbar().add(new Ext.Toolbar.Spacer());
+ win.getTopToolbar().add(new Ext.Toolbar.Spacer());
+ win.getTopToolbar().add(new Ext.Toolbar.Spacer());
+ win.getTopToolbar().add(sliderLabel);
});
-
+
win.on('close', function() {
- videoPlayer.stop();
+ videoPlayer.stop();
});
win.show();
@@ -214,154 +214,154 @@ tvheadend.VideoPlayer = function(url) {
* Obviosuly, access is verified in the server too.
*/
function accessUpdate(o) {
- tvheadend.accessUpdate = o;
- if (!tvheadend.capabilities)
- return;
+ tvheadend.accessUpdate = o;
+ if (!tvheadend.capabilities)
+ return;
- if (o.dvr == true && tvheadend.dvrpanel == null) {
- tvheadend.dvrpanel = new tvheadend.dvr;
- tvheadend.rootTabPanel.add(tvheadend.dvrpanel);
- }
-
- if (o.admin == true && tvheadend.confpanel == null) {
- var tabs1 = [
- new tvheadend.miscconf,
- new tvheadend.acleditor
- ]
- var tabs2;
-
- /* DVB inputs */
- tabs2 = [];
- if (tvheadend.capabilities.indexOf('linuxdvb') != -1 ||
- tvheadend.capabilities.indexOf('v4l') != -1) {
- tabs2.push(new tvheadend.tvadapters);
- }
-/*
- tabs2.push(new tvheadend.iptv);
-*/
- tvheadend.conf_dvbin = new Ext.TabPanel({
- activeTab: 0,
- autoScroll: true,
- title: 'DVB Inputs',
- iconCls: 'hardware',
- items : tabs2
- });
- tvheadend.networks(tvheadend.conf_dvbin);
- tvheadend.muxes(tvheadend.conf_dvbin);
- tvheadend.services(tvheadend.conf_dvbin);
- tvheadend.mux_sched(tvheadend.conf_dvbin);
- tabs1.push(tvheadend.conf_dvbin);
-
- /* Channel / EPG */
- tvheadend.conf_chepg = new Ext.TabPanel({
- activeTab: 0,
- autoScroll: true,
- title : 'Channel / EPG',
- iconCls : 'television',
- items : [
- new tvheadend.cteditor,
- new tvheadend.epggrab
- ]
- });
- tvheadend.channel_tab(tvheadend.conf_chepg);
- tabs1.push(tvheadend.conf_chepg);
-
- /* DVR / Timeshift */
- tabs2 = [ new tvheadend.dvrsettings ];
- if (tvheadend.capabilities.indexOf('timeshift') != -1) {
- tabs2.push(new tvheadend.timeshift)
- }
- tvheadend.conf_tsdvr = new Ext.TabPanel({
- activeTab: 0,
- autoScroll: true,
- title: 'Recording',
- iconCls: 'drive',
- items : tabs2
- });
- tabs1.push(tvheadend.conf_tsdvr);
-
- /* CSA */
- if (tvheadend.capabilities.indexOf('cwc') != -1) {
- tvheadend.conf_csa = new Ext.TabPanel({
- activeTab: 0,
- autoScroll: true,
- title: 'CSA',
- iconCls: 'key',
- items: [
- new tvheadend.cwceditor,
- new tvheadend.capmteditor
- ]
- });
- tabs1.push(tvheadend.conf_csa);
+ if (o.dvr == true && tvheadend.dvrpanel == null) {
+ tvheadend.dvrpanel = new tvheadend.dvr;
+ tvheadend.rootTabPanel.add(tvheadend.dvrpanel);
}
- /* Stream Config */
- tvheadend.conf_stream = new Ext.TabPanel({
- activeTab: 0,
- autoScroll: true,
- title: 'Stream',
- iconCls: 'stream_config',
- items: []
- });
- tvheadend.esfilter_tab(tvheadend.conf_stream);
- tabs1.push(tvheadend.conf_stream);
+ if (o.admin == true && tvheadend.confpanel == null) {
+ var tabs1 = [
+ new tvheadend.miscconf,
+ new tvheadend.acleditor
+ ];
+ var tabs2;
- /* Debug */
- tabs1.push(new tvheadend.tvhlog);
+ /* DVB inputs */
+ tabs2 = [];
+ if (tvheadend.capabilities.indexOf('linuxdvb') !== -1 ||
+ tvheadend.capabilities.indexOf('v4l') !== -1) {
+ tabs2.push(new tvheadend.tvadapters);
+ }
+ /*
+ tabs2.push(new tvheadend.iptv);
+ */
+ tvheadend.conf_dvbin = new Ext.TabPanel({
+ activeTab: 0,
+ autoScroll: true,
+ title: 'DVB Inputs',
+ iconCls: 'hardware',
+ items: tabs2
+ });
+ tvheadend.networks(tvheadend.conf_dvbin);
+ tvheadend.muxes(tvheadend.conf_dvbin);
+ tvheadend.services(tvheadend.conf_dvbin);
+ tvheadend.mux_sched(tvheadend.conf_dvbin);
+ tabs1.push(tvheadend.conf_dvbin);
- tvheadend.confpanel = new Ext.TabPanel({
- activeTab : 0,
- autoScroll : true,
- title : 'Configuration',
- iconCls : 'wrench',
- items : tabs1
- });
+ /* Channel / EPG */
+ tvheadend.conf_chepg = new Ext.TabPanel({
+ activeTab: 0,
+ autoScroll: true,
+ title: 'Channel / EPG',
+ iconCls: 'television',
+ items: [
+ new tvheadend.cteditor,
+ new tvheadend.epggrab
+ ]
+ });
+ tvheadend.channel_tab(tvheadend.conf_chepg);
+ tabs1.push(tvheadend.conf_chepg);
- tvheadend.rootTabPanel.add(tvheadend.confpanel);
- tvheadend.confpanel.doLayout();
- }
+ /* DVR / Timeshift */
+ tabs2 = [new tvheadend.dvrsettings];
+ if (tvheadend.capabilities.indexOf('timeshift') !== -1) {
+ tabs2.push(new tvheadend.timeshift);
+ }
+ tvheadend.conf_tsdvr = new Ext.TabPanel({
+ activeTab: 0,
+ autoScroll: true,
+ title: 'Recording',
+ iconCls: 'drive',
+ items: tabs2
+ });
+ tabs1.push(tvheadend.conf_tsdvr);
- if (o.admin == true && tvheadend.statuspanel == null) {
- tvheadend.statuspanel = new tvheadend.status;
- tvheadend.rootTabPanel.add(tvheadend.statuspanel);
- }
+ /* CSA */
+ if (tvheadend.capabilities.indexOf('cwc') !== -1) {
+ tvheadend.conf_csa = new Ext.TabPanel({
+ activeTab: 0,
+ autoScroll: true,
+ title: 'CSA',
+ iconCls: 'key',
+ items: [
+ new tvheadend.cwceditor,
+ new tvheadend.capmteditor
+ ]
+ });
+ tabs1.push(tvheadend.conf_csa);
+ }
- if (tvheadend.aboutPanel == null) {
- tvheadend.aboutPanel = new Ext.Panel({
- border : false,
- layout : 'fit',
- title : 'About',
- iconCls : 'info',
- autoLoad : 'about.html'
- });
- tvheadend.rootTabPanel.add(tvheadend.aboutPanel);
- }
+ /* Stream Config */
+ tvheadend.conf_stream = new Ext.TabPanel({
+ activeTab: 0,
+ autoScroll: true,
+ title: 'Stream',
+ iconCls: 'stream_config',
+ items: []
+ });
+ tvheadend.esfilter_tab(tvheadend.conf_stream);
+ tabs1.push(tvheadend.conf_stream);
- tvheadend.rootTabPanel.doLayout();
+ /* Debug */
+ tabs1.push(new tvheadend.tvhlog);
+
+ tvheadend.confpanel = new Ext.TabPanel({
+ activeTab: 0,
+ autoScroll: true,
+ title: 'Configuration',
+ iconCls: 'wrench',
+ items: tabs1
+ });
+
+ tvheadend.rootTabPanel.add(tvheadend.confpanel);
+ tvheadend.confpanel.doLayout();
+ }
+
+ if (o.admin == true && tvheadend.statuspanel == null) {
+ tvheadend.statuspanel = new tvheadend.status;
+ tvheadend.rootTabPanel.add(tvheadend.statuspanel);
+ }
+
+ if (tvheadend.aboutPanel == null) {
+ tvheadend.aboutPanel = new Ext.Panel({
+ border: false,
+ layout: 'fit',
+ title: 'About',
+ iconCls: 'info',
+ autoLoad: 'about.html'
+ });
+ tvheadend.rootTabPanel.add(tvheadend.aboutPanel);
+ }
+
+ tvheadend.rootTabPanel.doLayout();
}
/**
*
*/
function setServerIpPort(o) {
- tvheadend.serverIp = o.ip;
- tvheadend.serverPort = o.port;
+ tvheadend.serverIp = o.ip;
+ tvheadend.serverPort = o.port;
}
function makeRTSPprefix() {
- return 'rtsp://' + tvheadend.serverIp + ':' + tvheadend.serverPort + '/';
+ return 'rtsp://' + tvheadend.serverIp + ':' + tvheadend.serverPort + '/';
}
/**
*
*/
tvheadend.log = function(msg, style) {
- s = style ? '' : '
'
+ s = style ? '
' : '
';
- sl = Ext.get('systemlog');
- e = Ext.DomHelper.append(sl, s + '
' + msg + '
');
- e.scrollIntoView('systemlog');
-}
+ sl = Ext.get('systemlog');
+ e = Ext.DomHelper.append(sl, s + '
' + msg + '
');
+ e.scrollIntoView('systemlog');
+};
/**
*
@@ -369,73 +369,72 @@ tvheadend.log = function(msg, style) {
//create application
tvheadend.app = function() {
- // public space
- return {
+ // public space
+ return {
+ // public methods
+ init: function() {
+ var header = new Ext.Panel({
+ split: true,
+ region: 'north',
+ height: 45,
+ boxMaxHeight: 45,
+ boxMinHeight: 45,
+ border: false,
+ hidden: true,
+ html: ''
+ });
- // public methods
- init : function() {
- var header = new Ext.Panel({
- split: true,
- region: 'north',
- height : 45,
- boxMaxHeight : 45,
- boxMinHeight : 45,
- border: false,
- hidden: true,
- html: ''
- });
-
- tvheadend.rootTabPanel = new Ext.TabPanel({
- region : 'center',
- activeTab : 0,
- items : [ new tvheadend.epg ]
- });
+ tvheadend.rootTabPanel = new Ext.TabPanel({
+ region: 'center',
+ activeTab: 0,
+ items: [new tvheadend.epg]
+ });
- var viewport = new Ext.Viewport({
- layout : 'border',
- items : [{
- region : 'south',
- contentEl : 'systemlog',
- split : true,
- autoScroll : true,
- height : 150,
- minSize : 100,
- maxSize : 400,
- collapsible : true,
- collapsed : true,
- title : 'System log',
- margins : '0 0 0 0',
- tools : [ {
- id : 'gear',
- qtip : 'Enable debug output',
- handler : function(event, toolEl, panel) {
- Ext.Ajax.request({
- url : 'comet/debug',
- params : {
- boxid : tvheadend.boxid
- }
- });
- }
- } ]
- }, tvheadend.rootTabPanel, header ]
- });
+ var viewport = new Ext.Viewport({
+ layout: 'border',
+ items: [{
+ region: 'south',
+ contentEl: 'systemlog',
+ split: true,
+ autoScroll: true,
+ height: 150,
+ minSize: 100,
+ maxSize: 400,
+ collapsible: true,
+ collapsed: true,
+ title: 'System log',
+ margins: '0 0 0 0',
+ tools: [{
+ id: 'gear',
+ qtip: 'Enable debug output',
+ handler: function(event, toolEl, panel) {
+ Ext.Ajax.request({
+ url: 'comet/debug',
+ params: {
+ boxid: tvheadend.boxid
+ }
+ });
+ }
+ }]
+ }, tvheadend.rootTabPanel, header]
+ });
- tvheadend.comet.on('accessUpdate', accessUpdate);
+ tvheadend.comet.on('accessUpdate', accessUpdate);
- tvheadend.comet.on('setServerIpPort', setServerIpPort);
+ tvheadend.comet.on('setServerIpPort', setServerIpPort);
- tvheadend.comet.on('logmessage', function(m) {
- tvheadend.log(m.logtxt);
- });
+ tvheadend.comet.on('logmessage', function(m) {
+ tvheadend.log(m.logtxt);
+ });
- new tvheadend.cometPoller;
+ new tvheadend.cometPoller;
- Ext.QuickTips.init();
+ Ext.QuickTips.init();
- // Load the chart library smoothie.js, as used by the bandwidth monitor.
- Ext.Loader.load('static/smoothie.js');
- }
+ // Load the chart library smoothie.js, as used by the bandwidth monitor.
+ Ext.Loader.load('static/smoothie.js');
+ }
- };
+ };
}(); // end of app
diff --git a/src/webui/static/app/tvhlog.js b/src/webui/static/app/tvhlog.js
index 2d344ad5..d5c6e92c 100644
--- a/src/webui/static/app/tvhlog.js
+++ b/src/webui/static/app/tvhlog.js
@@ -1,110 +1,110 @@
tvheadend.tvhlog = function() {
- /*
- * Basic Config
- */
- var confreader = new Ext.data.JsonReader({
- root : 'config'
- }, [ 'tvhlog_path', 'tvhlog_dbg_syslog', 'tvhlog_trace_on',
- 'tvhlog_debug', 'tvhlog_trace' ]);
+ /*
+ * Basic Config
+ */
+ var confreader = new Ext.data.JsonReader({
+ root: 'config'
+ }, ['tvhlog_path', 'tvhlog_dbg_syslog', 'tvhlog_trace_on',
+ 'tvhlog_debug', 'tvhlog_trace']);
- /* ****************************************************************
- * Form Fields
- * ***************************************************************/
+ /* ****************************************************************
+ * Form Fields
+ * ***************************************************************/
- var tvhlogLogPath = new Ext.form.TextField({
- fieldLabel : 'Debug Log Path',
- name : 'tvhlog_path',
- allowBlank : true,
- width: 400
- });
+ var tvhlogLogPath = new Ext.form.TextField({
+ fieldLabel: 'Debug Log Path',
+ name: 'tvhlog_path',
+ allowBlank: true,
+ width: 400
+ });
- var tvhlogToSyslog = new Ext.form.Checkbox({
- name: 'tvhlog_dbg_syslog',
- fieldLabel: 'Debug to syslog'
- });
-
- var tvhlogTraceOn = new Ext.form.Checkbox({
- name: 'tvhlog_trace_on',
- fieldLabel: 'Debug trace (low-level stuff)'
- });
+ var tvhlogToSyslog = new Ext.form.Checkbox({
+ name: 'tvhlog_dbg_syslog',
+ fieldLabel: 'Debug to syslog'
+ });
- var tvhlogDebugSubsys = new Ext.form.TextField({
- fieldLabel : 'Debug Subsystems',
- name : 'tvhlog_debug',
- allowBlank : true,
- width: 400
- });
+ var tvhlogTraceOn = new Ext.form.Checkbox({
+ name: 'tvhlog_trace_on',
+ fieldLabel: 'Debug trace (low-level stuff)'
+ });
- var tvhlogTraceSubsys = new Ext.form.TextField({
- fieldLabel : 'Trace Subsystems',
- name : 'tvhlog_trace',
- allowBlank : true,
- width: 400
- });
+ var tvhlogDebugSubsys = new Ext.form.TextField({
+ fieldLabel: 'Debug Subsystems',
+ name: 'tvhlog_debug',
+ allowBlank: true,
+ width: 400
+ });
- /* ****************************************************************
- * Form
- * ***************************************************************/
+ var tvhlogTraceSubsys = new Ext.form.TextField({
+ fieldLabel: 'Trace Subsystems',
+ name: 'tvhlog_trace',
+ allowBlank: true,
+ width: 400
+ });
- var saveButton = new Ext.Button({
- text : "Save configuration",
- tooltip : 'Save changes made to configuration below',
- iconCls : 'save',
- handler : saveChanges
- });
+ /* ****************************************************************
+ * Form
+ * ***************************************************************/
- var helpButton = new Ext.Button({
- text : 'Help',
- handler : function() {
- new tvheadend.help('Debug Configuration', 'config_tvhlog.html');
- }
- });
+ var saveButton = new Ext.Button({
+ text: "Save configuration",
+ tooltip: 'Save changes made to configuration below',
+ iconCls: 'save',
+ handler: saveChanges
+ });
- var confpanel = new Ext.form.FormPanel({
- title : 'Debugging',
- iconCls : 'wrench',
- border : false,
- bodyStyle : 'padding:15px',
- labelAlign : 'left',
- labelWidth : 200,
- waitMsgTarget : true,
- reader : confreader,
- layout : 'form',
- defaultType : 'textfield',
- autoHeight : true,
- items : [ tvhlogLogPath, tvhlogToSyslog,
- tvhlogTraceOn, tvhlogDebugSubsys, tvhlogTraceSubsys ],
- tbar : [ saveButton, '->', helpButton ]
- });
+ var helpButton = new Ext.Button({
+ text: 'Help',
+ handler: function() {
+ new tvheadend.help('Debug Configuration', 'config_tvhlog.html');
+ }
+ });
- /* ****************************************************************
- * Load/Save
- * ***************************************************************/
+ var confpanel = new Ext.form.FormPanel({
+ title: 'Debugging',
+ iconCls: 'wrench',
+ border: false,
+ bodyStyle: 'padding:15px',
+ labelAlign: 'left',
+ labelWidth: 200,
+ waitMsgTarget: true,
+ reader: confreader,
+ layout: 'form',
+ defaultType: 'textfield',
+ autoHeight: true,
+ items: [tvhlogLogPath, tvhlogToSyslog,
+ tvhlogTraceOn, tvhlogDebugSubsys, tvhlogTraceSubsys],
+ tbar: [saveButton, '->', helpButton]
+ });
- confpanel.on('render', function() {
- confpanel.getForm().load({
- url : 'tvhlog',
- params : {
- op : 'loadSettings'
- },
- success : function(form, action) {
- confpanel.enable();
- }
- });
- });
+ /* ****************************************************************
+ * Load/Save
+ * ***************************************************************/
- function saveChanges() {
- confpanel.getForm().submit({
- url : 'tvhlog',
- params : {
- op : 'saveSettings'
- },
- waitMsg : 'Saving Data...',
- failure : function(form, action) {
- Ext.Msg.alert('Save failed', action.result.errormsg);
- }
- });
- }
+ confpanel.on('render', function() {
+ confpanel.getForm().load({
+ url: 'tvhlog',
+ params: {
+ op: 'loadSettings'
+ },
+ success: function(form, action) {
+ confpanel.enable();
+ }
+ });
+ });
- return confpanel;
-}
+ function saveChanges() {
+ confpanel.getForm().submit({
+ url: 'tvhlog',
+ params: {
+ op: 'saveSettings'
+ },
+ waitMsg: 'Saving Data...',
+ failure: function(form, action) {
+ Ext.Msg.alert('Save failed', action.result.errormsg);
+ }
+ });
+ }
+
+ return confpanel;
+};
diff --git a/src/webui/static/app/v4l.js b/src/webui/static/app/v4l.js
index d755d714..ab355e10 100644
--- a/src/webui/static/app/v4l.js
+++ b/src/webui/static/app/v4l.js
@@ -3,320 +3,319 @@
*/
tvheadend.v4l_adapter_general = function(adapterData) {
- adapterId = adapterData.identifier;
+ adapterId = adapterData.identifier;
- /* Conf panel */
+ /* Conf panel */
- var confreader = new Ext.data.JsonReader({
- root : 'v4ladapters'
- }, [ 'name', 'logging' ]);
+ var confreader = new Ext.data.JsonReader({
+ root: 'v4ladapters'
+ }, ['name', 'logging']);
- function saveConfForm() {
- confform.getForm().submit({
- url : 'v4l/adapter/' + adapterId,
- params : {
- 'op' : 'save'
- },
- waitMsg : 'Saving Data...'
- });
- }
+ function saveConfForm() {
+ confform.getForm().submit({
+ url: 'v4l/adapter/' + adapterId,
+ params: {
+ 'op': 'save'
+ },
+ waitMsg: 'Saving Data...'
+ });
+ }
- var items = [ {
- fieldLabel : 'Adapter name',
- name : 'name',
- width : 250
- }, new Ext.form.Checkbox({
- fieldLabel : 'Detailed logging',
- name : 'logging'
- }) ];
+ var items = [{
+ fieldLabel: 'Adapter name',
+ name: 'name',
+ width: 250
+ }, new Ext.form.Checkbox({
+ fieldLabel: 'Detailed logging',
+ name: 'logging'
+ })];
- var confform = new Ext.FormPanel({
- title : 'Adapter configuration',
- columnWidth : .40,
- frame : true,
- border : true,
- disabled : true,
- style : 'margin:10px',
- bodyStyle : 'padding:5px',
- labelAlign : 'right',
- labelWidth : 110,
- waitMsgTarget : true,
- reader : confreader,
- defaultType : 'textfield',
- items : items,
- buttons : [ {
- text : 'Save',
- handler : saveConfForm
- } ]
- });
+ var confform = new Ext.FormPanel({
+ title: 'Adapter configuration',
+ columnWidth: .40,
+ frame: true,
+ border: true,
+ disabled: true,
+ style: 'margin:10px',
+ bodyStyle: 'padding:5px',
+ labelAlign: 'right',
+ labelWidth: 110,
+ waitMsgTarget: true,
+ reader: confreader,
+ defaultType: 'textfield',
+ items: items,
+ buttons: [{
+ text: 'Save',
+ handler: saveConfForm
+ }]
+ });
- confform.getForm().load({
- url : 'v4l/adapter/' + adapterId,
- params : {
- 'op' : 'load'
- },
- success : function(form, action) {
- confform.enable();
- }
- });
+ confform.getForm().load({
+ url: 'v4l/adapter/' + adapterId,
+ params: {
+ 'op': 'load'
+ },
+ success: function(form, action) {
+ confform.enable();
+ }
+ });
- /**
- * Information / capabilities panel
- */
+ /**
+ * Information / capabilities panel
+ */
- var infoTemplate = new Ext.XTemplate(
- '
Hardware
'
- + '
Device path:
{path}' + '
Device name:
{devicename}'
- + '
Status
'
- + '
Currently tuned to:
{currentMux} ');
+ var infoTemplate = new Ext.XTemplate(
+ '
Hardware
'
+ + '
Device path:
{path}' + '
Device name:
{devicename}'
+ + '
Status
'
+ + '
Currently tuned to:
{currentMux} ');
- var infoPanel = new Ext.Panel({
- title : 'Information and capabilities',
- columnWidth : .35,
- frame : true,
- border : true,
- style : 'margin:10px',
- bodyStyle : 'padding:5px',
- html : infoTemplate.applyTemplate(adapterData)
- });
+ var infoPanel = new Ext.Panel({
+ title: 'Information and capabilities',
+ columnWidth: .35,
+ frame: true,
+ border: true,
+ style: 'margin:10px',
+ bodyStyle: 'padding:5px',
+ html: infoTemplate.applyTemplate(adapterData)
+ });
- /**
- * Main adapter panel
- */
- var panel = new Ext.Panel({
- title : 'General',
- layout : 'column',
- items : [ confform, infoPanel ]
- });
+ /**
+ * Main adapter panel
+ */
+ var panel = new Ext.Panel({
+ title: 'General',
+ layout: 'column',
+ items: [confform, infoPanel]
+ });
- /**
- * Subscribe and react on updates for this adapter
- */
- tvheadend.tvAdapterStore.on('update', function(s, r, o) {
- if (r.data.identifier != adapterId) return;
- infoTemplate.overwrite(infoPanel.body, r.data);
- });
+ /**
+ * Subscribe and react on updates for this adapter
+ */
+ tvheadend.tvAdapterStore.on('update', function(s, r, o) {
+ if (r.data.identifier !== adapterId)
+ return;
+ infoTemplate.overwrite(infoPanel.body, r.data);
+ });
- return panel;
-}
+ return panel;
+};
/**
* V4L service grid
*/
tvheadend.v4l_services = function(adapterId) {
- var fm = Ext.form;
+ var fm = Ext.form;
- var enabledColumn = new Ext.grid.CheckColumn({
- header : "Enabled",
- dataIndex : 'enabled',
- width : 45
- });
+ var enabledColumn = new Ext.grid.CheckColumn({
+ header: "Enabled",
+ dataIndex: 'enabled',
+ width: 45
+ });
- var cm = new Ext.grid.ColumnModel({
- defaultSortable: true,
- columns : [
- enabledColumn, {
- header : "Channel name",
- dataIndex : 'channelname',
- width : 150,
- renderer : function(value, metadata, record, row, col, store) {
- return value ? value : '
Unmapped';
- },
- editor : new fm.ComboBox({
- store : tvheadend.channels,
- allowBlank : true,
- typeAhead : true,
- minChars : 2,
- lazyRender : true,
- triggerAction : 'all',
- mode : 'local',
- displayField : 'name'
- })
- }, {
- header : "Frequency",
- dataIndex : 'frequency',
- width : 60,
- editor : new fm.NumberField({
- minValue : 10000,
- maxValue : 1000000000
- })
- } ]});
+ var cm = new Ext.grid.ColumnModel({
+ defaultSortable: true,
+ columns: [
+ enabledColumn, {
+ header: "Channel name",
+ dataIndex: 'channelname',
+ width: 150,
+ renderer: function(value, metadata, record, row, col, store) {
+ return value ? value : '
Unmapped';
+ },
+ editor: new fm.ComboBox({
+ store: tvheadend.channels,
+ allowBlank: true,
+ typeAhead: true,
+ minChars: 2,
+ lazyRender: true,
+ triggerAction: 'all',
+ mode: 'local',
+ displayField: 'name'
+ })
+ }, {
+ header: "Frequency",
+ dataIndex: 'frequency',
+ width: 60,
+ editor: new fm.NumberField({
+ minValue: 10000,
+ maxValue: 1000000000
+ })
+ }]});
- var rec = Ext.data.Record.create([ 'id', 'enabled', 'channelname',
- 'frequency' ]);
+ var rec = Ext.data.Record.create(['id', 'enabled', 'channelname',
+ 'frequency']);
- var store = new Ext.data.JsonStore({
- root : 'entries',
- fields : rec,
- url : "v4l/services/" + adapterId,
- autoLoad : true,
- id : 'id',
- baseParams : {
- op : "get"
- },
- listeners : {
- 'update' : function(s, r, o) {
- d = s.getModifiedRecords().length == 0
- saveBtn.setDisabled(d);
- rejectBtn.setDisabled(d);
- }
- }
- });
+ var store = new Ext.data.JsonStore({
+ root: 'entries',
+ fields: rec,
+ url: "v4l/services/" + adapterId,
+ autoLoad: true,
+ id: 'id',
+ baseParams: {
+ op: "get"
+ },
+ listeners: {
+ 'update': function(s, r, o) {
+ d = s.getModifiedRecords().length === 0;
+ saveBtn.setDisabled(d);
+ rejectBtn.setDisabled(d);
+ }
+ }
+ });
- function addRecord() {
- Ext.Ajax.request({
- url : "v4l/services/" + adapterId,
- params : {
- op : "create"
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Server Error',
- 'Unable to generate new record');
- },
- success : function(response, options) {
- var responseData = Ext.util.JSON.decode(response.responseText);
- var p = new rec(responseData, responseData.id);
- grid.stopEditing();
- store.insert(0, p);
- grid.startEditing(0, 0);
- }
- })
- }
- ;
+ function addRecord() {
+ Ext.Ajax.request({
+ url: "v4l/services/" + adapterId,
+ params: {
+ op: "create"
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Server Error',
+ 'Unable to generate new record');
+ },
+ success: function(response, options) {
+ var responseData = Ext.util.JSON.decode(response.responseText);
+ var p = new rec(responseData, responseData.id);
+ grid.stopEditing();
+ store.insert(0, p);
+ grid.startEditing(0, 0);
+ }
+ });
+ };
- function delSelected() {
- var selectedKeys = grid.selModel.selections.keys;
- if (selectedKeys.length > 0) {
- Ext.MessageBox.confirm('Message',
- 'Do you really want to delete selection?', deleteRecord);
- }
- else {
- Ext.MessageBox.alert('Message',
- 'Please select at least one item to delete');
- }
- }
- ;
+ function delSelected() {
+ var selectedKeys = grid.selModel.selections.keys;
+ if (selectedKeys.length > 0) {
+ Ext.MessageBox.confirm('Message',
+ 'Do you really want to delete selection?', deleteRecord);
+ }
+ else {
+ Ext.MessageBox.alert('Message',
+ 'Please select at least one item to delete');
+ }
+ };
- function deleteRecord(btn) {
- if (btn == 'yes') {
- var selectedKeys = grid.selModel.selections.keys;
+ function deleteRecord(btn) {
+ if (btn === 'yes') {
+ var selectedKeys = grid.selModel.selections.keys;
- Ext.Ajax.request({
- url : "v4l/services/" + adapterId,
- params : {
- op : "delete",
- entries : Ext.encode(selectedKeys)
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Server Error', 'Unable to delete');
- },
- success : function(response, options) {
- store.reload();
- }
- })
- }
- }
+ Ext.Ajax.request({
+ url: "v4l/services/" + adapterId,
+ params: {
+ op: "delete",
+ entries: Ext.encode(selectedKeys)
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Server Error', 'Unable to delete');
+ },
+ success: function(response, options) {
+ store.reload();
+ }
+ });
+ }
+ }
- function saveChanges() {
- var mr = store.getModifiedRecords();
- var out = new Array();
- for ( var x = 0; x < mr.length; x++) {
- v = mr[x].getChanges();
- out[x] = v;
- out[x].id = mr[x].id;
- }
+ function saveChanges() {
+ var mr = store.getModifiedRecords();
+ var out = new Array();
+ for (var x = 0; x < mr.length; x++) {
+ v = mr[x].getChanges();
+ out[x] = v;
+ out[x].id = mr[x].id;
+ }
- Ext.Ajax.request({
- url : "v4l/services/" + adapterId,
- params : {
- op : "update",
- entries : Ext.encode(out)
- },
- success : function(response, options) {
- store.commitChanges();
- },
- failure : function(response, options) {
- Ext.MessageBox.alert('Message', response.statusText);
- }
- });
- }
+ Ext.Ajax.request({
+ url: "v4l/services/" + adapterId,
+ params: {
+ op: "update",
+ entries: Ext.encode(out)
+ },
+ success: function(response, options) {
+ store.commitChanges();
+ },
+ failure: function(response, options) {
+ Ext.MessageBox.alert('Message', response.statusText);
+ }
+ });
+ }
- var delButton = new Ext.Toolbar.Button({
- tooltip : 'Delete one or more selected rows',
- iconCls : 'remove',
- text : 'Delete selected services',
- handler : delSelected,
- disabled : true
- });
+ var delButton = new Ext.Toolbar.Button({
+ tooltip: 'Delete one or more selected rows',
+ iconCls: 'remove',
+ text: 'Delete selected services',
+ handler: delSelected,
+ disabled: true
+ });
- var saveBtn = new Ext.Toolbar.Button({
- tooltip : 'Save any changes made (Changed cells have red borders).',
- iconCls : 'save',
- text : "Save changes",
- handler : saveChanges,
- disabled : true
- });
+ var saveBtn = new Ext.Toolbar.Button({
+ tooltip: 'Save any changes made (Changed cells have red borders).',
+ iconCls: 'save',
+ text: "Save changes",
+ handler: saveChanges,
+ disabled: true
+ });
- var rejectBtn = new Ext.Toolbar.Button({
- tooltip : 'Revert any changes made (Changed cells have red borders).',
- iconCls : 'undo',
- text : "Revert changes",
- handler : function() {
- store.rejectChanges();
- },
- disabled : true
- });
+ var rejectBtn = new Ext.Toolbar.Button({
+ tooltip: 'Revert any changes made (Changed cells have red borders).',
+ iconCls: 'undo',
+ text: "Revert changes",
+ handler: function() {
+ store.rejectChanges();
+ },
+ disabled: true
+ });
- var selModel = new Ext.grid.RowSelectionModel({
- singleSelect : false
- });
+ var selModel = new Ext.grid.RowSelectionModel({
+ singleSelect: false
+ });
- var grid = new Ext.grid.EditorGridPanel({
- stripeRows : true,
- title : 'Services',
- plugins : [ enabledColumn ],
- store : store,
- clicksToEdit : 2,
- cm : cm,
- viewConfig : {
- forceFit : true
- },
- selModel : selModel,
- tbar : [
- {
- tooltip : 'Create a new entry on the server. '
- + 'The new entry is initially disabled so it must be enabled '
- + 'before it start taking effect.',
- iconCls : 'add',
- text : 'Add service',
- handler : addRecord
- }, '-', delButton, '-', saveBtn, rejectBtn ]
- });
+ var grid = new Ext.grid.EditorGridPanel({
+ stripeRows: true,
+ title: 'Services',
+ plugins: [enabledColumn],
+ store: store,
+ clicksToEdit: 2,
+ cm: cm,
+ viewConfig: {
+ forceFit: true
+ },
+ selModel: selModel,
+ tbar: [
+ {
+ tooltip: 'Create a new entry on the server. '
+ + 'The new entry is initially disabled so it must be enabled '
+ + 'before it start taking effect.',
+ iconCls: 'add',
+ text: 'Add service',
+ handler: addRecord
+ }, '-', delButton, '-', saveBtn, rejectBtn]
+ });
- store.on('update', function(s, r, o) {
- d = s.getModifiedRecords().length == 0
- saveBtn.setDisabled(d);
- rejectBtn.setDisabled(d);
- });
+ store.on('update', function(s, r, o) {
+ d = s.getModifiedRecords().length === 0;
+ saveBtn.setDisabled(d);
+ rejectBtn.setDisabled(d);
+ });
- selModel.on('selectionchange', function(self) {
- delButton.setDisabled(self.getCount() == 0);
- });
+ selModel.on('selectionchange', function(self) {
+ delButton.setDisabled(self.getCount() === 0);
+ });
- return grid;
-}
+ return grid;
+};
/**
*
*/
tvheadend.v4l_adapter = function(data) {
- var panel = new Ext.TabPanel({
- border : false,
- activeTab : 0,
- autoScroll : true,
- items : [ new tvheadend.v4l_adapter_general(data),
- new tvheadend.v4l_services(data.identifier) ]
- });
- return panel;
-}
+ var panel = new Ext.TabPanel({
+ border: false,
+ activeTab: 0,
+ autoScroll: true,
+ items: [new tvheadend.v4l_adapter_general(data),
+ new tvheadend.v4l_services(data.identifier)]
+ });
+ return panel;
+};