Add scheduler plugin page to webui
This commit is contained in:
parent
101ad99c14
commit
4a7876f203
|
@ -1,17 +1,88 @@
|
||||||
ScheduleSelectPanel = Ext.extend(Ext.form.FieldSet, {
|
/*
|
||||||
constructor: function(config) {
|
Script: scheduler.js
|
||||||
config = Ext.apply({
|
The client-side javascript code for the Scheduler plugin.
|
||||||
|
|
||||||
|
Copyright:
|
||||||
|
(C) samuel337 2011
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, write to:
|
||||||
|
The Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give
|
||||||
|
permission to link the code of portions of this program with the OpenSSL
|
||||||
|
library.
|
||||||
|
You must obey the GNU General Public License in all respects for all of
|
||||||
|
the code used other than OpenSSL. If you modify file(s) with this
|
||||||
|
exception, you may extend this exception to your version of the file(s),
|
||||||
|
but you are not obligated to do so. If you do not wish to do so, delete
|
||||||
|
this exception statement from your version. If you delete this exception
|
||||||
|
statement from all source files in the program, then also delete it here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Ext.ns('Deluge.ux');
|
||||||
|
|
||||||
|
Deluge.ux.ScheduleSelector = Ext.extend(Ext.form.FieldSet, {
|
||||||
|
|
||||||
title: _('Schedule'),
|
title: _('Schedule'),
|
||||||
autoHeight: true
|
autoHeight: true,
|
||||||
}, config);
|
style: 'margin-bottom: 0px; padding-bottom: 0px;',
|
||||||
ScheduleSelectPanel.superclass.constructor.call(this, config);
|
border: false,
|
||||||
|
|
||||||
|
states: [
|
||||||
|
{
|
||||||
|
name: 'Normal',
|
||||||
|
backgroundColor: 'LightGreen',
|
||||||
|
borderColor: 'DarkGreen',
|
||||||
|
value: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Throttled',
|
||||||
|
backgroundColor: 'Yellow',
|
||||||
|
borderColor: 'Gold',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Paused',
|
||||||
|
backgroundColor: 'OrangeRed',
|
||||||
|
borderColor: 'FireBrick',
|
||||||
|
value: 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
daysOfWeek: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||||
|
|
||||||
|
initComponent: function() {
|
||||||
|
Deluge.ux.ScheduleSelector.superclass.initComponent.call(this);
|
||||||
|
|
||||||
|
// ExtJS' radiogroup implementation is very broken for styling.
|
||||||
|
/*this.stateBrush = this.add({
|
||||||
|
xtype: 'radiogroup',
|
||||||
|
fieldLabel: _('State Brush'),
|
||||||
|
name: 'current_state_brush',
|
||||||
|
submitValue: false,
|
||||||
|
items: [
|
||||||
|
{ boxLabel: 'Normal', name: 'current_state_brush', inputValue: 0 },
|
||||||
|
{ boxLabel: 'Throttled', name: 'current_state_brush', inputValue: 1, checked: true },
|
||||||
|
{ boxLabel: 'Paused', name: 'current_state_brush', inputValue: 2 },
|
||||||
|
]
|
||||||
|
});*/
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function(ct, position) {
|
onRender: function(ct, position) {
|
||||||
ScheduleSelectPanel.superclass.onRender.call(this, ct, position);
|
Deluge.ux.ScheduleSelector.superclass.onRender.call(this, ct, position);
|
||||||
|
|
||||||
var dom = this.body.dom;
|
var dom = this.body.dom;
|
||||||
var table = createEl(dom, 'table');
|
|
||||||
|
|
||||||
function createEl(parent, type) {
|
function createEl(parent, type) {
|
||||||
var el = document.createElement(type);
|
var el = document.createElement(type);
|
||||||
|
@ -19,30 +90,417 @@ ScheduleSelectPanel = Ext.extend(Ext.form.FieldSet, {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ext.each(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], function(day) {
|
// create state brushes
|
||||||
|
// tack a random number to the end to avoid clashes
|
||||||
|
this.stateBrushName = 'schedule-state-brush-' + Math.round(Math.random() * 10000);
|
||||||
|
|
||||||
|
var el1 = createEl(dom, 'div');
|
||||||
|
|
||||||
|
var el2 = createEl(el1, 'div');
|
||||||
|
this.stateBrush = el2;
|
||||||
|
el2.id = this.stateBrushName;
|
||||||
|
|
||||||
|
// for webkit
|
||||||
|
var floatAttr = 'float';
|
||||||
|
if (el2.style.float == undefined) {
|
||||||
|
// for firefox
|
||||||
|
if (el2.style.cssFloat != undefined) floatAttr = 'cssFloat';
|
||||||
|
// for IE
|
||||||
|
if (el2.style.styleFloat != undefined) floatAttr = 'styleFloat';
|
||||||
|
}
|
||||||
|
el2.style[floatAttr] = 'right';
|
||||||
|
|
||||||
|
for (var i=0; i < this.states.length; i++) {
|
||||||
|
var el3 = createEl(el2, 'input');
|
||||||
|
el3.type = 'radio';
|
||||||
|
el3.value = this.states[i].value;
|
||||||
|
el3.name = this.stateBrushName;
|
||||||
|
el3.id = this.stateBrushName + '-' + this.states[i].name;
|
||||||
|
|
||||||
|
// isn't the first one
|
||||||
|
if (i > 0) el3.style.marginLeft = '7px';
|
||||||
|
|
||||||
|
// assume the first is the default state, so make the 2nd one the default brush
|
||||||
|
if (i == 1) el3.checked = true;
|
||||||
|
|
||||||
|
var el4 = createEl(el2, 'label');
|
||||||
|
el4.appendChild(document.createTextNode(this.states[i].name));
|
||||||
|
el4.htmlFor = el3.id;
|
||||||
|
el4.style.backgroundColor = this.states[i].backgroundColor;
|
||||||
|
el4.style.borderBottom = '2px solid ' + this.states[i].borderColor;
|
||||||
|
el4.style.padding = '2px 3px';
|
||||||
|
el4.style.marginLeft = '3px';
|
||||||
|
}
|
||||||
|
|
||||||
|
el1.appendChild(document.createTextNode('Select a state brush:'));
|
||||||
|
|
||||||
|
el1.style.marginBottom = '10px';
|
||||||
|
|
||||||
|
// keep the radio buttons separate from the time bars
|
||||||
|
createEl(dom, 'div').style.clear = 'both';
|
||||||
|
|
||||||
|
var table = createEl(dom, 'table');
|
||||||
|
table.cellSpacing = 0;
|
||||||
|
|
||||||
|
// cache access to cells for easier access later
|
||||||
|
this.scheduleCells = { };
|
||||||
|
|
||||||
|
Ext.each(this.daysOfWeek, function(day) {
|
||||||
|
var cells = [ ];
|
||||||
var row = createEl(table, 'tr');
|
var row = createEl(table, 'tr');
|
||||||
var label = createEl(row, 'th');
|
var label = createEl(row, 'th');
|
||||||
label.setAttribute('style', 'font-weight: bold; padding-right: 5px;');
|
label.setAttribute('style', 'font-weight: bold; padding-right: 5px;');
|
||||||
label.innerHTML = day;
|
label.appendChild(document.createTextNode(day));
|
||||||
for (var hour = 0; hour < 24; hour++) {
|
for (var hour = 0; hour < 24; hour++) {
|
||||||
var cell = createEl(row, 'td');
|
var cell = createEl(row, 'td');
|
||||||
cell.setAttribute('style', 'border: 1px solid Green; width: 16px; height: 20px; background: LightGreen;');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
SchedulerPreferences = Ext.extend(Ext.Panel, {
|
// assume the first state is the default state
|
||||||
constructor: function(config) {
|
cell.currentValue = cell.oldValue = this.states[0].value;
|
||||||
config = Ext.apply({
|
cell.day = day;
|
||||||
border: false,
|
cell.hour = hour;
|
||||||
title: _('Scheduler')
|
|
||||||
}, config);
|
cell.width = '16px';
|
||||||
SchedulerPreferences.superclass.constructor.call(this, config);
|
cell.height = '20px';
|
||||||
|
|
||||||
|
cell.style.border = '1px solid #999999';
|
||||||
|
// don't repeat borders in between cells
|
||||||
|
if (hour != 23) // not the last cell
|
||||||
|
cell.style.borderRight = 'none';
|
||||||
|
|
||||||
|
this.updateCell(cell);
|
||||||
|
|
||||||
|
cells.push(cell);
|
||||||
|
|
||||||
|
cell = Ext.get(cell);
|
||||||
|
cell.on('click', this.onCellClick, this);
|
||||||
|
cell.on('mouseover', this.onCellMouseOver, this);
|
||||||
|
cell.on('mouseout', this.onCellMouseOut, this);
|
||||||
|
cell.on('mousedown', this.onCellMouseDown, this);
|
||||||
|
cell.on('mouseup', this.onCellMouseUp, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert gap row to provide visual separation
|
||||||
|
row = createEl(table, 'tr');
|
||||||
|
// blank cell to create gap
|
||||||
|
createEl(row, 'td').height = '3px';
|
||||||
|
|
||||||
|
this.scheduleCells[day] = cells;
|
||||||
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateCell: function(cell) {
|
||||||
|
// sanity check
|
||||||
|
if (cell.currentValue == undefined) return;
|
||||||
|
|
||||||
|
for (var i in this.states) {
|
||||||
|
var curState = this.states[i];
|
||||||
|
if (curState.value == cell.currentValue) {
|
||||||
|
cell.style.background = curState.backgroundColor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurrentBrushValue: function() {
|
||||||
|
var v = null;
|
||||||
|
var brushes = Ext.get(this.body.dom).findParent('form').elements[this.stateBrushName];
|
||||||
|
Ext.each(brushes, function(b) {
|
||||||
|
if (b.checked)
|
||||||
|
v = b.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
return v;
|
||||||
|
},
|
||||||
|
|
||||||
|
onCellClick: function(event, cell) {
|
||||||
|
cell.oldValue = cell.currentValue;
|
||||||
|
|
||||||
|
this.dragAnchor = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
onCellMouseDown: function(event, cell) {
|
||||||
|
this.dragAnchor = cell;
|
||||||
|
},
|
||||||
|
|
||||||
|
onCellMouseUp: function(event, cell) {
|
||||||
|
// if we're dragging...
|
||||||
|
if (this.dragAnchor) {
|
||||||
|
// set all those between here and the anchor to the new values
|
||||||
|
if (cell.hour > this.dragAnchor.hour)
|
||||||
|
this.confirmCells(cell.day, this.dragAnchor.hour, cell.hour);
|
||||||
|
else if (cell.hour < this.dragAnchor.hour)
|
||||||
|
this.confirmCells(cell.day, cell.hour, this.dragAnchor.hour);
|
||||||
|
else
|
||||||
|
this.confirmCells(cell.day, cell.hour, cell.hour);
|
||||||
|
|
||||||
|
this.hideCellLeftTooltip();
|
||||||
|
this.hideCellRightTooltip();
|
||||||
|
this.dragAnchor = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onCellMouseOver: function(event, cell) {
|
||||||
|
// LEFT TOOL TIP
|
||||||
|
// if it isn't showing and we're dragging, show it.
|
||||||
|
// otherwise if dragging, leave it alone unless we're dragging to the left.
|
||||||
|
// if we're not dragging, show it.
|
||||||
|
var leftTooltipCell = null;
|
||||||
|
if (!this.dragAnchor)
|
||||||
|
leftTooltipCell = cell;
|
||||||
|
else if ((this.dragAnchor && this.isCellLeftTooltipHidden()) ||
|
||||||
|
(this.dragAnchor && this.dragAnchor.hour > cell.hour))
|
||||||
|
leftTooltipCell = this.dragAnchor;
|
||||||
|
|
||||||
|
if (leftTooltipCell) {
|
||||||
|
var hour = leftTooltipCell.hour;
|
||||||
|
var pm = false;
|
||||||
|
|
||||||
|
// convert to 12-hour time
|
||||||
|
if (hour >= 12) {
|
||||||
|
pm = true;
|
||||||
|
if (hour > 12) hour -= 12;
|
||||||
|
}
|
||||||
|
// change 0 hour to 12am
|
||||||
|
else if (hour == 0) {
|
||||||
|
hour = 12;
|
||||||
|
}
|
||||||
|
this.showCellLeftTooltip(hour + ' ' + (pm ? 'pm' : 'am'), leftTooltipCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RIGHT TOOL TIP
|
||||||
|
var rightTooltipCell = null;
|
||||||
|
if (this.dragAnchor) {
|
||||||
|
if (this.dragAnchor.hour == cell.hour)
|
||||||
|
this.hideCellRightTooltip();
|
||||||
|
else if (this.dragAnchor.hour > cell.hour && this.isCellRightTooltipHidden())
|
||||||
|
rightTooltipCell = this.dragAnchor;
|
||||||
|
else // cell.hour > this.dragAnchor.hour
|
||||||
|
rightTooltipCell = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightTooltipCell) {
|
||||||
|
var hour = rightTooltipCell.hour;
|
||||||
|
var pm = false;
|
||||||
|
|
||||||
|
// convert to 12-hour time
|
||||||
|
if (hour >= 12) {
|
||||||
|
pm = true;
|
||||||
|
if (hour > 12) hour -= 12;
|
||||||
|
}
|
||||||
|
// change 0 hour to 12am
|
||||||
|
else if (hour == 0) {
|
||||||
|
hour = 12;
|
||||||
|
}
|
||||||
|
this.showCellRightTooltip(hour + ' ' + (pm ? 'pm' : 'am'), rightTooltipCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// preview colour change and
|
||||||
|
// revert state for all those on the outer side of the drag if dragging
|
||||||
|
if (this.dragAnchor) {
|
||||||
|
if (cell.day != this.dragAnchor.day) {
|
||||||
|
// dragged into another day. Abort! Abort!
|
||||||
|
Ext.each(this.daysOfWeek, function(day) {
|
||||||
|
this.revertCells(day, 0, 23);
|
||||||
|
}, this);
|
||||||
|
this.dragAnchor = null;
|
||||||
|
this.hideCellLeftTooltip();
|
||||||
|
this.hideCellRightTooltip();
|
||||||
|
}
|
||||||
|
else if (cell.hour > this.dragAnchor.hour) {
|
||||||
|
// dragging right
|
||||||
|
this.revertCells(cell.day, cell.hour+1, 23);
|
||||||
|
this.previewCells(cell.day, this.dragAnchor.hour, cell.hour);
|
||||||
|
}
|
||||||
|
else if (cell.hour < this.dragAnchor.hour) {
|
||||||
|
// dragging left
|
||||||
|
this.revertCells(cell.day, 0, cell.hour-1);
|
||||||
|
this.previewCells(cell.day, cell.hour, this.dragAnchor.hour);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// back to anchor cell
|
||||||
|
// don't know if it is from right or left, so revert all except this
|
||||||
|
this.revertCells(cell.day, cell.hour+1, 23);
|
||||||
|
this.revertCells(cell.day, 0, cell.hour-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// not dragging, just preview this cell
|
||||||
|
this.previewCells(cell.day, cell.hour, cell.hour);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onCellMouseOut: function(event, cell) {
|
||||||
|
if (!this.dragAnchor)
|
||||||
|
this.hideCellLeftTooltip();
|
||||||
|
|
||||||
|
// revert state. If new state has been set, old and new will be equal.
|
||||||
|
// if dragging, this will be handled by the next mouse over
|
||||||
|
if (this.dragAnchor == null && cell.oldValue != cell.currentValue) {
|
||||||
|
this.revertCells(cell.day, cell.hour, cell.hour);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
previewCells: function(day, fromHour, toHour) {
|
||||||
|
var cells = this.scheduleCells[day];
|
||||||
|
var curBrushValue = this.getCurrentBrushValue();
|
||||||
|
|
||||||
|
if (toHour > cells.length) toHour = cells.length;
|
||||||
|
|
||||||
|
for (var i=fromHour; i <= toHour; i++) {
|
||||||
|
if (cells[i].currentValue != curBrushValue) {
|
||||||
|
cells[i].oldValue = cells[i].currentValue;
|
||||||
|
cells[i].currentValue = curBrushValue;
|
||||||
|
this.updateCell(cells[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
revertCells: function(day, fromHour, toHour) {
|
||||||
|
var cells = this.scheduleCells[day];
|
||||||
|
|
||||||
|
if (toHour > cells.length) toHour = cells.length;
|
||||||
|
|
||||||
|
for (var i=fromHour; i <= toHour; i++) {
|
||||||
|
cells[i].currentValue = cells[i].oldValue;
|
||||||
|
this.updateCell(cells[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
confirmCells: function(day, fromHour, toHour) {
|
||||||
|
var cells = this.scheduleCells[day];
|
||||||
|
|
||||||
|
if (toHour > cells.length) toHour = cells.length;
|
||||||
|
|
||||||
|
for (var i=fromHour; i <= toHour; i++) {
|
||||||
|
if (cells[i].currentValue != cells[i].oldValue) {
|
||||||
|
cells[i].oldValue = cells[i].currentValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
showCellLeftTooltip: function(text, cell) {
|
||||||
|
var tooltip = this.cellLeftTooltip;
|
||||||
|
|
||||||
|
if (!tooltip) {
|
||||||
|
// no cached left tooltip exists, create one
|
||||||
|
tooltip = document.createElement('div');
|
||||||
|
this.cellLeftTooltip = tooltip;
|
||||||
|
this.body.dom.appendChild(tooltip);
|
||||||
|
tooltip.style.position = 'absolute';
|
||||||
|
tooltip.style.backgroundColor = '#F2F2F2';
|
||||||
|
tooltip.style.border = '1px solid #333333';
|
||||||
|
tooltip.style.padding = '1px 3px';
|
||||||
|
tooltip.style.opacity = 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all existing children
|
||||||
|
while (tooltip.childNodes.length > 0) {
|
||||||
|
tooltip.removeChild(tooltip.firstChild);
|
||||||
|
}
|
||||||
|
// add the requested text
|
||||||
|
tooltip.appendChild(document.createTextNode(text));
|
||||||
|
|
||||||
|
// place the tooltip
|
||||||
|
Ext.get(tooltip).alignTo(cell, 'br-tr');
|
||||||
|
|
||||||
|
// make it visible
|
||||||
|
tooltip.style.visibility = 'visible';
|
||||||
|
},
|
||||||
|
|
||||||
|
hideCellLeftTooltip: function() {
|
||||||
|
if (this.cellLeftTooltip) {
|
||||||
|
this.cellLeftTooltip.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isCellLeftTooltipHidden: function() {
|
||||||
|
if (this.cellLeftTooltip)
|
||||||
|
return this.cellLeftTooltip.style.visibility == 'hidden';
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
showCellRightTooltip: function(text, cell) {
|
||||||
|
var tooltip = this.cellRightTooltip;
|
||||||
|
|
||||||
|
if (!tooltip) {
|
||||||
|
// no cached left tooltip exists, create one
|
||||||
|
tooltip = document.createElement('div');
|
||||||
|
this.cellRightTooltip = tooltip;
|
||||||
|
this.body.dom.appendChild(tooltip);
|
||||||
|
tooltip.style.position = 'absolute';
|
||||||
|
tooltip.style.backgroundColor = '#F2F2F2';
|
||||||
|
tooltip.style.border = '1px solid #333333';
|
||||||
|
tooltip.style.padding = '1px 3px';
|
||||||
|
tooltip.style.opacity = 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all existing children
|
||||||
|
while (tooltip.childNodes.length > 0) {
|
||||||
|
tooltip.removeChild(tooltip.firstChild);
|
||||||
|
}
|
||||||
|
// add the requested text
|
||||||
|
tooltip.appendChild(document.createTextNode(text));
|
||||||
|
|
||||||
|
// place the tooltip
|
||||||
|
Ext.get(tooltip).alignTo(cell, 'bl-tl');
|
||||||
|
|
||||||
|
// make it visible
|
||||||
|
tooltip.style.visibility = 'visible';
|
||||||
|
},
|
||||||
|
|
||||||
|
hideCellRightTooltip: function() {
|
||||||
|
if (this.cellRightTooltip) {
|
||||||
|
this.cellRightTooltip.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isCellRightTooltipHidden: function() {
|
||||||
|
if (this.cellRightTooltip)
|
||||||
|
return this.cellRightTooltip.style.visibility == 'hidden';
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
getConfig: function() {
|
||||||
|
var config = [ ];
|
||||||
|
|
||||||
|
for (var i=0; i < 24; i++) {
|
||||||
|
var hourConfig = [ 0, 0, 0, 0, 0, 0, 0 ];
|
||||||
|
|
||||||
|
for (var j=0; j < this.daysOfWeek.length; j++) {
|
||||||
|
hourConfig[j] = parseInt(this.scheduleCells[this.daysOfWeek[j]][i].currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.push(hourConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
|
||||||
|
setConfig: function(config) {
|
||||||
|
for (var i=0; i < 24; i++) {
|
||||||
|
var hourConfig = config[i];
|
||||||
|
|
||||||
|
for (var j=0; j < this.daysOfWeek.length; j++) {
|
||||||
|
var cell = this.scheduleCells[this.daysOfWeek[j]][i];
|
||||||
|
cell.currentValue = cell.oldValue = hourConfig[j];
|
||||||
|
this.updateCell(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ext.ns('Deluge.ux.preferences');
|
||||||
|
|
||||||
|
Deluge.ux.preferences.SchedulerPage = Ext.extend(Ext.Panel, {
|
||||||
|
|
||||||
|
border: false,
|
||||||
|
title: _('Scheduler'),
|
||||||
|
layout: 'fit',
|
||||||
|
|
||||||
initComponent: function() {
|
initComponent: function() {
|
||||||
SchedulerPreferences.superclass.initComponent.call(this);
|
Deluge.ux.preferences.SchedulerPage.superclass.initComponent.call(this);
|
||||||
|
|
||||||
this.form = this.add({
|
this.form = this.add({
|
||||||
xtype: 'form',
|
xtype: 'form',
|
||||||
|
@ -51,56 +509,116 @@ SchedulerPreferences = Ext.extend(Ext.Panel, {
|
||||||
autoHeight: true
|
autoHeight: true
|
||||||
});
|
});
|
||||||
|
|
||||||
this.schedule = this.form.add(new ScheduleSelectPanel());
|
this.schedule = this.form.add(new Deluge.ux.ScheduleSelector());
|
||||||
|
|
||||||
this.slowSettings = this.form.add({
|
this.slowSettings = this.form.add({
|
||||||
xtype: 'fieldset',
|
xtype: 'fieldset',
|
||||||
title: _('Slow Settings'),
|
border: false,
|
||||||
|
title: _('Throttled Settings'),
|
||||||
autoHeight: true,
|
autoHeight: true,
|
||||||
defaultType: 'uxspinner'
|
defaultType: 'spinnerfield',
|
||||||
|
defaults: {
|
||||||
|
minValue: -1,
|
||||||
|
maxValue: 99999
|
||||||
|
},
|
||||||
|
style: 'margin-top: 5px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||||
|
labelWidth: 200
|
||||||
});
|
});
|
||||||
|
|
||||||
this.downloadLimit = this.slowSettings.add({
|
this.downloadLimit = this.slowSettings.add({
|
||||||
fieldLabel: _('Download Limit'),
|
fieldLabel: _('Maximum Download Speed (KiB/s)'),
|
||||||
name: 'download_limit'
|
name: 'download_limit',
|
||||||
|
width: 80,
|
||||||
|
value: -1,
|
||||||
|
decimalPrecision: 0
|
||||||
});
|
});
|
||||||
this.uploadLimit = this.slowSettings.add({
|
this.uploadLimit = this.slowSettings.add({
|
||||||
fieldLabel: _('Upload Limit'),
|
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
|
||||||
name: 'upload_limit'
|
name: 'upload_limit',
|
||||||
|
width: 80,
|
||||||
|
value: -1,
|
||||||
|
decimalPrecision: 0
|
||||||
});
|
});
|
||||||
this.activeTorrents = this.slowSettings.add({
|
this.activeTorrents = this.slowSettings.add({
|
||||||
fieldLabel: _('Active Torrents'),
|
fieldLabel: _('Active Torrents'),
|
||||||
name: 'active_torrents'
|
name: 'active_torrents',
|
||||||
|
width: 80,
|
||||||
|
value: -1,
|
||||||
|
decimalPrecision: 0
|
||||||
});
|
});
|
||||||
|
this.activeDownloading = this.slowSettings.add({
|
||||||
|
fieldLabel: _('Active Downloading'),
|
||||||
|
name: 'active_downloading',
|
||||||
|
width: 80,
|
||||||
|
value: -1,
|
||||||
|
decimalPrecision: 0
|
||||||
|
});
|
||||||
|
this.activeSeeding = this.slowSettings.add({
|
||||||
|
fieldLabel: _('Active Seeding'),
|
||||||
|
name: 'active_seeding',
|
||||||
|
width: 80,
|
||||||
|
value: -1,
|
||||||
|
decimalPrecision: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
deluge.preferences.on('show', this.updateConfig, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function(ct, position) {
|
onRender: function(ct, position) {
|
||||||
SchedulerPreferences.superclass.onRender.call(this, ct, position);
|
Deluge.ux.preferences.SchedulerPage.superclass.onRender.call(this, ct, position);
|
||||||
this.form.layout = new Ext.layout.FormLayout();
|
this.form.layout = new Ext.layout.FormLayout();
|
||||||
this.form.layout.setContainer(this);
|
this.form.layout.setContainer(this);
|
||||||
this.form.doLayout();
|
this.form.doLayout();
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow: function() {
|
onApply: function() {
|
||||||
SchedulerPreferences.superclass.onShow.call(this);
|
// build settings object
|
||||||
|
var config = { }
|
||||||
|
|
||||||
|
config['button_state'] = this.schedule.getConfig();
|
||||||
|
config['low_down'] = this.downloadLimit.getValue();
|
||||||
|
config['low_up'] = this.uploadLimit.getValue();
|
||||||
|
config['low_active'] = this.activeTorrents.getValue();
|
||||||
|
config['low_active_down'] = this.activeDownloading.getValue();
|
||||||
|
config['low_active_up'] = this.activeSeeding.getValue();
|
||||||
|
|
||||||
|
deluge.client.scheduler.set_config(config);
|
||||||
|
},
|
||||||
|
|
||||||
|
onOk: function() {
|
||||||
|
this.onApply();
|
||||||
|
},
|
||||||
|
|
||||||
|
afterRender: function() {
|
||||||
|
Deluge.ux.preferences.SchedulerPage.superclass.afterRender.call(this);
|
||||||
|
this.updateConfig();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateConfig: function() {
|
||||||
|
deluge.client.scheduler.get_config({
|
||||||
|
success: function(config) {
|
||||||
|
this.schedule.setConfig(config['button_state']);
|
||||||
|
this.downloadLimit.setValue(config['low_down']);
|
||||||
|
this.uploadLimit.setValue(config['low_up']);
|
||||||
|
this.activeTorrents.setValue(config['low_active']);
|
||||||
|
this.activeDownloading.setValue(config['low_active_down']);
|
||||||
|
this.activeSeeding.setValue(config['low_active_up']);
|
||||||
|
},
|
||||||
|
scope: this
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
SchedulerPlugin = Ext.extend(Deluge.Plugin, {
|
Deluge.plugins.SchedulerPlugin = Ext.extend(Deluge.Plugin, {
|
||||||
constructor: function(config) {
|
|
||||||
config = Ext.apply({
|
name: 'Scheduler',
|
||||||
name: "Scheduler"
|
|
||||||
}, config);
|
|
||||||
SchedulerPlugin.superclass.constructor.call(this, config);
|
|
||||||
},
|
|
||||||
|
|
||||||
onDisable: function() {
|
onDisable: function() {
|
||||||
Deluge.Preferences.removePage(this.prefsPage);
|
deluge.preferences.removePage(this.prefsPage);
|
||||||
},
|
},
|
||||||
|
|
||||||
onEnable: function() {
|
onEnable: function() {
|
||||||
this.prefsPage = new SchedulerPreferences();
|
this.prefsPage = deluge.preferences.addPage(new Deluge.ux.preferences.SchedulerPage());
|
||||||
this.prefsPage = Deluge.Preferences.addPage(this.prefsPage);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
new SchedulerPlugin();
|
Deluge.registerPlugin('Scheduler', Deluge.plugins.SchedulerPlugin);
|
||||||
|
|
|
@ -48,3 +48,4 @@ log = logging.getLogger(__name__)
|
||||||
class WebUI(WebPluginBase):
|
class WebUI(WebPluginBase):
|
||||||
|
|
||||||
scripts = [get_resource("scheduler.js")]
|
scripts = [get_resource("scheduler.js")]
|
||||||
|
debug_scripts = scripts
|
||||||
|
|
Loading…
Reference in New Issue