webui: cosmetics cleanup of static/app
This commit is contained in:
parent
dd6b47dcf8
commit
2244b26989
24 changed files with 6912 additions and 6896 deletions
|
@ -1,78 +1,77 @@
|
|||
tvheadend.acleditor = function() {
|
||||
var fm = Ext.form;
|
||||
var fm = Ext.form;
|
||||
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
columns: [{
|
||||
xtype: 'checkcolumn',
|
||||
header: "Enabled",
|
||||
dataIndex: 'enabled',
|
||||
width: 60
|
||||
}, {
|
||||
header: "Username",
|
||||
dataIndex: 'username',
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "Password",
|
||||
dataIndex: 'password',
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
return '<span class="tvh-grid-unset">Hidden</span>';
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "Prefix",
|
||||
dataIndex: 'prefix',
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Streaming",
|
||||
dataIndex: 'streaming',
|
||||
width: 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Video Recorder",
|
||||
dataIndex: 'dvr',
|
||||
width: 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "All Configs (VR)",
|
||||
dataIndex: 'dvrallcfg',
|
||||
width: 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Web Interface",
|
||||
dataIndex: 'webui',
|
||||
width: 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Admin",
|
||||
dataIndex: 'admin',
|
||||
width: 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Channel Tag Only",
|
||||
dataIndex: 'tag_only',
|
||||
width: 200
|
||||
}, {
|
||||
header: "Comment",
|
||||
dataIndex: 'comment',
|
||||
width: 300,
|
||||
editor: new fm.TextField({})
|
||||
}]});
|
||||
|
||||
columns : [{
|
||||
xtype: 'checkcolumn',
|
||||
header : "Enabled",
|
||||
dataIndex : 'enabled',
|
||||
width : 60
|
||||
}, {
|
||||
header : "Username",
|
||||
dataIndex : 'username',
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "Password",
|
||||
dataIndex : 'password',
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
return '<span class="tvh-grid-unset">Hidden</span>';
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "Prefix",
|
||||
dataIndex : 'prefix',
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Streaming",
|
||||
dataIndex : 'streaming',
|
||||
width : 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Video Recorder",
|
||||
dataIndex : 'dvr',
|
||||
width : 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "All Configs (VR)",
|
||||
dataIndex : 'dvrallcfg',
|
||||
width : 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Web Interface",
|
||||
dataIndex : 'webui',
|
||||
width : 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Admin",
|
||||
dataIndex : 'admin',
|
||||
width : 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Channel Tag Only",
|
||||
dataIndex : 'tag_only',
|
||||
width : 200
|
||||
}, {
|
||||
header : "Comment",
|
||||
dataIndex : 'comment',
|
||||
width : 300,
|
||||
editor : new fm.TextField({})
|
||||
}]});
|
||||
var UserRecord = Ext.data.Record.create(
|
||||
['enabled', 'streaming', 'dvr', 'dvrallcfg', 'admin', 'webui', 'username', 'tag_only',
|
||||
'prefix', 'password', 'comment'
|
||||
]);
|
||||
|
||||
var UserRecord = Ext.data.Record.create(
|
||||
[ 'enabled', 'streaming', 'dvr', 'dvrallcfg', 'admin', 'webui', 'username', 'tag_only',
|
||||
'prefix', 'password', 'comment'
|
||||
]);
|
||||
|
||||
return new tvheadend.tableEditor('Access control', 'accesscontrol', cm,
|
||||
UserRecord, [], null, 'config_access.html',
|
||||
'group');
|
||||
}
|
||||
return new tvheadend.tableEditor('Access control', 'accesscontrol', cm,
|
||||
UserRecord, [], null, 'config_access.html',
|
||||
'group');
|
||||
};
|
||||
|
|
|
@ -1,106 +1,107 @@
|
|||
tvheadend.capmteditor = function() {
|
||||
var fm = Ext.form;
|
||||
var fm = Ext.form;
|
||||
|
||||
function setMetaAttr(meta, record) {
|
||||
var enabled = record.get('enabled');
|
||||
if (!enabled) return;
|
||||
function setMetaAttr(meta, record) {
|
||||
var enabled = record.get('enabled');
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
var connected = record.get('connected');
|
||||
if (connected == 2) {
|
||||
meta.attr = 'style="color:green;"';
|
||||
}
|
||||
else if (connected == 1) {
|
||||
meta.attr = 'style="color:orange;"';
|
||||
}
|
||||
else {
|
||||
meta.attr = 'style="color:red;"';
|
||||
}
|
||||
}
|
||||
var selectMode = new Ext.form.ComboBox({
|
||||
displayField:'name',
|
||||
valueField: 'res',
|
||||
value: 2,
|
||||
mode: 'local',
|
||||
editable: false,
|
||||
triggerAction: 'all',
|
||||
emptyText: 'Select mode...',
|
||||
store: new Ext.data.SimpleStore({
|
||||
fields: ['res','name'],
|
||||
id: 0,
|
||||
data: [
|
||||
['2','Recent OSCam (svn rev >= 9095)'],
|
||||
['1','Older OSCam'],
|
||||
['0','Wrapper (capmt_ca.so)']
|
||||
]
|
||||
})
|
||||
});
|
||||
var connected = record.get('connected');
|
||||
if (connected === 2) {
|
||||
meta.attr = 'style="color:green;"';
|
||||
}
|
||||
else if (connected === 1) {
|
||||
meta.attr = 'style="color:orange;"';
|
||||
}
|
||||
else {
|
||||
meta.attr = 'style="color:red;"';
|
||||
}
|
||||
}
|
||||
var selectMode = new Ext.form.ComboBox({
|
||||
displayField: 'name',
|
||||
valueField: 'res',
|
||||
value: 2,
|
||||
mode: 'local',
|
||||
editable: false,
|
||||
triggerAction: 'all',
|
||||
emptyText: 'Select mode...',
|
||||
store: new Ext.data.SimpleStore({
|
||||
fields: ['res', 'name'],
|
||||
id: 0,
|
||||
data: [
|
||||
['2', 'Recent OSCam (svn rev >= 9095)'],
|
||||
['1', 'Older OSCam'],
|
||||
['0', 'Wrapper (capmt_ca.so)']
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
columns: [ {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Enabled",
|
||||
dataIndex : 'enabled',
|
||||
width : 60
|
||||
}, {
|
||||
header: "Mode",
|
||||
dataIndex: 'oscam',
|
||||
width: 150,
|
||||
editor: selectMode
|
||||
}, {
|
||||
header : "Camd.socket Filename",
|
||||
dataIndex : 'camdfilename',
|
||||
width : 200,
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "Listenport",
|
||||
dataIndex : 'port',
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "Comment",
|
||||
dataIndex : 'comment',
|
||||
width : 400,
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor : new fm.TextField()
|
||||
} ]});
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
columns: [{
|
||||
xtype: 'checkcolumn',
|
||||
header: "Enabled",
|
||||
dataIndex: 'enabled',
|
||||
width: 60
|
||||
}, {
|
||||
header: "Mode",
|
||||
dataIndex: 'oscam',
|
||||
width: 150,
|
||||
editor: selectMode
|
||||
}, {
|
||||
header: "Camd.socket Filename",
|
||||
dataIndex: 'camdfilename',
|
||||
width: 200,
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "Listenport",
|
||||
dataIndex: 'port',
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "Comment",
|
||||
dataIndex: 'comment',
|
||||
width: 400,
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor: new fm.TextField()
|
||||
}]});
|
||||
|
||||
var rec = Ext.data.Record.create([ 'enabled', 'connected', 'camdfilename',
|
||||
'port', 'oscam', 'comment' ]);
|
||||
var rec = Ext.data.Record.create(['enabled', 'connected', 'camdfilename',
|
||||
'port', 'oscam', 'comment']);
|
||||
|
||||
store = new Ext.data.JsonStore({
|
||||
root : 'entries',
|
||||
fields : rec,
|
||||
url : "tablemgr",
|
||||
autoLoad : true,
|
||||
id : 'id',
|
||||
baseParams : {
|
||||
table : 'capmt',
|
||||
op : "get"
|
||||
}
|
||||
});
|
||||
store = new Ext.data.JsonStore({
|
||||
root: 'entries',
|
||||
fields: rec,
|
||||
url: "tablemgr",
|
||||
autoLoad: true,
|
||||
id: 'id',
|
||||
baseParams: {
|
||||
table: 'capmt',
|
||||
op: "get"
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.comet.on('capmt', function(server) {
|
||||
var rec = store.getById(server.id);
|
||||
if (rec) {
|
||||
rec.set('connected', server.connected);
|
||||
}
|
||||
});
|
||||
tvheadend.comet.on('capmt', function(server) {
|
||||
var rec = store.getById(server.id);
|
||||
if (rec) {
|
||||
rec.set('connected', server.connected);
|
||||
}
|
||||
});
|
||||
|
||||
return new tvheadend.tableEditor('Capmt Connections', 'capmt', cm, rec,
|
||||
[ ], store, 'config_capmt.html', 'key');
|
||||
}
|
||||
return new tvheadend.tableEditor('Capmt Connections', 'capmt', cm, rec,
|
||||
[], store, 'config_capmt.html', 'key');
|
||||
};
|
||||
|
|
|
@ -2,219 +2,222 @@
|
|||
* Channel tags
|
||||
*/
|
||||
tvheadend.channelTags = new Ext.data.JsonStore({
|
||||
autoLoad : true,
|
||||
root : 'entries',
|
||||
fields : [ 'identifier', 'name' ],
|
||||
id : 'identifier',
|
||||
url : 'channeltags',
|
||||
baseParams : {
|
||||
op : 'listTags'
|
||||
}
|
||||
autoLoad: true,
|
||||
root: 'entries',
|
||||
fields: ['identifier', 'name'],
|
||||
id: 'identifier',
|
||||
url: 'channeltags',
|
||||
baseParams: {
|
||||
op: 'listTags'
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.channelTags.setDefaultSort('name', 'ASC');
|
||||
|
||||
tvheadend.comet.on('channeltags', function(m) {
|
||||
if (m.reload != null) tvheadend.channelTags.reload();
|
||||
if (m.reload != null)
|
||||
tvheadend.channelTags.reload();
|
||||
});
|
||||
|
||||
/**
|
||||
* Channels
|
||||
*/
|
||||
tvheadend.channelrec = new Ext.data.Record.create(
|
||||
[ 'name', 'chid', 'epggrabsrc', 'tags', 'ch_icon', 'epg_pre_start',
|
||||
'epg_post_end', 'number' ]);
|
||||
['name', 'chid', 'epggrabsrc', 'tags', 'ch_icon', 'epg_pre_start',
|
||||
'epg_post_end', 'number']);
|
||||
|
||||
tvheadend.channels = new Ext.data.JsonStore({
|
||||
url : 'api/channel/list',
|
||||
root : 'entries',
|
||||
fields : [ 'key', 'val' ],
|
||||
id : 'key',
|
||||
autoLoad : true,
|
||||
sortInfo : {
|
||||
field : 'val',
|
||||
direction : 'ASC'
|
||||
}
|
||||
url: 'api/channel/list',
|
||||
root: 'entries',
|
||||
fields: ['key', 'val'],
|
||||
id: 'key',
|
||||
autoLoad: true,
|
||||
sortInfo: {
|
||||
field: 'val',
|
||||
direction: 'ASC'
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.comet.on('channels', function(m) {
|
||||
if (m.reload != null) tvheadend.channels.reload();
|
||||
if (m.reload != null)
|
||||
tvheadend.channels.reload();
|
||||
});
|
||||
|
||||
tvheadend.channel_tab = function(panel)
|
||||
{
|
||||
function assign_low_number() {
|
||||
var tab = panel.getActiveTab()
|
||||
var sm = tab.getSelectionModel()
|
||||
var store = tab.getStore()
|
||||
function assign_low_number() {
|
||||
var tab = panel.getActiveTab();
|
||||
var sm = tab.getSelectionModel();
|
||||
var store = tab.getStore();
|
||||
|
||||
if (sm.getCount() != 1)
|
||||
return
|
||||
if (sm.getCount() !== 1)
|
||||
return;
|
||||
|
||||
var nums = []
|
||||
store.each(function() {
|
||||
if(this.data.number > 0)
|
||||
nums.push(this.data.number)
|
||||
})
|
||||
var nums = [];
|
||||
store.each(function() {
|
||||
if (this.data.number > 0)
|
||||
nums.push(this.data.number);
|
||||
});
|
||||
|
||||
if(nums.length == 0)
|
||||
{
|
||||
sm.getSelected().set('number', 1)
|
||||
return
|
||||
}
|
||||
|
||||
nums.sort(function(a,b) { return (a - b) })
|
||||
|
||||
var max = nums[nums.length - 1]
|
||||
var low = max + 1
|
||||
|
||||
for(var i = 1; i <= max; ++i)
|
||||
{
|
||||
var ct = false
|
||||
for(var j = 0; j < nums.length; ++j)
|
||||
if(nums[j] == i)
|
||||
if (nums.length === 0)
|
||||
{
|
||||
ct = true
|
||||
break
|
||||
sm.getSelected().set('number', 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ct)
|
||||
{
|
||||
low = i
|
||||
break;
|
||||
}
|
||||
}
|
||||
nums.sort(function(a, b) {
|
||||
return (a - b);
|
||||
});
|
||||
|
||||
sm.getSelected().set('number', low)
|
||||
sm.selectNext()
|
||||
}
|
||||
var max = nums[nums.length - 1];
|
||||
var low = max + 1;
|
||||
|
||||
function move_number_up() {
|
||||
var tab = panel.getActiveTab()
|
||||
var sm = tab.getSelectionModel()
|
||||
var store = tab.getStore()
|
||||
|
||||
if (sm.getCount() != 1)
|
||||
return
|
||||
|
||||
var sel = sm.getSelected()
|
||||
var num = sel.data.number
|
||||
|
||||
if(!num)
|
||||
num = 0
|
||||
|
||||
store.each(function() {
|
||||
if(this.data.number == num + 1)
|
||||
this.set('number', num)
|
||||
})
|
||||
|
||||
sel.set('number', num + 1)
|
||||
}
|
||||
|
||||
function move_number_down() {
|
||||
var tab = panel.getActiveTab()
|
||||
var sm = tab.getSelectionModel()
|
||||
var store = tab.getStore()
|
||||
|
||||
if(sm.getCount() != 1)
|
||||
return
|
||||
|
||||
var sel = sm.getSelected()
|
||||
var num = sel.data.number
|
||||
|
||||
if(!num)
|
||||
num = 0
|
||||
|
||||
if(num <= 1)
|
||||
return
|
||||
|
||||
store.each(function() {
|
||||
if(this.data.number == num - 1)
|
||||
this.set('number', num)
|
||||
})
|
||||
|
||||
sel.set('number', num - 1)
|
||||
}
|
||||
|
||||
function swap_numbers() {
|
||||
var tab = panel.getActiveTab()
|
||||
var sm = tab.getSelectionModel()
|
||||
var store = tab.getStore()
|
||||
|
||||
if(sm.getCount() != 2)
|
||||
return
|
||||
|
||||
var sel = sm.getSelections()
|
||||
var tmp = sel[0].data.number
|
||||
|
||||
sel[0].set('number', sel[1].data.number)
|
||||
sel[1].set('number', tmp)
|
||||
}
|
||||
|
||||
var mapButton = new Ext.Toolbar.Button({
|
||||
tooltip : 'Map services to channels',
|
||||
iconCls : 'clone',
|
||||
text : 'Map Services',
|
||||
handler : tvheadend.service_mapper,
|
||||
disabled : false
|
||||
});
|
||||
|
||||
var lowNoButton = new Ext.Toolbar.Button({
|
||||
tooltip : 'Assign lowest free channel number',
|
||||
iconCls : 'bullet_add',
|
||||
text : 'Assign Number',
|
||||
handler : assign_low_number,
|
||||
disabled : false
|
||||
});
|
||||
|
||||
var noUpButton = new Ext.Toolbar.Button({
|
||||
tooltip : 'Move channel one number up',
|
||||
iconCls : 'arrow_up',
|
||||
text : 'Number Up',
|
||||
handler : move_number_up,
|
||||
disabled : false
|
||||
});
|
||||
|
||||
var noDownButton = new Ext.Toolbar.Button({
|
||||
tooltip : 'Move channel one number down',
|
||||
iconCls : 'arrow_down',
|
||||
text : 'Number Down',
|
||||
handler : move_number_down,
|
||||
disabled : false
|
||||
});
|
||||
|
||||
var noSwapButton = new Ext.Toolbar.Button({
|
||||
tooltip : 'Swap the two selected channels numbers',
|
||||
iconCls : 'arrow_switch',
|
||||
text : 'Swap Numbers',
|
||||
handler : swap_numbers,
|
||||
disabled : false
|
||||
});
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url : 'api/channel',
|
||||
comet : 'channel',
|
||||
titleS : 'Channel',
|
||||
titleP : 'Channels',
|
||||
tabIndex: 0,
|
||||
add : {
|
||||
url : 'api/channel',
|
||||
create : {}
|
||||
},
|
||||
del : true,
|
||||
tbar : [ mapButton, lowNoButton, noUpButton, noDownButton, noSwapButton ],
|
||||
lcol : [
|
||||
{
|
||||
width : 50,
|
||||
header : 'Play',
|
||||
renderer : function (v, o, r) {
|
||||
return "<a href='stream/channel/" + r.id + "'>Play</a>";
|
||||
for (var i = 1; i <= max; ++i)
|
||||
{
|
||||
var ct = false;
|
||||
for (var j = 0; j < nums.length; ++j)
|
||||
if (nums[j] === i)
|
||||
{
|
||||
ct = true;
|
||||
break
|
||||
}
|
||||
if (!ct)
|
||||
{
|
||||
low = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
sort : {
|
||||
field : 'number',
|
||||
direction : 'ASC'
|
||||
|
||||
sm.getSelected().set('number', low);
|
||||
sm.selectNext();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function move_number_up() {
|
||||
var tab = panel.getActiveTab();
|
||||
var sm = tab.getSelectionModel();
|
||||
var store = tab.getStore();
|
||||
|
||||
if (sm.getCount() !== 1)
|
||||
return;
|
||||
|
||||
var sel = sm.getSelected();
|
||||
var num = sel.data.number;
|
||||
|
||||
if (!num)
|
||||
num = 0;
|
||||
|
||||
store.each(function() {
|
||||
if (this.data.number === num + 1)
|
||||
this.set('number', num);
|
||||
});
|
||||
|
||||
sel.set('number', num + 1);
|
||||
}
|
||||
|
||||
function move_number_down() {
|
||||
var tab = panel.getActiveTab();
|
||||
var sm = tab.getSelectionModel();
|
||||
var store = tab.getStore();
|
||||
|
||||
if (sm.getCount() !== 1)
|
||||
return;
|
||||
|
||||
var sel = sm.getSelected();
|
||||
var num = sel.data.number;
|
||||
|
||||
if (!num)
|
||||
num = 0;
|
||||
|
||||
if (num <= 1)
|
||||
return;
|
||||
|
||||
store.each(function() {
|
||||
if (this.data.number === num - 1)
|
||||
this.set('number', num);
|
||||
});
|
||||
|
||||
sel.set('number', num - 1);
|
||||
}
|
||||
|
||||
function swap_numbers() {
|
||||
var tab = panel.getActiveTab();
|
||||
var sm = tab.getSelectionModel();
|
||||
var store = tab.getStore(); //store is unused
|
||||
|
||||
if (sm.getCount() !== 2)
|
||||
return;
|
||||
|
||||
var sel = sm.getSelections();
|
||||
var tmp = sel[0].data.number;
|
||||
|
||||
sel[0].set('number', sel[1].data.number);
|
||||
sel[1].set('number', tmp);
|
||||
}
|
||||
|
||||
var mapButton = new Ext.Toolbar.Button({
|
||||
tooltip: 'Map services to channels',
|
||||
iconCls: 'clone',
|
||||
text: 'Map Services',
|
||||
handler: tvheadend.service_mapper,
|
||||
disabled: false
|
||||
});
|
||||
|
||||
var lowNoButton = new Ext.Toolbar.Button({
|
||||
tooltip: 'Assign lowest free channel number',
|
||||
iconCls: 'bullet_add',
|
||||
text: 'Assign Number',
|
||||
handler: assign_low_number,
|
||||
disabled: false
|
||||
});
|
||||
|
||||
var noUpButton = new Ext.Toolbar.Button({
|
||||
tooltip: 'Move channel one number up',
|
||||
iconCls: 'arrow_up',
|
||||
text: 'Number Up',
|
||||
handler: move_number_up,
|
||||
disabled: false
|
||||
});
|
||||
|
||||
var noDownButton = new Ext.Toolbar.Button({
|
||||
tooltip: 'Move channel one number down',
|
||||
iconCls: 'arrow_down',
|
||||
text: 'Number Down',
|
||||
handler: move_number_down,
|
||||
disabled: false
|
||||
});
|
||||
|
||||
var noSwapButton = new Ext.Toolbar.Button({
|
||||
tooltip: 'Swap the two selected channels numbers',
|
||||
iconCls: 'arrow_switch',
|
||||
text: 'Swap Numbers',
|
||||
handler: swap_numbers,
|
||||
disabled: false
|
||||
});
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/channel',
|
||||
comet: 'channel',
|
||||
titleS: 'Channel',
|
||||
titleP: 'Channels',
|
||||
tabIndex: 0,
|
||||
add: {
|
||||
url: 'api/channel',
|
||||
create: {}
|
||||
},
|
||||
del: true,
|
||||
tbar: [mapButton, lowNoButton, noUpButton, noDownButton, noSwapButton],
|
||||
lcol: [
|
||||
{
|
||||
width: 50,
|
||||
header: 'Play',
|
||||
renderer: function(v, o, r) {
|
||||
return "<a href='stream/channel/" + r.id + "'>Play</a>";
|
||||
}
|
||||
}
|
||||
],
|
||||
sort: {
|
||||
field: 'number',
|
||||
direction: 'ASC'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
* Comet interfaces
|
||||
*/
|
||||
Ext.extend(tvheadend.Comet = function() {
|
||||
this.addEvents({
|
||||
accessUpdate : true,
|
||||
tvAdapter : true,
|
||||
dvbMux : true,
|
||||
dvbStore : true,
|
||||
dvbSatConf : true,
|
||||
logmessage : true,
|
||||
channeltags : true,
|
||||
autorec : true,
|
||||
dvrdb : true,
|
||||
dvrconfig : true,
|
||||
channels : true
|
||||
});
|
||||
this.addEvents({
|
||||
accessUpdate: true,
|
||||
tvAdapter: true,
|
||||
dvbMux: true,
|
||||
dvbStore: true,
|
||||
dvbSatConf: true,
|
||||
logmessage: true,
|
||||
channeltags: true,
|
||||
autorec: true,
|
||||
dvrdb: true,
|
||||
dvrconfig: true,
|
||||
channels: true
|
||||
});
|
||||
}, Ext.util.Observable);
|
||||
|
||||
tvheadend.comet = new tvheadend.Comet();
|
||||
|
@ -22,53 +22,53 @@ tvheadend.boxid = null;
|
|||
|
||||
tvheadend.cometPoller = function() {
|
||||
|
||||
var failures = 0;
|
||||
var failures = 0;
|
||||
|
||||
var cometRequest = new Ext.util.DelayedTask(function() {
|
||||
var cometRequest = new Ext.util.DelayedTask(function() {
|
||||
|
||||
Ext.Ajax
|
||||
.request({
|
||||
url : 'comet/poll',
|
||||
params : {
|
||||
boxid : (tvheadend.boxid ? tvheadend.boxid : null),
|
||||
immediate : failures > 0 ? 1 : 0
|
||||
},
|
||||
success : function(result, request) {
|
||||
parse_comet_response(result.responseText);
|
||||
Ext.Ajax
|
||||
.request({
|
||||
url: 'comet/poll',
|
||||
params: {
|
||||
boxid: (tvheadend.boxid ? tvheadend.boxid : null),
|
||||
immediate: failures > 0 ? 1 : 0
|
||||
},
|
||||
success: function(result, request) {
|
||||
parse_comet_response(result.responseText);
|
||||
|
||||
if (failures > 1) {
|
||||
tvheadend.log('Reconnected to Tvheadend',
|
||||
'font-weight: bold; color: #080');
|
||||
}
|
||||
failures = 0;
|
||||
},
|
||||
failure : function(result, request) {
|
||||
cometRequest.delay(failures ? 1000 : 1);
|
||||
if (failures == 1) {
|
||||
tvheadend.log('There seems to be a problem with the '
|
||||
+ 'live update feed from Tvheadend. '
|
||||
+ 'Trying to reconnect...',
|
||||
'font-weight: bold; color: #f00');
|
||||
}
|
||||
failures++;
|
||||
}
|
||||
});
|
||||
});
|
||||
if (failures > 1) {
|
||||
tvheadend.log('Reconnected to Tvheadend',
|
||||
'font-weight: bold; color: #080');
|
||||
}
|
||||
failures = 0;
|
||||
},
|
||||
failure: function(result, request) {
|
||||
cometRequest.delay(failures ? 1000 : 1);
|
||||
if (failures === 1) {
|
||||
tvheadend.log('There seems to be a problem with the '
|
||||
+ 'live update feed from Tvheadend. '
|
||||
+ 'Trying to reconnect...',
|
||||
'font-weight: bold; color: #f00');
|
||||
}
|
||||
failures++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function parse_comet_response(responsetxt) {
|
||||
response = Ext.util.JSON.decode(responsetxt);
|
||||
tvheadend.boxid = response.boxid
|
||||
for (x = 0; x < response.messages.length; x++) {
|
||||
m = response.messages[x];
|
||||
try {
|
||||
tvheadend.comet.fireEvent(m.notificationClass, m);
|
||||
} catch (e) {
|
||||
tvheadend.log('comet failure [e=' + e.message + ']');
|
||||
}
|
||||
}
|
||||
cometRequest.delay(100);
|
||||
}
|
||||
;
|
||||
function parse_comet_response(responsetxt) {
|
||||
response = Ext.util.JSON.decode(responsetxt);
|
||||
tvheadend.boxid = response.boxid;
|
||||
for (x = 0; x < response.messages.length; x++) {
|
||||
m = response.messages[x];
|
||||
try {
|
||||
tvheadend.comet.fireEvent(m.notificationClass, m);
|
||||
} catch (e) {
|
||||
tvheadend.log('comet failure [e=' + e.message + ']');
|
||||
}
|
||||
}
|
||||
cometRequest.delay(100);
|
||||
}
|
||||
;
|
||||
|
||||
cometRequest.delay(100);
|
||||
}
|
||||
cometRequest.delay(100);
|
||||
};
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
// Store: config languages
|
||||
tvheadend.languages = new Ext.data.JsonStore({
|
||||
autoLoad:true,
|
||||
root:'entries',
|
||||
fields: ['identifier','name'],
|
||||
autoLoad: true,
|
||||
root: 'entries',
|
||||
fields: ['identifier', 'name'],
|
||||
id: 'identifier',
|
||||
url:'languages',
|
||||
url: 'languages',
|
||||
baseParams: {
|
||||
op: 'list'
|
||||
op: 'list'
|
||||
}
|
||||
});
|
||||
|
||||
// Store: all languages
|
||||
tvheadend.config_languages = new Ext.data.JsonStore({
|
||||
autoLoad:true,
|
||||
root:'entries',
|
||||
fields: ['identifier','name'],
|
||||
autoLoad: true,
|
||||
root: 'entries',
|
||||
fields: ['identifier', 'name'],
|
||||
id: 'identifier',
|
||||
url:'languages',
|
||||
url: 'languages',
|
||||
baseParams: {
|
||||
op: 'config'
|
||||
op: 'config'
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.languages.setDefaultSort('name', 'ASC');
|
||||
|
||||
tvheadend.comet.on('config', function(m) {
|
||||
if(m.reload != null) {
|
||||
if (m.reload != null) {
|
||||
tvheadend.languages.reload();
|
||||
tvheadend.config_languages.reload();
|
||||
}
|
||||
|
@ -33,240 +33,243 @@ tvheadend.comet.on('config', function(m) {
|
|||
|
||||
tvheadend.miscconf = function() {
|
||||
|
||||
/*
|
||||
* Basic Config
|
||||
*/
|
||||
var confreader = new Ext.data.JsonReader({
|
||||
root : 'config'
|
||||
}, [ 'muxconfpath', 'language',
|
||||
'tvhtime_update_enabled', 'tvhtime_ntp_enabled',
|
||||
'tvhtime_tolerance', 'transcoding_enabled']);
|
||||
|
||||
/* ****************************************************************
|
||||
* Form Fields
|
||||
* ***************************************************************/
|
||||
|
||||
/*
|
||||
* DVB path
|
||||
*/
|
||||
|
||||
var dvbscanPath = new Ext.form.TextField({
|
||||
fieldLabel : 'DVB scan files path',
|
||||
name : 'muxconfpath',
|
||||
allowBlank : true,
|
||||
width: 400
|
||||
});
|
||||
|
||||
/*
|
||||
* Language
|
||||
*/
|
||||
|
||||
var language = new Ext.ux.ItemSelector({
|
||||
name: 'language',
|
||||
fromStore: tvheadend.languages,
|
||||
toStore: tvheadend.config_languages,
|
||||
fieldLabel: 'Default Language(s)',
|
||||
dataFields:['identifier', 'name'],
|
||||
msWidth: 190,
|
||||
msHeight: 150,
|
||||
valueField: 'identifier',
|
||||
displayField: 'name',
|
||||
imagePath: 'static/multiselect/resources',
|
||||
toLegend: 'Selected',
|
||||
fromLegend: 'Available'
|
||||
});
|
||||
|
||||
/*
|
||||
* Time/Date
|
||||
*/
|
||||
var tvhtimeUpdateEnabled = new Ext.form.Checkbox({
|
||||
name: 'tvhtime_update_enabled',
|
||||
fieldLabel: 'Update time'
|
||||
});
|
||||
|
||||
var tvhtimeNtpEnabled = new Ext.form.Checkbox({
|
||||
name: 'tvhtime_ntp_enabled',
|
||||
fieldLabel: 'Enable NTP driver'
|
||||
});
|
||||
|
||||
var tvhtimeTolerance = new Ext.form.NumberField({
|
||||
name: 'tvhtime_tolerance',
|
||||
fieldLabel: 'Update tolerance (ms)'
|
||||
});
|
||||
|
||||
var tvhtimePanel = new Ext.form.FieldSet({
|
||||
title: 'Time Update',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items : [ tvhtimeUpdateEnabled, tvhtimeNtpEnabled, tvhtimeTolerance ]
|
||||
});
|
||||
|
||||
/*
|
||||
* Image cache
|
||||
*/
|
||||
if (tvheadend.capabilities.indexOf('imagecache') != -1) {
|
||||
var imagecache_reader = new Ext.data.JsonReader({
|
||||
root : 'entries'
|
||||
/*
|
||||
* Basic Config
|
||||
*/
|
||||
var confreader = new Ext.data.JsonReader({
|
||||
root: 'config'
|
||||
},
|
||||
[
|
||||
'enabled', 'ok_period', 'fail_period', 'ignore_sslcert',
|
||||
'muxconfpath', 'language',
|
||||
'tvhtime_update_enabled', 'tvhtime_ntp_enabled',
|
||||
'tvhtime_tolerance', 'transcoding_enabled'
|
||||
]);
|
||||
|
||||
var imagecacheEnabled = new Ext.ux.form.XCheckbox({
|
||||
name: 'enabled',
|
||||
fieldLabel: 'Enabled',
|
||||
/* ****************************************************************
|
||||
* Form Fields
|
||||
* ***************************************************************/
|
||||
|
||||
/*
|
||||
* DVB path
|
||||
*/
|
||||
|
||||
var dvbscanPath = new Ext.form.TextField({
|
||||
fieldLabel: 'DVB scan files path',
|
||||
name: 'muxconfpath',
|
||||
allowBlank: true,
|
||||
width: 400
|
||||
});
|
||||
|
||||
var imagecacheOkPeriod = new Ext.form.NumberField({
|
||||
name: 'ok_period',
|
||||
fieldLabel: 'Re-fetch period (hours)'
|
||||
/*
|
||||
* Language
|
||||
*/
|
||||
|
||||
var language = new Ext.ux.ItemSelector({
|
||||
name: 'language',
|
||||
fromStore: tvheadend.languages,
|
||||
toStore: tvheadend.config_languages,
|
||||
fieldLabel: 'Default Language(s)',
|
||||
dataFields: ['identifier', 'name'],
|
||||
msWidth: 190,
|
||||
msHeight: 150,
|
||||
valueField: 'identifier',
|
||||
displayField: 'name',
|
||||
imagePath: 'static/multiselect/resources',
|
||||
toLegend: 'Selected',
|
||||
fromLegend: 'Available'
|
||||
});
|
||||
|
||||
var imagecacheFailPeriod = new Ext.form.NumberField({
|
||||
name: 'fail_period',
|
||||
fieldLabel: 'Re-try period (hours)',
|
||||
/*
|
||||
* Time/Date
|
||||
*/
|
||||
var tvhtimeUpdateEnabled = new Ext.form.Checkbox({
|
||||
name: 'tvhtime_update_enabled',
|
||||
fieldLabel: 'Update time'
|
||||
});
|
||||
|
||||
var imagecacheIgnoreSSLCert = new Ext.ux.form.XCheckbox({
|
||||
name: 'ignore_sslcert',
|
||||
fieldLabel: 'Ignore invalid SSL certificate'
|
||||
var tvhtimeNtpEnabled = new Ext.form.Checkbox({
|
||||
name: 'tvhtime_ntp_enabled',
|
||||
fieldLabel: 'Enable NTP driver'
|
||||
});
|
||||
|
||||
var imagecachePanel = new Ext.form.FieldSet({
|
||||
title: 'Image Caching',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items : [ imagecacheEnabled, imagecacheOkPeriod, imagecacheFailPeriod,
|
||||
imagecacheIgnoreSSLCert ]
|
||||
var tvhtimeTolerance = new Ext.form.NumberField({
|
||||
name: 'tvhtime_tolerance',
|
||||
fieldLabel: 'Update tolerance (ms)'
|
||||
});
|
||||
|
||||
var imagecache_form = new Ext.form.FormPanel({
|
||||
border : false,
|
||||
labelAlign : 'left',
|
||||
labelWidth : 200,
|
||||
waitMsgTarget : true,
|
||||
reader: imagecache_reader,
|
||||
layout : 'form',
|
||||
defaultType : 'textfield',
|
||||
autoHeight : true,
|
||||
items : [ imagecachePanel ]
|
||||
var tvhtimePanel = new Ext.form.FieldSet({
|
||||
title: 'Time Update',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items: [tvhtimeUpdateEnabled, tvhtimeNtpEnabled, tvhtimeTolerance]
|
||||
});
|
||||
} else {
|
||||
var imagecache_form = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transcoding
|
||||
*/
|
||||
var transcodingEnabled = new Ext.form.Checkbox({
|
||||
name: 'transcoding_enabled',
|
||||
fieldLabel: 'Enabled',
|
||||
});
|
||||
|
||||
var transcodingPanel = new Ext.form.FieldSet({
|
||||
title: 'Transcoding',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items : [ transcodingEnabled ]
|
||||
});
|
||||
if (tvheadend.capabilities.indexOf('transcoding') == -1)
|
||||
transcodingPanel.hide();
|
||||
|
||||
|
||||
/* ****************************************************************
|
||||
* Form
|
||||
* ***************************************************************/
|
||||
|
||||
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('General Configuration', 'config_misc.html');
|
||||
}
|
||||
});
|
||||
|
||||
var confpanel = new Ext.form.FormPanel({
|
||||
labelAlign : 'left',
|
||||
labelWidth : 200,
|
||||
border : false,
|
||||
waitMsgTarget : true,
|
||||
reader : confreader,
|
||||
layout : 'form',
|
||||
defaultType : 'textfield',
|
||||
autoHeight : true,
|
||||
items : [ language, dvbscanPath,
|
||||
tvhtimePanel,
|
||||
transcodingPanel]
|
||||
});
|
||||
|
||||
var _items = [confpanel];
|
||||
if (imagecache_form)
|
||||
_items.push(imagecache_form);
|
||||
var panel = new Ext.Panel({
|
||||
title : 'General',
|
||||
iconCls : 'wrench',
|
||||
border : false,
|
||||
bodyStyle : 'padding:15px',
|
||||
layout : 'form',
|
||||
items: _items,
|
||||
tbar : [ saveButton, '->', helpButton ]
|
||||
});
|
||||
|
||||
/* ****************************************************************
|
||||
* Load/Save
|
||||
* ***************************************************************/
|
||||
|
||||
confpanel.on('render', function() {
|
||||
confpanel.getForm().load({
|
||||
url : 'config',
|
||||
params : {
|
||||
op : 'loadSettings'
|
||||
},
|
||||
success : function(form, action) {
|
||||
confpanel.enable();
|
||||
}
|
||||
});
|
||||
if (imagecache_form)
|
||||
imagecache_form.getForm().load({
|
||||
url : 'api/imagecache/config/load',
|
||||
success : function (form, action) {
|
||||
imagecache_form.enable();
|
||||
/*
|
||||
* Image cache
|
||||
*/
|
||||
if (tvheadend.capabilities.indexOf('imagecache') !== -1) {
|
||||
var imagecache_reader = new Ext.data.JsonReader({
|
||||
root: 'entries'
|
||||
},
|
||||
failure : function (form, action) {
|
||||
alert("FAILED");
|
||||
}
|
||||
});
|
||||
});
|
||||
[
|
||||
'enabled', 'ok_period', 'fail_period', 'ignore_sslcert'
|
||||
]);
|
||||
|
||||
function saveChanges() {
|
||||
confpanel.getForm().submit({
|
||||
url : 'config',
|
||||
params : {
|
||||
op : 'saveSettings'
|
||||
},
|
||||
waitMsg : 'Saving Data...',
|
||||
failure : function(form, action) {
|
||||
Ext.Msg.alert('Save failed', action.result.errormsg);
|
||||
}
|
||||
});
|
||||
if (imagecache_form)
|
||||
imagecache_form.getForm().submit({
|
||||
url : 'api/imagecache/config/save',
|
||||
waitMsg : 'Saving data...',
|
||||
failure : function(form, action) {
|
||||
Ext.Msg.alert('Imagecache save failed', action.result.errormsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
var imagecacheEnabled = new Ext.ux.form.XCheckbox({
|
||||
name: 'enabled',
|
||||
fieldLabel: 'Enabled'
|
||||
});
|
||||
|
||||
return panel;
|
||||
}
|
||||
var imagecacheOkPeriod = new Ext.form.NumberField({
|
||||
name: 'ok_period',
|
||||
fieldLabel: 'Re-fetch period (hours)'
|
||||
});
|
||||
|
||||
var imagecacheFailPeriod = new Ext.form.NumberField({
|
||||
name: 'fail_period',
|
||||
fieldLabel: 'Re-try period (hours)'
|
||||
});
|
||||
|
||||
var imagecacheIgnoreSSLCert = new Ext.ux.form.XCheckbox({
|
||||
name: 'ignore_sslcert',
|
||||
fieldLabel: 'Ignore invalid SSL certificate'
|
||||
});
|
||||
|
||||
var imagecachePanel = new Ext.form.FieldSet({
|
||||
title: 'Image Caching',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items: [imagecacheEnabled, imagecacheOkPeriod, imagecacheFailPeriod,
|
||||
imagecacheIgnoreSSLCert]
|
||||
});
|
||||
|
||||
var imagecache_form = new Ext.form.FormPanel({
|
||||
border: false,
|
||||
labelAlign: 'left',
|
||||
labelWidth: 200,
|
||||
waitMsgTarget: true,
|
||||
reader: imagecache_reader,
|
||||
layout: 'form',
|
||||
defaultType: 'textfield',
|
||||
autoHeight: true,
|
||||
items: [imagecachePanel]
|
||||
});
|
||||
} else {
|
||||
var imagecache_form = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transcoding
|
||||
*/
|
||||
var transcodingEnabled = new Ext.form.Checkbox({
|
||||
name: 'transcoding_enabled',
|
||||
fieldLabel: 'Enabled'
|
||||
});
|
||||
|
||||
var transcodingPanel = new Ext.form.FieldSet({
|
||||
title: 'Transcoding',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items: [transcodingEnabled]
|
||||
});
|
||||
if (tvheadend.capabilities.indexOf('transcoding') === -1)
|
||||
transcodingPanel.hide();
|
||||
|
||||
|
||||
/* ****************************************************************
|
||||
* Form
|
||||
* ***************************************************************/
|
||||
|
||||
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('General Configuration', 'config_misc.html');
|
||||
}
|
||||
});
|
||||
|
||||
var confpanel = new Ext.form.FormPanel({
|
||||
labelAlign: 'left',
|
||||
labelWidth: 200,
|
||||
border: false,
|
||||
waitMsgTarget: true,
|
||||
reader: confreader,
|
||||
layout: 'form',
|
||||
defaultType: 'textfield',
|
||||
autoHeight: true,
|
||||
items: [language, dvbscanPath,
|
||||
tvhtimePanel,
|
||||
transcodingPanel]
|
||||
});
|
||||
|
||||
var _items = [confpanel];
|
||||
if (imagecache_form)
|
||||
_items.push(imagecache_form);
|
||||
var panel = new Ext.Panel({
|
||||
title: 'General',
|
||||
iconCls: 'wrench',
|
||||
border: false,
|
||||
bodyStyle: 'padding:15px',
|
||||
layout: 'form',
|
||||
items: _items,
|
||||
tbar: [saveButton, '->', helpButton]
|
||||
});
|
||||
|
||||
/* ****************************************************************
|
||||
* Load/Save
|
||||
* ***************************************************************/
|
||||
|
||||
confpanel.on('render', function() {
|
||||
confpanel.getForm().load({
|
||||
url: 'config',
|
||||
params: {
|
||||
op: 'loadSettings'
|
||||
},
|
||||
success: function(form, action) {
|
||||
confpanel.enable();
|
||||
}
|
||||
});
|
||||
if (imagecache_form)
|
||||
imagecache_form.getForm().load({
|
||||
url: 'api/imagecache/config/load',
|
||||
success: function(form, action) {
|
||||
imagecache_form.enable();
|
||||
},
|
||||
failure: function(form, action) {
|
||||
alert("FAILED");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function saveChanges() {
|
||||
confpanel.getForm().submit({
|
||||
url: 'config',
|
||||
params: {
|
||||
op: 'saveSettings'
|
||||
},
|
||||
waitMsg: 'Saving Data...',
|
||||
failure: function(form, action) {
|
||||
Ext.Msg.alert('Save failed', action.result.errormsg);
|
||||
}
|
||||
});
|
||||
if (imagecache_form)
|
||||
imagecache_form.getForm().submit({
|
||||
url: 'api/imagecache/config/save',
|
||||
waitMsg: 'Saving data...',
|
||||
failure: function(form, action) {
|
||||
Ext.Msg.alert('Imagecache save failed', action.result.errormsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return panel;
|
||||
};
|
||||
|
|
|
@ -1,49 +1,48 @@
|
|||
tvheadend.cteditor = function() {
|
||||
var fm = Ext.form;
|
||||
var fm = Ext.form;
|
||||
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
columns: [{
|
||||
xtype: 'checkcolumn',
|
||||
header: "Enabled",
|
||||
dataIndex: 'enabled',
|
||||
width: 60
|
||||
}, {
|
||||
header: "Name",
|
||||
dataIndex: 'name',
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Internal",
|
||||
dataIndex: 'internal',
|
||||
width: 100
|
||||
}, {
|
||||
header: "Icon (full URL)",
|
||||
dataIndex: 'icon',
|
||||
width: 400,
|
||||
editor: new fm.TextField({})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Icon has title",
|
||||
dataIndex: 'titledIcon',
|
||||
width: 100,
|
||||
tooltip: 'Set this if the supplied icon has a title embedded. '
|
||||
+ 'This will tell displaying application not to superimpose title '
|
||||
+ 'on top of logo.'
|
||||
}, {
|
||||
header: "Comment",
|
||||
dataIndex: 'comment',
|
||||
width: 400,
|
||||
editor: new fm.TextField({})
|
||||
}]});
|
||||
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
columns : [{
|
||||
xtype: 'checkcolumn',
|
||||
header : "Enabled",
|
||||
dataIndex : 'enabled',
|
||||
width : 60
|
||||
} , {
|
||||
header : "Name",
|
||||
dataIndex : 'name',
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Internal",
|
||||
dataIndex : 'internal',
|
||||
width : 100
|
||||
}, {
|
||||
header : "Icon (full URL)",
|
||||
dataIndex : 'icon',
|
||||
width : 400,
|
||||
editor : new fm.TextField({})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Icon has title",
|
||||
dataIndex : 'titledIcon',
|
||||
width : 100,
|
||||
tooltip : 'Set this if the supplied icon has a title embedded. '
|
||||
+ 'This will tell displaying application not to superimpose title '
|
||||
+ 'on top of logo.'
|
||||
}, {
|
||||
header : "Comment",
|
||||
dataIndex : 'comment',
|
||||
width : 400,
|
||||
editor : new fm.TextField({})
|
||||
} ]});
|
||||
var ChannelTagRecord = Ext.data.Record.create([
|
||||
'enabled', 'name', 'internal', 'icon', 'comment', 'titledIcon']);
|
||||
|
||||
var ChannelTagRecord = Ext.data.Record.create([
|
||||
'enabled', 'name', 'internal', 'icon', 'comment', 'titledIcon' ]);
|
||||
|
||||
return new tvheadend.tableEditor('Channel Tags', 'channeltags', cm,
|
||||
ChannelTagRecord, [],
|
||||
null, 'config_tags.html', 'tags');
|
||||
}
|
||||
return new tvheadend.tableEditor('Channel Tags', 'channeltags', cm,
|
||||
ChannelTagRecord, [],
|
||||
null, 'config_tags.html', 'tags');
|
||||
};
|
||||
|
|
|
@ -1,128 +1,129 @@
|
|||
tvheadend.cwceditor = function() {
|
||||
var fm = Ext.form;
|
||||
var fm = Ext.form;
|
||||
|
||||
function setMetaAttr(meta, record) {
|
||||
var enabled = record.get('enabled');
|
||||
if (!enabled) return;
|
||||
function setMetaAttr(meta, record) {
|
||||
var enabled = record.get('enabled');
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
var connected = record.get('connected');
|
||||
if (connected == 1) {
|
||||
meta.attr = 'style="color:green;"';
|
||||
}
|
||||
else {
|
||||
meta.attr = 'style="color:red;"';
|
||||
}
|
||||
}
|
||||
var connected = record.get('connected');
|
||||
if (connected === 1) {
|
||||
meta.attr = 'style="color:green;"';
|
||||
}
|
||||
else {
|
||||
meta.attr = 'style="color:red;"';
|
||||
}
|
||||
}
|
||||
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
columns : [ {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Enabled",
|
||||
dataIndex : 'enabled',
|
||||
width : 60
|
||||
}, {
|
||||
header : "Hostname",
|
||||
dataIndex : 'hostname',
|
||||
width : 200,
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "Port",
|
||||
dataIndex : 'port',
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "Username",
|
||||
dataIndex : 'username',
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "Password",
|
||||
dataIndex : 'password',
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return '<span class="tvh-grid-unset">Hidden</span>';
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
header : "DES Key",
|
||||
dataIndex : 'deskey',
|
||||
width : 300,
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return '<span class="tvh-grid-unset">Hidden</span>';
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Update Card",
|
||||
dataIndex : 'emm',
|
||||
width : 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header : "Update One",
|
||||
dataIndex : 'emmex',
|
||||
width : 100
|
||||
}, {
|
||||
header : "Comment",
|
||||
dataIndex : 'comment',
|
||||
width : 400,
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor : new fm.TextField()
|
||||
} ]});
|
||||
var cm = new Ext.grid.ColumnModel({
|
||||
defaultSortable: true,
|
||||
columns: [{
|
||||
xtype: 'checkcolumn',
|
||||
header: "Enabled",
|
||||
dataIndex: 'enabled',
|
||||
width: 60
|
||||
}, {
|
||||
header: "Hostname",
|
||||
dataIndex: 'hostname',
|
||||
width: 200,
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "Port",
|
||||
dataIndex: 'port',
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "Username",
|
||||
dataIndex: 'username',
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "Password",
|
||||
dataIndex: 'password',
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return '<span class="tvh-grid-unset">Hidden</span>';
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
header: "DES Key",
|
||||
dataIndex: 'deskey',
|
||||
width: 300,
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return '<span class="tvh-grid-unset">Hidden</span>';
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Update Card",
|
||||
dataIndex: 'emm',
|
||||
width: 100
|
||||
}, {
|
||||
xtype: 'checkcolumn',
|
||||
header: "Update One",
|
||||
dataIndex: 'emmex',
|
||||
width: 100
|
||||
}, {
|
||||
header: "Comment",
|
||||
dataIndex: 'comment',
|
||||
width: 400,
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
setMetaAttr(metadata, record);
|
||||
return value;
|
||||
},
|
||||
editor: new fm.TextField()
|
||||
}]});
|
||||
|
||||
var rec = Ext.data.Record.create([ 'enabled', 'connected', 'hostname',
|
||||
'port', 'username', 'password', 'deskey', 'emm', 'emmex', 'comment' ]);
|
||||
var rec = Ext.data.Record.create(['enabled', 'connected', 'hostname',
|
||||
'port', 'username', 'password', 'deskey', 'emm', 'emmex', 'comment']);
|
||||
|
||||
var store = new Ext.data.JsonStore({
|
||||
root : 'entries',
|
||||
fields : rec,
|
||||
url : "tablemgr",
|
||||
autoLoad : true,
|
||||
id : 'id',
|
||||
baseParams : {
|
||||
table : 'cwc',
|
||||
op : "get"
|
||||
},
|
||||
sortInfo : {
|
||||
field : 'username',
|
||||
direction : 'ASC'
|
||||
}
|
||||
});
|
||||
var store = new Ext.data.JsonStore({
|
||||
root: 'entries',
|
||||
fields: rec,
|
||||
url: "tablemgr",
|
||||
autoLoad: true,
|
||||
id: 'id',
|
||||
baseParams: {
|
||||
table: 'cwc',
|
||||
op: "get"
|
||||
},
|
||||
sortInfo: {
|
||||
field: 'username',
|
||||
direction: 'ASC'
|
||||
}
|
||||
});
|
||||
|
||||
var grid = new tvheadend.tableEditor('Code Word Client', 'cwc', cm, rec, [],
|
||||
store, 'config_cwc.html', 'key');
|
||||
var grid = new tvheadend.tableEditor('Code Word Client', 'cwc', cm, rec, [],
|
||||
store, 'config_cwc.html', 'key');
|
||||
|
||||
tvheadend.comet.on('cwcStatus', function(msg) {
|
||||
var rec = store.getById(msg.id);
|
||||
if (rec) {
|
||||
rec.set('connected', msg.connected);
|
||||
grid.getView().refresh();
|
||||
}
|
||||
});
|
||||
tvheadend.comet.on('cwcStatus', function(msg) {
|
||||
var rec = store.getById(msg.id);
|
||||
if (rec) {
|
||||
rec.set('connected', msg.connected);
|
||||
grid.getView().refresh();
|
||||
}
|
||||
});
|
||||
|
||||
return grid;
|
||||
}
|
||||
return grid;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
948
src/webui/static/app/epg.js
Executable file → Normal file
948
src/webui/static/app/epg.js
Executable file → Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,427 +1,430 @@
|
|||
tvheadend.epggrabChannels = new Ext.data.JsonStore({
|
||||
root : 'entries',
|
||||
url : 'epggrab',
|
||||
baseParams : {
|
||||
op : 'channelList'
|
||||
},
|
||||
fields : [ 'id', 'mod', 'name', 'icon', 'number', 'channel', 'mod-id',
|
||||
'mod-name' ]
|
||||
root: 'entries',
|
||||
url: 'epggrab',
|
||||
baseParams: {
|
||||
op: 'channelList'
|
||||
},
|
||||
fields: ['id', 'mod', 'name', 'icon', 'number', 'channel', 'mod-id',
|
||||
'mod-name']
|
||||
});
|
||||
|
||||
tvheadend.epggrab = function() {
|
||||
|
||||
/* ****************************************************************
|
||||
* Data
|
||||
* ***************************************************************/
|
||||
/* ****************************************************************
|
||||
* Data
|
||||
* ***************************************************************/
|
||||
|
||||
/*
|
||||
* Module lists (I'm sure there is a better way!)
|
||||
*/
|
||||
var EPGGRAB_MODULE_INTERNAL = "internal";
|
||||
var EPGGRAB_MODULE_EXTERNAL = "external";
|
||||
var EPGGRAB_MODULE_OTA = "ota";
|
||||
/*
|
||||
* Module lists (I'm sure there is a better way!)
|
||||
*/
|
||||
var EPGGRAB_MODULE_INTERNAL = "internal";
|
||||
var EPGGRAB_MODULE_EXTERNAL = "external";
|
||||
var EPGGRAB_MODULE_OTA = "ota";
|
||||
|
||||
var moduleStore = new Ext.data.JsonStore({
|
||||
root : 'entries',
|
||||
url : 'epggrab',
|
||||
baseParams : {
|
||||
op : 'moduleList'
|
||||
},
|
||||
autoLoad : true,
|
||||
fields : [ 'id', 'name', 'path', 'type', 'enabled' ]
|
||||
});
|
||||
var internalModuleStore = new Ext.data.Store({
|
||||
recordType : moduleStore.recordType
|
||||
});
|
||||
var externalModuleStore = new Ext.data.Store({
|
||||
recordType : moduleStore.recordType
|
||||
});
|
||||
var otaModuleStore = new Ext.data.Store({
|
||||
recordType : moduleStore.recordType
|
||||
});
|
||||
moduleStore.on('load', function() {
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') == EPGGRAB_MODULE_INTERNAL;
|
||||
});
|
||||
r = new internalModuleStore.recordType({
|
||||
id : '',
|
||||
name : 'Disabled'
|
||||
});
|
||||
internalModuleStore.add(r);
|
||||
moduleStore.each(function(r) {
|
||||
internalModuleStore.add(r.copy());
|
||||
});
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') == EPGGRAB_MODULE_EXTERNAL;
|
||||
});
|
||||
moduleStore.each(function(r) {
|
||||
externalModuleStore.add(r.copy());
|
||||
});
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') == EPGGRAB_MODULE_OTA;
|
||||
});
|
||||
moduleStore.each(function(r) {
|
||||
otaModuleStore.add(r.copy());
|
||||
});
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') != EPGGRAB_MODULE_INTERNAL;
|
||||
});
|
||||
});
|
||||
|
||||
/* Enable module in one of the stores (will auto update primary) */
|
||||
function moduleSelect(r, e) {
|
||||
r.set('enabled', e);
|
||||
t = moduleStore.getById(r.id);
|
||||
if (t) t.set('enabled', e);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic Config
|
||||
*/
|
||||
|
||||
var confreader = new Ext.data.JsonReader({
|
||||
root : 'epggrabSettings'
|
||||
}, [ 'module', 'interval', 'channel_rename', 'channel_renumber',
|
||||
'channel_reicon', 'epgdb_periodicsave' ]);
|
||||
|
||||
/* ****************************************************************
|
||||
* Basic Fields
|
||||
* ***************************************************************/
|
||||
|
||||
/*
|
||||
* Module selector
|
||||
*/
|
||||
var internalModule = new Ext.form.ComboBox({
|
||||
fieldLabel : 'Module',
|
||||
hiddenName : 'module',
|
||||
width : 300,
|
||||
valueField : 'id',
|
||||
displayField : 'name',
|
||||
forceSelection : true,
|
||||
editable : false,
|
||||
mode : 'local',
|
||||
triggerAction : 'all',
|
||||
store : internalModuleStore
|
||||
});
|
||||
|
||||
/*
|
||||
* Interval selector
|
||||
*/
|
||||
var intervalUnits = [ [ 86400, 'Days' ], [ 3600, 'Hours' ],
|
||||
[ 60, 'Minutes' ], [ 1, 'Seconds' ] ];
|
||||
var intervalValue = new Ext.form.NumberField({
|
||||
width : 300,
|
||||
allowNegative : false,
|
||||
allowDecimals : false,
|
||||
minValue : 1,
|
||||
maxValue : 7,
|
||||
value : 1,
|
||||
fieldLabel : 'Grab interval',
|
||||
name : 'intervalValue',
|
||||
listeners : {
|
||||
'valid' : function(e) {
|
||||
v = e.getValue() * intervalUnit.getValue();
|
||||
interval.setValue(v);
|
||||
}
|
||||
}
|
||||
})
|
||||
var intervalUnit = new Ext.form.ComboBox({
|
||||
name : 'intervalUnit',
|
||||
width : 300,
|
||||
valueField : 'key',
|
||||
displayField : 'value',
|
||||
value : 86400,
|
||||
forceSelection : true,
|
||||
editable : false,
|
||||
triggerAction : 'all',
|
||||
mode : 'local',
|
||||
store : new Ext.data.SimpleStore({
|
||||
fields : [ 'key', 'value' ],
|
||||
data : intervalUnits
|
||||
}),
|
||||
listeners : {
|
||||
'change' : function(e, n, o) {
|
||||
intervalValue.maxValue = (7 * 86400) / n;
|
||||
intervalValue.validate();
|
||||
}
|
||||
}
|
||||
});
|
||||
var interval = new Ext.form.Hidden({
|
||||
name : 'interval',
|
||||
value : 86400,
|
||||
listeners : {
|
||||
'enable' : function(e) {
|
||||
v = e.getValue();
|
||||
for (i = 0; i < intervalUnits.length; i++) {
|
||||
u = intervalUnits[i][0];
|
||||
if ((v % u) == 0) {
|
||||
intervalUnit.setValue(u);
|
||||
intervalValue.maxValue = (7 * 86400) / u;
|
||||
intervalValue.setValue(v / u);
|
||||
intervalValue.validate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Channel handling
|
||||
*/
|
||||
var channelRename = new Ext.form.Checkbox({
|
||||
name : 'channel_rename',
|
||||
fieldLabel : 'Update channel name'
|
||||
});
|
||||
|
||||
var channelRenumber = new Ext.form.Checkbox({
|
||||
name : 'channel_renumber',
|
||||
fieldLabel : 'Update channel number'
|
||||
});
|
||||
|
||||
var channelReicon = new Ext.form.Checkbox({
|
||||
name : 'channel_reicon',
|
||||
fieldLabel : 'Update channel icon'
|
||||
});
|
||||
|
||||
var epgPeriodicSave = new Ext.form.NumberField({
|
||||
width : 30,
|
||||
allowNegative : false,
|
||||
allowDecimals : false,
|
||||
minValue : 0,
|
||||
maxValue : 24,
|
||||
value : 0,
|
||||
fieldLabel : 'Periodic save EPG to disk',
|
||||
name : 'epgdb_periodicsave',
|
||||
var moduleStore = new Ext.data.JsonStore({
|
||||
root: 'entries',
|
||||
url: 'epggrab',
|
||||
baseParams: {
|
||||
op: 'moduleList'
|
||||
},
|
||||
autoLoad: true,
|
||||
fields: ['id', 'name', 'path', 'type', 'enabled']
|
||||
});
|
||||
var internalModuleStore = new Ext.data.Store({
|
||||
recordType: moduleStore.recordType
|
||||
});
|
||||
var externalModuleStore = new Ext.data.Store({
|
||||
recordType: moduleStore.recordType
|
||||
});
|
||||
var otaModuleStore = new Ext.data.Store({
|
||||
recordType: moduleStore.recordType
|
||||
});
|
||||
moduleStore.on('load', function() {
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') === EPGGRAB_MODULE_INTERNAL;
|
||||
});
|
||||
r = new internalModuleStore.recordType({
|
||||
id: '',
|
||||
name: 'Disabled'
|
||||
});
|
||||
internalModuleStore.add(r);
|
||||
moduleStore.each(function(r) {
|
||||
internalModuleStore.add(r.copy());
|
||||
});
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') === EPGGRAB_MODULE_EXTERNAL;
|
||||
});
|
||||
moduleStore.each(function(r) {
|
||||
externalModuleStore.add(r.copy());
|
||||
});
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') === EPGGRAB_MODULE_OTA;
|
||||
});
|
||||
moduleStore.each(function(r) {
|
||||
otaModuleStore.add(r.copy());
|
||||
});
|
||||
moduleStore.filterBy(function(r) {
|
||||
return r.get('type') !== EPGGRAB_MODULE_INTERNAL;
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Simple fields
|
||||
*/
|
||||
var simplePanel = new Ext.form.FieldSet({
|
||||
title : 'General Config',
|
||||
width : 700,
|
||||
autoHeight : true,
|
||||
collapsible : true,
|
||||
items : [ channelRename, channelRenumber, channelReicon, epgPeriodicSave ]
|
||||
});
|
||||
/* Enable module in one of the stores (will auto update primary) */
|
||||
function moduleSelect(r, e) {
|
||||
r.set('enabled', e);
|
||||
t = moduleStore.getById(r.id);
|
||||
if (t)
|
||||
t.set('enabled', e);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal grabber
|
||||
*/
|
||||
var internalPanel = new Ext.form.FieldSet({
|
||||
title : 'Internal Grabber',
|
||||
width : 700,
|
||||
autoHeight : true,
|
||||
collapsible : true,
|
||||
items : [ interval, internalModule, intervalValue, intervalUnit ]
|
||||
});
|
||||
/*
|
||||
* Basic Config
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
* Advanced Fields
|
||||
* ***************************************************************/
|
||||
var confreader = new Ext.data.JsonReader({
|
||||
root: 'epggrabSettings'
|
||||
}, ['module', 'interval', 'channel_rename', 'channel_renumber',
|
||||
'channel_reicon', 'epgdb_periodicsave']);
|
||||
|
||||
/*
|
||||
* External modules
|
||||
*/
|
||||
var externalSelectionModel = new Ext.grid.CheckboxSelectionModel({
|
||||
singleSelect : false,
|
||||
listeners : {
|
||||
'rowselect' : function(s, ri, r) {
|
||||
moduleSelect(r, 1);
|
||||
},
|
||||
'rowdeselect' : function(s, ri, r) {
|
||||
moduleSelect(r, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
/* ****************************************************************
|
||||
* Basic Fields
|
||||
* ***************************************************************/
|
||||
|
||||
var externalColumnModel = new Ext.grid.ColumnModel([ externalSelectionModel,
|
||||
{
|
||||
header : 'Module',
|
||||
dataIndex : 'name',
|
||||
width : 200,
|
||||
sortable : false
|
||||
}, {
|
||||
header : 'Path',
|
||||
dataIndex : 'path',
|
||||
width : 300,
|
||||
sortable : false
|
||||
} ]);
|
||||
/*
|
||||
* Module selector
|
||||
*/
|
||||
var internalModule = new Ext.form.ComboBox({
|
||||
fieldLabel: 'Module',
|
||||
hiddenName: 'module',
|
||||
width: 300,
|
||||
valueField: 'id',
|
||||
displayField: 'name',
|
||||
forceSelection: true,
|
||||
editable: false,
|
||||
mode: 'local',
|
||||
triggerAction: 'all',
|
||||
store: internalModuleStore
|
||||
});
|
||||
|
||||
var externalGrid = new Ext.grid.EditorGridPanel({
|
||||
store : externalModuleStore,
|
||||
cm : externalColumnModel,
|
||||
sm : externalSelectionModel,
|
||||
width : 600,
|
||||
height : 150,
|
||||
frame : false,
|
||||
viewConfig : {
|
||||
forceFit : true
|
||||
},
|
||||
iconCls : 'icon-grid'
|
||||
});
|
||||
/*
|
||||
* Interval selector
|
||||
*/
|
||||
var intervalUnits = [[86400, 'Days'], [3600, 'Hours'],
|
||||
[60, 'Minutes'], [1, 'Seconds']];
|
||||
var intervalValue = new Ext.form.NumberField({
|
||||
width: 300,
|
||||
allowNegative: false,
|
||||
allowDecimals: false,
|
||||
minValue: 1,
|
||||
maxValue: 7,
|
||||
value: 1,
|
||||
fieldLabel: 'Grab interval',
|
||||
name: 'intervalValue',
|
||||
listeners: {
|
||||
'valid': function(e) {
|
||||
v = e.getValue() * intervalUnit.getValue();
|
||||
interval.setValue(v);
|
||||
}
|
||||
}
|
||||
});
|
||||
var intervalUnit = new Ext.form.ComboBox({
|
||||
name: 'intervalUnit',
|
||||
width: 300,
|
||||
valueField: 'key',
|
||||
displayField: 'value',
|
||||
value: 86400,
|
||||
forceSelection: true,
|
||||
editable: false,
|
||||
triggerAction: 'all',
|
||||
mode: 'local',
|
||||
store: new Ext.data.SimpleStore({
|
||||
fields: ['key', 'value'],
|
||||
data: intervalUnits
|
||||
}),
|
||||
listeners: {
|
||||
'change': function(e, n, o) {
|
||||
intervalValue.maxValue = (7 * 86400) / n;
|
||||
intervalValue.validate();
|
||||
}
|
||||
}
|
||||
});
|
||||
var interval = new Ext.form.Hidden({
|
||||
name: 'interval',
|
||||
value: 86400,
|
||||
listeners: {
|
||||
'enable': function(e) {
|
||||
v = e.getValue();
|
||||
for (i = 0; i < intervalUnits.length; i++) {
|
||||
u = intervalUnits[i][0];
|
||||
if ((v % u) === 0) {
|
||||
intervalUnit.setValue(u);
|
||||
intervalValue.maxValue = (7 * 86400) / u;
|
||||
intervalValue.setValue(v / u);
|
||||
intervalValue.validate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var externalPanel = new Ext.form.FieldSet({
|
||||
title : 'External Interfaces',
|
||||
width : 700,
|
||||
autoHeight : true,
|
||||
collapsible : true,
|
||||
collapsed : true,
|
||||
items : [ externalGrid ]
|
||||
});
|
||||
/*
|
||||
* Channel handling
|
||||
*/
|
||||
var channelRename = new Ext.form.Checkbox({
|
||||
name: 'channel_rename',
|
||||
fieldLabel: 'Update channel name'
|
||||
});
|
||||
|
||||
/*
|
||||
* OTA modules
|
||||
*/
|
||||
var channelRenumber = new Ext.form.Checkbox({
|
||||
name: 'channel_renumber',
|
||||
fieldLabel: 'Update channel number'
|
||||
});
|
||||
|
||||
var otaSelectionModel = new Ext.grid.CheckboxSelectionModel({
|
||||
singleSelect : false,
|
||||
listeners : {
|
||||
'rowselect' : function(s, ri, r) {
|
||||
moduleSelect(r, 1);
|
||||
},
|
||||
'rowdeselect' : function(s, ri, r) {
|
||||
moduleSelect(r, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
var channelReicon = new Ext.form.Checkbox({
|
||||
name: 'channel_reicon',
|
||||
fieldLabel: 'Update channel icon'
|
||||
});
|
||||
|
||||
var otaColumnModel = new Ext.grid.ColumnModel([ otaSelectionModel, {
|
||||
header : 'Module',
|
||||
dataIndex : 'name',
|
||||
width : 200,
|
||||
sortable : false
|
||||
} ]);
|
||||
var epgPeriodicSave = new Ext.form.NumberField({
|
||||
width: 30,
|
||||
allowNegative: false,
|
||||
allowDecimals: false,
|
||||
minValue: 0,
|
||||
maxValue: 24,
|
||||
value: 0,
|
||||
fieldLabel: 'Periodic save EPG to disk',
|
||||
name: 'epgdb_periodicsave'
|
||||
});
|
||||
|
||||
var otaGrid = new Ext.grid.EditorGridPanel({
|
||||
store : otaModuleStore,
|
||||
cm : otaColumnModel,
|
||||
sm : otaSelectionModel,
|
||||
width : 600,
|
||||
height : 150,
|
||||
frame : false,
|
||||
viewConfig : {
|
||||
forceFit : true
|
||||
},
|
||||
iconCls : 'icon-grid'
|
||||
});
|
||||
/*
|
||||
* Simple fields
|
||||
*/
|
||||
var simplePanel = new Ext.form.FieldSet({
|
||||
title: 'General Config',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items: [channelRename, channelRenumber, channelReicon, epgPeriodicSave]
|
||||
});
|
||||
|
||||
var otaPanel = new Ext.form.FieldSet({
|
||||
title : 'Over-the-air Grabbers',
|
||||
width : 700,
|
||||
autoHeight : true,
|
||||
collapsible : true,
|
||||
collapsed : true,
|
||||
items : [ otaGrid ]
|
||||
});
|
||||
/*
|
||||
* Internal grabber
|
||||
*/
|
||||
var internalPanel = new Ext.form.FieldSet({
|
||||
title: 'Internal Grabber',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
items: [interval, internalModule, intervalValue, intervalUnit]
|
||||
});
|
||||
|
||||
/* ****************************************************************
|
||||
* Form
|
||||
* ***************************************************************/
|
||||
/* ****************************************************************
|
||||
* Advanced Fields
|
||||
* ***************************************************************/
|
||||
|
||||
var saveButton = new Ext.Button({
|
||||
text : "Save configuration",
|
||||
tooltip : 'Save changes made to configuration below',
|
||||
iconCls : 'save',
|
||||
handler : saveChanges
|
||||
});
|
||||
/*
|
||||
* External modules
|
||||
*/
|
||||
var externalSelectionModel = new Ext.grid.CheckboxSelectionModel({
|
||||
singleSelect: false,
|
||||
listeners: {
|
||||
'rowselect': function(s, ri, r) {
|
||||
moduleSelect(r, 1);
|
||||
},
|
||||
'rowdeselect': function(s, ri, r) {
|
||||
moduleSelect(r, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var helpButton = new Ext.Button({
|
||||
text : 'Help',
|
||||
handler : function() {
|
||||
new tvheadend.help('EPG Grab Configuration', 'config_epggrab.html');
|
||||
}
|
||||
});
|
||||
var externalColumnModel = new Ext.grid.ColumnModel([externalSelectionModel,
|
||||
{
|
||||
header: 'Module',
|
||||
dataIndex: 'name',
|
||||
width: 200,
|
||||
sortable: false
|
||||
}, {
|
||||
header: 'Path',
|
||||
dataIndex: 'path',
|
||||
width: 300,
|
||||
sortable: false
|
||||
}]);
|
||||
|
||||
var confpanel = new Ext.FormPanel({
|
||||
title : 'EPG Grabber',
|
||||
iconCls : 'xml',
|
||||
border : false,
|
||||
bodyStyle : 'padding:15px',
|
||||
labelAlign : 'left',
|
||||
labelWidth : 150,
|
||||
waitMsgTarget : true,
|
||||
reader : confreader,
|
||||
layout : 'form',
|
||||
defaultType : 'textfield',
|
||||
autoHeight : true,
|
||||
items : [ simplePanel, internalPanel, otaPanel, externalPanel ],
|
||||
tbar : [ saveButton, '->', helpButton ]
|
||||
});
|
||||
var externalGrid = new Ext.grid.EditorGridPanel({
|
||||
store: externalModuleStore,
|
||||
cm: externalColumnModel,
|
||||
sm: externalSelectionModel,
|
||||
width: 600,
|
||||
height: 150,
|
||||
frame: false,
|
||||
viewConfig: {
|
||||
forceFit: true
|
||||
},
|
||||
iconCls: 'icon-grid'
|
||||
});
|
||||
|
||||
/* ****************************************************************
|
||||
* Load/Save
|
||||
* ***************************************************************/
|
||||
var externalPanel = new Ext.form.FieldSet({
|
||||
title: 'External Interfaces',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [externalGrid]
|
||||
});
|
||||
|
||||
/* HACK: get display working */
|
||||
externalGrid.on('render', function() {
|
||||
delay = new Ext.util.DelayedTask(function() {
|
||||
rows = [];
|
||||
externalModuleStore.each(function(r) {
|
||||
if (r.get('enabled')) rows.push(r);
|
||||
});
|
||||
externalSelectionModel.selectRecords(rows);
|
||||
});
|
||||
delay.delay(100);
|
||||
});
|
||||
otaGrid.on('render', function() {
|
||||
delay = new Ext.util.DelayedTask(function() {
|
||||
rows = [];
|
||||
otaModuleStore.each(function(r) {
|
||||
if (r.get('enabled')) rows.push(r);
|
||||
});
|
||||
otaSelectionModel.selectRecords(rows);
|
||||
});
|
||||
delay.delay(100);
|
||||
});
|
||||
/*
|
||||
* OTA modules
|
||||
*/
|
||||
|
||||
confpanel.on('render', function() {
|
||||
var otaSelectionModel = new Ext.grid.CheckboxSelectionModel({
|
||||
singleSelect: false,
|
||||
listeners: {
|
||||
'rowselect': function(s, ri, r) {
|
||||
moduleSelect(r, 1);
|
||||
},
|
||||
'rowdeselect': function(s, ri, r) {
|
||||
moduleSelect(r, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Hack to get display working */
|
||||
delay = new Ext.util.DelayedTask(function() {
|
||||
simplePanel.doLayout(false);
|
||||
internalPanel.doLayout(false);
|
||||
externalPanel.doLayout(false);
|
||||
otaPanel.doLayout(false);
|
||||
});
|
||||
delay.delay(100);
|
||||
var otaColumnModel = new Ext.grid.ColumnModel([otaSelectionModel, {
|
||||
header: 'Module',
|
||||
dataIndex: 'name',
|
||||
width: 200,
|
||||
sortable: false
|
||||
}]);
|
||||
|
||||
confpanel.getForm().load({
|
||||
url : 'epggrab',
|
||||
params : {
|
||||
op : 'loadSettings'
|
||||
},
|
||||
success : function(form, action) {
|
||||
confpanel.enable();
|
||||
}
|
||||
});
|
||||
});
|
||||
var otaGrid = new Ext.grid.EditorGridPanel({
|
||||
store: otaModuleStore,
|
||||
cm: otaColumnModel,
|
||||
sm: otaSelectionModel,
|
||||
width: 600,
|
||||
height: 150,
|
||||
frame: false,
|
||||
viewConfig: {
|
||||
forceFit: true
|
||||
},
|
||||
iconCls: 'icon-grid'
|
||||
});
|
||||
|
||||
function saveChanges() {
|
||||
mods = [];
|
||||
moduleStore.each(function(r) {
|
||||
mods.push({
|
||||
id : r.get('id'),
|
||||
enabled : r.get('enabled') ? 1 : 0
|
||||
});
|
||||
});
|
||||
mods = Ext.util.JSON.encode(mods);
|
||||
confpanel.getForm().submit({
|
||||
url : 'epggrab',
|
||||
params : {
|
||||
op : 'saveSettings',
|
||||
external : mods
|
||||
},
|
||||
waitMsg : 'Saving Data...',
|
||||
success : function(form, action) {
|
||||
externalModuleStore.commitChanges();
|
||||
},
|
||||
failure : function(form, action) {
|
||||
Ext.Msg.alert('Save failed', action.result.errormsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
var otaPanel = new Ext.form.FieldSet({
|
||||
title: 'Over-the-air Grabbers',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [otaGrid]
|
||||
});
|
||||
|
||||
return confpanel;
|
||||
}
|
||||
/* ****************************************************************
|
||||
* Form
|
||||
* ***************************************************************/
|
||||
|
||||
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('EPG Grab Configuration', 'config_epggrab.html');
|
||||
}
|
||||
});
|
||||
|
||||
var confpanel = new Ext.FormPanel({
|
||||
title: 'EPG Grabber',
|
||||
iconCls: 'xml',
|
||||
border: false,
|
||||
bodyStyle: 'padding:15px',
|
||||
labelAlign: 'left',
|
||||
labelWidth: 150,
|
||||
waitMsgTarget: true,
|
||||
reader: confreader,
|
||||
layout: 'form',
|
||||
defaultType: 'textfield',
|
||||
autoHeight: true,
|
||||
items: [simplePanel, internalPanel, otaPanel, externalPanel],
|
||||
tbar: [saveButton, '->', helpButton]
|
||||
});
|
||||
|
||||
/* ****************************************************************
|
||||
* Load/Save
|
||||
* ***************************************************************/
|
||||
|
||||
/* HACK: get display working */
|
||||
externalGrid.on('render', function() {
|
||||
delay = new Ext.util.DelayedTask(function() {
|
||||
rows = [];
|
||||
externalModuleStore.each(function(r) {
|
||||
if (r.get('enabled'))
|
||||
rows.push(r);
|
||||
});
|
||||
externalSelectionModel.selectRecords(rows);
|
||||
});
|
||||
delay.delay(100);
|
||||
});
|
||||
otaGrid.on('render', function() {
|
||||
delay = new Ext.util.DelayedTask(function() {
|
||||
rows = [];
|
||||
otaModuleStore.each(function(r) {
|
||||
if (r.get('enabled'))
|
||||
rows.push(r);
|
||||
});
|
||||
otaSelectionModel.selectRecords(rows);
|
||||
});
|
||||
delay.delay(100);
|
||||
});
|
||||
|
||||
confpanel.on('render', function() {
|
||||
|
||||
/* Hack to get display working */
|
||||
delay = new Ext.util.DelayedTask(function() {
|
||||
simplePanel.doLayout(false);
|
||||
internalPanel.doLayout(false);
|
||||
externalPanel.doLayout(false);
|
||||
otaPanel.doLayout(false);
|
||||
});
|
||||
delay.delay(100);
|
||||
|
||||
confpanel.getForm().load({
|
||||
url: 'epggrab',
|
||||
params: {
|
||||
op: 'loadSettings'
|
||||
},
|
||||
success: function(form, action) {
|
||||
confpanel.enable();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function saveChanges() {
|
||||
mods = [];
|
||||
moduleStore.each(function(r) {
|
||||
mods.push({
|
||||
id: r.get('id'),
|
||||
enabled: r.get('enabled') ? 1 : 0
|
||||
});
|
||||
});
|
||||
mods = Ext.util.JSON.encode(mods);
|
||||
confpanel.getForm().submit({
|
||||
url: 'epggrab',
|
||||
params: {
|
||||
op: 'saveSettings',
|
||||
external: mods
|
||||
},
|
||||
waitMsg: 'Saving Data...',
|
||||
success: function(form, action) {
|
||||
externalModuleStore.commitChanges();
|
||||
},
|
||||
failure: function(form, action) {
|
||||
Ext.Msg.alert('Save failed', action.result.errormsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return confpanel;
|
||||
};
|
||||
|
|
|
@ -4,105 +4,105 @@
|
|||
|
||||
tvheadend.esfilter_tab = function(panel)
|
||||
{
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url : 'api/esfilter/video',
|
||||
comet : 'esfilter_video',
|
||||
titleS : 'Video Stream Filter',
|
||||
titleP : 'Video Stream Filters',
|
||||
tabIndex : 0,
|
||||
add : {
|
||||
url : 'api/esfilter/video',
|
||||
create : {}
|
||||
},
|
||||
del : true,
|
||||
move : true,
|
||||
help : function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/esfilter/video',
|
||||
comet: 'esfilter_video',
|
||||
titleS: 'Video Stream Filter',
|
||||
titleP: 'Video Stream Filters',
|
||||
tabIndex: 0,
|
||||
add: {
|
||||
url: 'api/esfilter/video',
|
||||
create: {}
|
||||
},
|
||||
del: true,
|
||||
move: true,
|
||||
help: function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url : 'api/esfilter/audio',
|
||||
comet : 'esfilter_audio',
|
||||
titleS : 'Audio Stream Filter',
|
||||
titleP : 'Audio Stream Filters',
|
||||
tabIndex : 1,
|
||||
add : {
|
||||
url : 'api/esfilter/audio',
|
||||
create : {}
|
||||
},
|
||||
del : true,
|
||||
move : true,
|
||||
help : function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/esfilter/audio',
|
||||
comet: 'esfilter_audio',
|
||||
titleS: 'Audio Stream Filter',
|
||||
titleP: 'Audio Stream Filters',
|
||||
tabIndex: 1,
|
||||
add: {
|
||||
url: 'api/esfilter/audio',
|
||||
create: {}
|
||||
},
|
||||
del: true,
|
||||
move: true,
|
||||
help: function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url : 'api/esfilter/teletext',
|
||||
comet : 'esfilter_teletext',
|
||||
titleS : 'Teletext Stream Filter',
|
||||
titleP : 'Teletext Stream Filters',
|
||||
tabIndex : 2,
|
||||
add : {
|
||||
url : 'api/esfilter/teletext',
|
||||
create : {}
|
||||
},
|
||||
del : true,
|
||||
move : true,
|
||||
help : function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/esfilter/teletext',
|
||||
comet: 'esfilter_teletext',
|
||||
titleS: 'Teletext Stream Filter',
|
||||
titleP: 'Teletext Stream Filters',
|
||||
tabIndex: 2,
|
||||
add: {
|
||||
url: 'api/esfilter/teletext',
|
||||
create: {}
|
||||
},
|
||||
del: true,
|
||||
move: true,
|
||||
help: function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url : 'api/esfilter/subtit',
|
||||
comet : 'esfilter_subtit',
|
||||
titleS : 'Subtitle Stream Filter',
|
||||
titleP : 'Subtitle Stream Filters',
|
||||
tabIndex : 3,
|
||||
add : {
|
||||
url : 'api/esfilter/subtit',
|
||||
create : {}
|
||||
},
|
||||
del : true,
|
||||
move : true,
|
||||
help : function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/esfilter/subtit',
|
||||
comet: 'esfilter_subtit',
|
||||
titleS: 'Subtitle Stream Filter',
|
||||
titleP: 'Subtitle Stream Filters',
|
||||
tabIndex: 3,
|
||||
add: {
|
||||
url: 'api/esfilter/subtit',
|
||||
create: {}
|
||||
},
|
||||
del: true,
|
||||
move: true,
|
||||
help: function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url : 'api/esfilter/ca',
|
||||
comet : 'esfilter_ca',
|
||||
titleS : 'CA Stream Filter',
|
||||
titleP : 'CA Stream Filters',
|
||||
tabIndex : 4,
|
||||
add : {
|
||||
url : 'api/esfilter/ca',
|
||||
create : {}
|
||||
},
|
||||
del : true,
|
||||
move : true,
|
||||
help : function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/esfilter/ca',
|
||||
comet: 'esfilter_ca',
|
||||
titleS: 'CA Stream Filter',
|
||||
titleP: 'CA Stream Filters',
|
||||
tabIndex: 4,
|
||||
add: {
|
||||
url: 'api/esfilter/ca',
|
||||
create: {}
|
||||
},
|
||||
del: true,
|
||||
move: true,
|
||||
help: function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url : 'api/esfilter/other',
|
||||
comet : 'esfilter_other',
|
||||
titleS : 'Other Stream Filter',
|
||||
titleP : 'Other Stream Filters',
|
||||
tabIndex : 5,
|
||||
add : {
|
||||
url : 'api/esfilter/other',
|
||||
create : {}
|
||||
},
|
||||
del : true,
|
||||
move : true,
|
||||
help : function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
}
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/esfilter/other',
|
||||
comet: 'esfilter_other',
|
||||
titleS: 'Other Stream Filter',
|
||||
titleP: 'Other Stream Filters',
|
||||
tabIndex: 5,
|
||||
add: {
|
||||
url: 'api/esfilter/other',
|
||||
create: {}
|
||||
},
|
||||
del: true,
|
||||
move: true,
|
||||
help: function() {
|
||||
new tvheadend.help('Elementary Stream Filter', 'config_esfilter.html');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://extjs.com/license
|
||||
*/
|
||||
#header {
|
||||
font-family: tahoma,arial;
|
||||
font-family: tahoma,arial;
|
||||
background-color: #507AAA;
|
||||
color: #F8F8F8;
|
||||
height: 5.3em;
|
||||
|
@ -15,8 +15,8 @@
|
|||
background: url("../img/bg-header.png") repeat-x scroll 0 0 transparent;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
#header > h1 {
|
||||
|
||||
#header > h1 {
|
||||
background: url("../img/logo.png") no-repeat scroll 10px 20% transparent;
|
||||
color: #E0E0E0;
|
||||
font-size: 22px;
|
||||
|
@ -25,341 +25,341 @@
|
|||
}
|
||||
|
||||
.x-tree-col {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
padding: 0 1px;
|
||||
zoom: 1;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
padding: 0 1px;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.x-tree-col-text,.x-tree-hd-text {
|
||||
overflow: hidden;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
padding: 3px 3px 3px 5px;
|
||||
white-space: nowrap;
|
||||
font: normal 11px arial, tahoma, helvetica, sans-serif;
|
||||
overflow: hidden;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
padding: 3px 3px 3px 5px;
|
||||
white-space: nowrap;
|
||||
font: normal 11px arial, tahoma, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.x-tree-headers {
|
||||
background: #f9f9f9
|
||||
url(../extjs/resources/images/default/grid/grid3-hrow.gif) repeat-x 0
|
||||
bottom;
|
||||
cursor: default;
|
||||
zoom: 1;
|
||||
background: #f9f9f9
|
||||
url(../extjs/resources/images/default/grid/grid3-hrow.gif) repeat-x 0
|
||||
bottom;
|
||||
cursor: default;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.x-tree-hd {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
border-left: 1px solid #eee;
|
||||
border-right: 1px solid #d0d0d0;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
border-left: 1px solid #eee;
|
||||
border-right: 1px solid #d0d0d0;
|
||||
}
|
||||
|
||||
.ux-mselect {
|
||||
overflow: auto;
|
||||
background: white;
|
||||
position: relative; /* for calculating scroll offsets */
|
||||
zoom: 1;
|
||||
overflow: auto;
|
||||
overflow: auto;
|
||||
background: white;
|
||||
position: relative; /* for calculating scroll offsets */
|
||||
zoom: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.ux-mselect-item {
|
||||
font: normal 12px tahoma, arial, helvetica, sans-serif;
|
||||
padding: 2px;
|
||||
border: 1px solid #fff;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
font: normal 12px tahoma, arial, helvetica, sans-serif;
|
||||
padding: 2px;
|
||||
border: 1px solid #fff;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ux-mselect-selected {
|
||||
border: 1px dotted #a3bae9 !important;
|
||||
background: #DFE8F6;
|
||||
cursor: pointer;
|
||||
border: 1px dotted #a3bae9 !important;
|
||||
background: #DFE8F6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.x-view-drag-insert-above {
|
||||
border-top: 1px dotted #3366cc;
|
||||
border-top: 1px dotted #3366cc;
|
||||
}
|
||||
|
||||
.x-view-drag-insert-below {
|
||||
border-bottom: 1px dotted #3366cc;
|
||||
border-bottom: 1px dotted #3366cc;
|
||||
}
|
||||
|
||||
.x-grid3-progresscol .x-grid3-cell-inner {
|
||||
padding: 0px 0px 0px 5px;
|
||||
padding: 0px 0px 0px 5px;
|
||||
}
|
||||
|
||||
.x-grid3-progresscol .x-progress-bar {
|
||||
height: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.x-grid3-progresscol .x-progress-inner {
|
||||
height: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.x-grid3-progresscol .x-progress-text-front-ie6 {
|
||||
padding: 2.5px 5px;
|
||||
padding: 2.5px 5px;
|
||||
}
|
||||
|
||||
.x-grid3-progresscol .x-progress-text-front {
|
||||
padding: 2px 5px;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
.x-progress-bar-red,.x-progress-bar-orange,.x-progress-bar-green {
|
||||
border-bottom: 1px solid #7fa9e4;
|
||||
float: left;
|
||||
height: 16px;
|
||||
border-bottom: 1px solid #7fa9e4;
|
||||
float: left;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.x-progress-bar-red {
|
||||
background: #ff0000 url(../icons/progress-bg-red.gif) repeat-x scroll
|
||||
left center;
|
||||
border-top: 1px solid #ecb7ad;
|
||||
background: #ff0000 url(../icons/progress-bg-red.gif) repeat-x scroll
|
||||
left center;
|
||||
border-top: 1px solid #ecb7ad;
|
||||
}
|
||||
|
||||
.x-progress-bar-orange {
|
||||
background: #9cbfee url(../icons/progress-bg-orange.gif) repeat-x scroll
|
||||
left center;
|
||||
border-right: 1px solid #deab7e;
|
||||
border-top: 1px solid #d7b290;
|
||||
background: #9cbfee url(../icons/progress-bg-orange.gif) repeat-x scroll
|
||||
left center;
|
||||
border-right: 1px solid #deab7e;
|
||||
border-top: 1px solid #d7b290;
|
||||
}
|
||||
|
||||
.x-progress-bar-green {
|
||||
background: #00ff00 url(../icons/progress-bg-green.gif) repeat-x scroll
|
||||
left center;
|
||||
border-right: 1px solid #5bd976;
|
||||
border-top: 1px solid #79e18f;
|
||||
background: #00ff00 url(../icons/progress-bg-green.gif) repeat-x scroll
|
||||
left center;
|
||||
border-right: 1px solid #5bd976;
|
||||
border-top: 1px solid #79e18f;
|
||||
}
|
||||
|
||||
.tvh-grid-unset {
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.add {
|
||||
background-image: url(../icons/add.png) !important;
|
||||
background-image: url(../icons/add.png) !important;
|
||||
}
|
||||
|
||||
.option {
|
||||
background-image: url(../icons/plugin.png) !important;
|
||||
background-image: url(../icons/plugin.png) !important;
|
||||
}
|
||||
|
||||
.remove {
|
||||
background-image: url(../icons/delete.png) !important;
|
||||
background-image: url(../icons/delete.png) !important;
|
||||
}
|
||||
|
||||
.moveup {
|
||||
background-image: url(../icons/arrow_up.png) !important;
|
||||
background-image: url(../icons/arrow_up.png) !important;
|
||||
}
|
||||
|
||||
.movedown {
|
||||
background-image: url(../icons/arrow_down.png) !important;
|
||||
background-image: url(../icons/arrow_down.png) !important;
|
||||
}
|
||||
|
||||
.save {
|
||||
background-image: url(../icons/save.png) !important;
|
||||
background-image: url(../icons/save.png) !important;
|
||||
}
|
||||
|
||||
.rec {
|
||||
background-image: url(../icons/rec.png) !important;
|
||||
background-image: url(../icons/rec.png) !important;
|
||||
}
|
||||
|
||||
.info {
|
||||
background-image: url(../icons/information.png) !important;
|
||||
background-image: url(../icons/information.png) !important;
|
||||
}
|
||||
|
||||
.undo {
|
||||
background-image: url(../icons/undo.png) !important;
|
||||
background-image: url(../icons/undo.png) !important;
|
||||
}
|
||||
|
||||
.edit {
|
||||
background-image: url(../icons/edit.png) !important;
|
||||
background-image: url(../icons/edit.png) !important;
|
||||
}
|
||||
|
||||
.key {
|
||||
background-image: url(../icons/key.png) !important;
|
||||
background-image: url(../icons/key.png) !important;
|
||||
}
|
||||
|
||||
.tags {
|
||||
background-image: url(../icons/tag_blue.png) !important;
|
||||
background-image: url(../icons/tag_blue.png) !important;
|
||||
}
|
||||
|
||||
.xml {
|
||||
background-image: url(../icons/tag.png) !important;
|
||||
background-image: url(../icons/tag.png) !important;
|
||||
}
|
||||
|
||||
.drive {
|
||||
background-image: url(../icons/drive.png) !important;
|
||||
background-image: url(../icons/drive.png) !important;
|
||||
}
|
||||
|
||||
.group {
|
||||
background-image: url(../icons/group.png) !important;
|
||||
background-image: url(../icons/group.png) !important;
|
||||
}
|
||||
|
||||
.hardware {
|
||||
background-image: url(../icons/pci.png) !important;
|
||||
background-image: url(../icons/pci.png) !important;
|
||||
}
|
||||
|
||||
.television {
|
||||
background-image: url(../icons/television.png) !important;
|
||||
background-image: url(../icons/television.png) !important;
|
||||
}
|
||||
|
||||
.eye {
|
||||
background-image: url(../icons/eye.png) !important;
|
||||
background-image: url(../icons/eye.png) !important;
|
||||
}
|
||||
|
||||
.control_play {
|
||||
background-image: url(../icons/control_play.png) !important;
|
||||
background-image: url(../icons/control_play.png) !important;
|
||||
}
|
||||
|
||||
.control_pause {
|
||||
background-image: url(../icons/control_pause.png) !important;
|
||||
background-image: url(../icons/control_pause.png) !important;
|
||||
}
|
||||
|
||||
.control_stop {
|
||||
background-image: url(../icons/control_stop.png) !important;
|
||||
background-image: url(../icons/control_stop.png) !important;
|
||||
}
|
||||
|
||||
.control_volume {
|
||||
background-image: url(../icons/sound.png) !important;
|
||||
background-image: url(../icons/sound.png) !important;
|
||||
}
|
||||
|
||||
.control_fullscreen {
|
||||
background-image: url(../icons/arrow_out.png) !important;
|
||||
background-image: url(../icons/arrow_out.png) !important;
|
||||
}
|
||||
|
||||
.newspaper {
|
||||
background-image: url(../icons/newspaper.png) !important;
|
||||
background-image: url(../icons/newspaper.png) !important;
|
||||
}
|
||||
|
||||
.clock {
|
||||
background-image: url(../icons/clock.png) !important;
|
||||
background-image: url(../icons/clock.png) !important;
|
||||
}
|
||||
|
||||
.exclamation {
|
||||
background-image: url(../icons/exclamation.png) !important;
|
||||
background-image: url(../icons/exclamation.png) !important;
|
||||
}
|
||||
|
||||
.wrench {
|
||||
background-image: url(../icons/wrench.png) !important;
|
||||
background-image: url(../icons/wrench.png) !important;
|
||||
}
|
||||
|
||||
.wand {
|
||||
background-image: url(../icons/wand.png) !important;
|
||||
background-image: url(../icons/wand.png) !important;
|
||||
}
|
||||
|
||||
.merge {
|
||||
background-image: url(../icons/arrow_join.png) !important;
|
||||
background-image: url(../icons/arrow_join.png) !important;
|
||||
}
|
||||
|
||||
.iptv {
|
||||
background-image: url(../icons/world.png) !important;
|
||||
background-image: url(../icons/world.png) !important;
|
||||
}
|
||||
|
||||
.clone {
|
||||
background-image: url(../icons/layers.png) !important;
|
||||
background-image: url(../icons/layers.png) !important;
|
||||
}
|
||||
|
||||
.scheduled {
|
||||
background-image: url(../icons/clock.png) !important;
|
||||
background-image: url(../icons/clock.png) !important;
|
||||
}
|
||||
|
||||
.recordingError {
|
||||
background-image: url(../icons/exclamation.png) !important;
|
||||
background-image: url(../icons/exclamation.png) !important;
|
||||
}
|
||||
|
||||
.completed {
|
||||
background-image: url(../icons/tick.png) !important;
|
||||
background-image: url(../icons/tick.png) !important;
|
||||
}
|
||||
|
||||
.completedError {
|
||||
background-image: url(../icons/exclamation.png) !important;
|
||||
background-image: url(../icons/exclamation.png) !important;
|
||||
}
|
||||
|
||||
.recording {
|
||||
background-image: url(../icons/rec.png) !important;
|
||||
background-image: url(../icons/rec.png) !important;
|
||||
}
|
||||
|
||||
.bullet_add {
|
||||
background-image: url(../icons/bullet_add.png) !important;
|
||||
background-image: url(../icons/bullet_add.png) !important;
|
||||
}
|
||||
|
||||
.arrow_up {
|
||||
background-image: url(../icons/arrow_up.png) !important;
|
||||
background-image: url(../icons/arrow_up.png) !important;
|
||||
}
|
||||
|
||||
.arrow_down {
|
||||
background-image: url(../icons/arrow_down.png) !important;
|
||||
background-image: url(../icons/arrow_down.png) !important;
|
||||
}
|
||||
|
||||
.arrow_switch {
|
||||
background-image: url(../icons/arrow_switch.png) !important;
|
||||
background-image: url(../icons/arrow_switch.png) !important;
|
||||
|
||||
}
|
||||
|
||||
.stream_config {
|
||||
background-image: url(../icons/film_edit.png) !important;
|
||||
background-image: url(../icons/film_edit.png) !important;
|
||||
}
|
||||
|
||||
.x-smallhdr {
|
||||
float: left;
|
||||
width: 100px;
|
||||
float: left;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.x-epg-title {
|
||||
margin: 5px;
|
||||
font: normal 15px arial, tahoma, helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
margin: 5px;
|
||||
font: normal 15px arial, tahoma, helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.x-epg-subtitle {
|
||||
margin: 5px;
|
||||
font: normal 12px arial, tahoma, helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
margin: 5px;
|
||||
font: normal 12px arial, tahoma, helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.x-epg-desc {
|
||||
margin: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.x-epg-chicon {
|
||||
float: right;
|
||||
margin: 5px;
|
||||
max-width: 132px;
|
||||
max-height: 99px;
|
||||
float: right;
|
||||
margin: 5px;
|
||||
max-width: 132px;
|
||||
max-height: 99px;
|
||||
}
|
||||
|
||||
.x-epg-meta {
|
||||
margin: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.hts-t-info {
|
||||
float: left;
|
||||
width: 100px;
|
||||
float: left;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.hts-doc-text {
|
||||
font: normal 11px verdana;
|
||||
padding: 5px;
|
||||
font: normal 11px verdana;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.hts-doc-text dt {
|
||||
padding-top: 10px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hts-doc-text dl {
|
||||
padding-left: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.hts-doc-text li {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.hts-doc-text img {
|
||||
padding: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.tv-video-player {
|
||||
|
@ -384,8 +384,8 @@
|
|||
}
|
||||
|
||||
.about-title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/** vim: ts=4:sw=4:nu:fdc=4:nospell
|
||||
|
@ -408,69 +408,69 @@
|
|||
|
||||
/* styles for rows */
|
||||
.ux-row-action-cell .x-grid3-cell-inner {
|
||||
padding: 1px 0 0 0;
|
||||
padding: 1px 0 0 0;
|
||||
}
|
||||
|
||||
.ux-row-action-item {
|
||||
float: left;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
margin: 0 5px 0 0;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
margin: 0 5px 0 0;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ext-ie .ux-row-action-item {
|
||||
width: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.ext-ie .ux-row-action-text {
|
||||
width: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.ux-row-action-item span {
|
||||
vertical-align: middle;
|
||||
padding: 0 0 0 20px;
|
||||
line-height: 18px;
|
||||
vertical-align: middle;
|
||||
padding: 0 0 0 20px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.ext-ie .ux-row-action-item span {
|
||||
width: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* styles for groups */
|
||||
.x-grid-group-hd div {
|
||||
position: relative;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.ux-grow-action-item {
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 50% ! important;
|
||||
margin: 0 0 0 4px;
|
||||
padding: 0 ! important;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 50% ! important;
|
||||
margin: 0 0 0 4px;
|
||||
padding: 0 ! important;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ext-ie .ux-grow-action-item {
|
||||
width: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.ux-action-right {
|
||||
float: right;
|
||||
margin: 0 3px 0 2px;
|
||||
padding: 0 ! important;
|
||||
float: right;
|
||||
margin: 0 3px 0 2px;
|
||||
padding: 0 ! important;
|
||||
}
|
||||
|
||||
.ux-grow-action-text {
|
||||
padding: 0 ! important;
|
||||
margin: 0 ! important;
|
||||
background: transparent none ! important;
|
||||
float: left;
|
||||
padding: 0 ! important;
|
||||
margin: 0 ! important;
|
||||
background: transparent none ! important;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/** vim: ts=4:sw=4:nu:fdc=4:nospell
|
||||
|
@ -490,21 +490,21 @@
|
|||
* License details: http://www.gnu.org/licenses/lgpl.html
|
||||
*/
|
||||
.ux-lovcombo-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
float: left;
|
||||
background-position: -1px -1px ! important;
|
||||
background-repeat: no-repeat ! important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
float: left;
|
||||
background-position: -1px -1px ! important;
|
||||
background-repeat: no-repeat ! important;
|
||||
}
|
||||
|
||||
.ux-lovcombo-icon-checked {
|
||||
background: transparent
|
||||
url(../extjs/resources/images/default/menu/checked.gif);
|
||||
background: transparent
|
||||
url(../extjs/resources/images/default/menu/checked.gif);
|
||||
}
|
||||
|
||||
.ux-lovcombo-icon-unchecked {
|
||||
background: transparent
|
||||
url(../extjs/resources/images/default/menu/unchecked.gif);
|
||||
background: transparent
|
||||
url(../extjs/resources/images/default/menu/unchecked.gif);
|
||||
}
|
||||
|
||||
/* eof */
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
: '<span class="tvh-grid-unset">Unmapped</span>';
|
||||
},
|
||||
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 : '<span class="tvh-grid-unset">Unset</span>';
|
||||
},
|
||||
editor : new fm.TextField({
|
||||
allowBlank : false
|
||||
})
|
||||
},
|
||||
{
|
||||
header : "Group",
|
||||
dataIndex : 'group',
|
||||
width : 100,
|
||||
renderer : function(value, metadata, record, row, col, store) {
|
||||
return value ? value : '<span class="tvh-grid-unset">Unset</span>';
|
||||
},
|
||||
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')
|
||||
: '<span class="tvh-grid-unset">Unset</span>';
|
||||
}
|
||||
}, {
|
||||
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
|
||||
: '<span class="tvh-grid-unset">Unmapped</span>';
|
||||
},
|
||||
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 : '<span class="tvh-grid-unset">Unset</span>';
|
||||
},
|
||||
editor: new fm.TextField({
|
||||
allowBlank: false
|
||||
})
|
||||
},
|
||||
{
|
||||
header: "Group",
|
||||
dataIndex: 'group',
|
||||
width: 100,
|
||||
renderer: function(value, metadata, record, row, col, store) {
|
||||
return value ? value : '<span class="tvh-grid-unset">Unset</span>';
|
||||
},
|
||||
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')
|
||||
: '<span class="tvh-grid-unset">Unset</span>';
|
||||
}
|
||||
}, {
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -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 "<a href='stream/mux/" + r.id + "'>Play</a>";
|
||||
}
|
||||
}
|
||||
],
|
||||
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 "<a href='stream/mux/" + r.id + "'>Play</a>";
|
||||
});
|
||||
};
|
||||
|
||||
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 += '<table style="font-size:8pt;font-family:mono;padding:2px"';
|
||||
html += '<tr>';
|
||||
html += '<th style="width:50px;font-weight:bold">Index</th>';
|
||||
html += '<th style="width:120px;font-weight:bold">PID</th>';
|
||||
html += '<th style="width:100px;font-weight:bold">Type</th>';
|
||||
html += '<th style="width:75px;font-weight:bold">Language</th>';
|
||||
html += '<th style="width:*;font-weight:bold">Details</th>';
|
||||
html += '</tr>';
|
||||
|
||||
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 += '<table style="font-size:8pt;font-family:mono;padding:2px"';
|
||||
html += '<tr>';
|
||||
html += '<th style="width:50px;font-weight:bold">Index</th>';
|
||||
html += '<th style="width:120px;font-weight:bold">PID</th>';
|
||||
html += '<th style="width:100px;font-weight:bold">Type</th>';
|
||||
html += '<th style="width:75px;font-weight:bold">Language</th>';
|
||||
html += '<th style="width:*;font-weight:bold">Details</th>';
|
||||
html += '</tr>';
|
||||
|
||||
}
|
||||
|
||||
function single ( s ) {
|
||||
html += '<tr><td colspan="5">' + s + '</td></tr>';
|
||||
}
|
||||
|
||||
function stream ( s ) {
|
||||
var d = ' ';
|
||||
var p = '0x' + hexstr(s.pid) + ' / ' + fixstr(s.pid);
|
||||
|
||||
html += '<tr>';
|
||||
html += '<td>' + (s.index > 0 ? s.index : ' ') + '</td>';
|
||||
html += '<td>' + p + '</td>';
|
||||
html += '<td>' + s.type + '</td>';
|
||||
html += '<td>' + (s.language || ' ') + '</td>'
|
||||
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 += '<tr><td colspan="5">' + s + '</td></tr>';
|
||||
}
|
||||
html += '<td>' + d + '</td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
|
||||
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 += '<tr>';
|
||||
html += '<td>' + (s.index > 0 ? s.index : ' ') + '</td>';
|
||||
html += '<td>' + p + '</td>';
|
||||
html += '<td>' + s.type + '</td>';
|
||||
html += '<td>' + (s.language || ' ') + '</td>';
|
||||
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 += '<td>' + d + '</td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
|
||||
single(' ');
|
||||
single('<h3>After filtering and reordering (without PCR and PMT)</h3>');
|
||||
header();
|
||||
header();
|
||||
|
||||
if (data.fstreams.length)
|
||||
for (i = 0; i < data.fstreams.length; i++)
|
||||
stream(data.fstreams[i]);
|
||||
else
|
||||
single('<p>None</p>');
|
||||
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('<h3>After filtering and reordering (without PCR and PMT)</h3>');
|
||||
header();
|
||||
|
||||
if (data.fstreams.length)
|
||||
for (i = 0; i < data.fstreams.length; i++)
|
||||
stream(data.fstreams[i]);
|
||||
else
|
||||
single('<p>None</p>');
|
||||
|
||||
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 "<a href='stream/service/" + r.id + "'>Play</a>";
|
||||
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 "<a href='stream/service/" + r.id + "'>Play</a>";
|
||||
}
|
||||
},
|
||||
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
|
||||
});
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -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 ? '<div style="' + style + '">' : '<div>'
|
||||
s = style ? '<div style="' + style + '">' : '<div>';
|
||||
|
||||
sl = Ext.get('systemlog');
|
||||
e = Ext.DomHelper.append(sl, s + '<pre>' + msg + '</pre></div>');
|
||||
e.scrollIntoView('systemlog');
|
||||
}
|
||||
sl = Ext.get('systemlog');
|
||||
e = Ext.DomHelper.append(sl, s + '<pre>' + msg + '</pre></div>');
|
||||
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: '<div id="header"><h1>Tvheadend Web-Panel</h1></div>'
|
||||
});
|
||||
|
||||
// public methods
|
||||
init : function() {
|
||||
var header = new Ext.Panel({
|
||||
split: true,
|
||||
region: 'north',
|
||||
height : 45,
|
||||
boxMaxHeight : 45,
|
||||
boxMinHeight : 45,
|
||||
border: false,
|
||||
hidden: true,
|
||||
html: '<div id="header"><h1>Tvheadend Web-Panel</h1></div>'
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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(
|
||||
'<h2 style="font-size: 150%">Hardware</h2>'
|
||||
+ '<h3>Device path:</h3>{path}' + '<h3>Device name:</h3>{devicename}'
|
||||
+ '<h2 style="font-size: 150%">Status</h2>'
|
||||
+ '<h3>Currently tuned to:</h3>{currentMux} ');
|
||||
var infoTemplate = new Ext.XTemplate(
|
||||
'<h2 style="font-size: 150%">Hardware</h2>'
|
||||
+ '<h3>Device path:</h3>{path}' + '<h3>Device name:</h3>{devicename}'
|
||||
+ '<h2 style="font-size: 150%">Status</h2>'
|
||||
+ '<h3>Currently tuned to:</h3>{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 : '<span class="tvh-grid-unset">Unmapped</span>';
|
||||
},
|
||||
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 : '<span class="tvh-grid-unset">Unmapped</span>';
|
||||
},
|
||||
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;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue