spaces FTW

This commit is contained in:
Damien Churchill 2011-06-01 20:29:38 +01:00
commit bb981127db
70 changed files with 7268 additions and 7244 deletions

View file

@ -37,86 +37,86 @@ Ext.ns('Deluge');
*/
Deluge.AddConnectionWindow = Ext.extend(Ext.Window, {
title: _('Add Connection'),
iconCls: 'x-deluge-add-window-icon',
title: _('Add Connection'),
iconCls: 'x-deluge-add-window-icon',
layout: 'fit',
width: 300,
height: 195,
layout: 'fit',
width: 300,
height: 195,
bodyStyle: 'padding: 10px 5px;',
closeAction: 'hide',
bodyStyle: 'padding: 10px 5px;',
closeAction: 'hide',
initComponent: function() {
Deluge.AddConnectionWindow.superclass.initComponent.call(this);
initComponent: function() {
Deluge.AddConnectionWindow.superclass.initComponent.call(this);
this.addEvents('hostadded');
this.addButton(_('Close'), this.hide, this);
this.addButton(_('Add'), this.onAddClick, this);
this.on('hide', this.onHide, this);
this.form = this.add({
xtype: 'form',
defaultType: 'textfield',
baseCls: 'x-plain',
labelWidth: 60,
items: [{
fieldLabel: _('Host'),
name: 'host',
anchor: '75%',
value: ''
}, {
xtype: 'spinnerfield',
fieldLabel: _('Port'),
name: 'port',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 65535
},
value: '58846',
anchor: '40%'
}, {
fieldLabel: _('Username'),
name: 'username',
anchor: '75%',
value: ''
}, {
fieldLabel: _('Password'),
anchor: '75%',
name: 'password',
inputType: 'password',
value: ''
}]
});
},
this.addEvents('hostadded');
this.addButton(_('Close'), this.hide, this);
this.addButton(_('Add'), this.onAddClick, this);
this.on('hide', this.onHide, this);
this.form = this.add({
xtype: 'form',
defaultType: 'textfield',
baseCls: 'x-plain',
labelWidth: 60,
items: [{
fieldLabel: _('Host'),
name: 'host',
anchor: '75%',
value: ''
}, {
xtype: 'spinnerfield',
fieldLabel: _('Port'),
name: 'port',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 65535
},
value: '58846',
anchor: '40%'
}, {
fieldLabel: _('Username'),
name: 'username',
anchor: '75%',
value: ''
}, {
fieldLabel: _('Password'),
anchor: '75%',
name: 'password',
inputType: 'password',
value: ''
}]
});
},
onAddClick: function() {
var values = this.form.getForm().getValues();
deluge.client.web.add_host(values.host, values.port, values.username, values.password, {
success: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: "Unable to add host: " + result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
this.fireEvent('hostadded');
}
this.hide();
},
scope: this
});
},
onAddClick: function() {
var values = this.form.getForm().getValues();
deluge.client.web.add_host(values.host, values.port, values.username, values.password, {
success: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: "Unable to add host: " + result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
this.fireEvent('hostadded');
}
this.hide();
},
scope: this
});
},
onHide: function() {
this.form.getForm().reset();
}
onHide: function() {
this.form.getForm().reset();
}
});

View file

@ -36,57 +36,57 @@ Ext.ns('Deluge');
* @extends Ext.Window
*/
Deluge.AddTrackerWindow = Ext.extend(Ext.Window, {
title: _('Add Tracker'),
layout: 'fit',
width: 375,
height: 150,
plain: true,
closable: true,
resizable: false,
title: _('Add Tracker'),
layout: 'fit',
width: 375,
height: 150,
plain: true,
closable: true,
resizable: false,
bodyStyle: 'padding: 5px',
buttonAlign: 'right',
closeAction: 'hide',
iconCls: 'x-deluge-edit-trackers',
bodyStyle: 'padding: 5px',
buttonAlign: 'right',
closeAction: 'hide',
iconCls: 'x-deluge-edit-trackers',
initComponent: function() {
Deluge.AddTrackerWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Add'), this.onAddClick, this);
this.addEvents('add');
this.form = this.add({
xtype: 'form',
defaultType: 'textarea',
baseCls: 'x-plain',
labelWidth: 55,
items: [{
fieldLabel: _('Trackers'),
name: 'trackers',
anchor: '100%'
}]
})
},
initComponent: function() {
Deluge.AddTrackerWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Add'), this.onAddClick, this);
this.addEvents('add');
this.form = this.add({
xtype: 'form',
defaultType: 'textarea',
baseCls: 'x-plain',
labelWidth: 55,
items: [{
fieldLabel: _('Trackers'),
name: 'trackers',
anchor: '100%'
}]
})
},
onAddClick: function() {
var trackers = this.form.getForm().findField('trackers').getValue();
trackers = trackers.split('\n');
var cleaned = [];
Ext.each(trackers, function(tracker) {
if (Ext.form.VTypes.url(tracker)) {
cleaned.push(tracker);
}
}, this);
this.fireEvent('add', cleaned);
this.hide();
this.form.getForm().findField('trackers').setValue('');
},
onAddClick: function() {
var trackers = this.form.getForm().findField('trackers').getValue();
trackers = trackers.split('\n');
var cleaned = [];
Ext.each(trackers, function(tracker) {
if (Ext.form.VTypes.url(tracker)) {
cleaned.push(tracker);
}
}, this);
this.fireEvent('add', cleaned);
this.hide();
this.form.getForm().findField('trackers').setValue('');
},
onCancelClick: function() {
this.form.getForm().findField('trackers').setValue('');
this.hide();
}
onCancelClick: function() {
this.form.getForm().findField('trackers').setValue('');
this.hide();
}
});

View file

@ -39,157 +39,157 @@ Ext.namespace('Ext.ux.util');
*/
Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
_components: [],
_methods: [],
_requests: {},
_url: null,
_optionKeys: ['scope', 'success', 'failure'],
constructor: function(config) {
Ext.ux.util.RpcClient.superclass.constructor.call(this, config);
this._url = config.url || null;
this._id = 0;
this.addEvents(
// raw events
/**
* @event connected
* Fires when the client has retrieved the list of methods from the server.
* @param {Ext.ux.util.RpcClient} this
*/
'connected',
'error'
);
this.reloadMethods();
},
reloadMethods: function() {
Ext.each(this._components, function(component) {
delete this[component];
}, this);
this._execute('system.listMethods', {
success: this._setMethods,
scope: this
});
},
_components: [],
_methods: [],
_requests: {},
_url: null,
_optionKeys: ['scope', 'success', 'failure'],
constructor: function(config) {
Ext.ux.util.RpcClient.superclass.constructor.call(this, config);
this._url = config.url || null;
this._id = 0;
this.addEvents(
// raw events
/**
* @event connected
* Fires when the client has retrieved the list of methods from the server.
* @param {Ext.ux.util.RpcClient} this
*/
'connected',
'error'
);
this.reloadMethods();
},
reloadMethods: function() {
Ext.each(this._components, function(component) {
delete this[component];
}, this);
this._execute('system.listMethods', {
success: this._setMethods,
scope: this
});
},
_execute: function(method, options) {
options = options || {};
options.params = options.params || [];
options.id = this._id;
var request = Ext.encode({
method: method,
params: options.params,
id: options.id
});
this._id++;
return Ext.Ajax.request({
url: this._url,
method: 'POST',
success: this._onSuccess,
failure: this._onFailure,
scope: this,
jsonData: request,
options: options
});
},
_onFailure: function(response, requestOptions) {
var options = requestOptions.options;
errorObj = {
id: options.id,
result: null,
error: {
msg: 'HTTP: ' + response.status + ' ' + response.statusText,
code: 255
}
}
this.fireEvent('error', errorObj, response, requestOptions)
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, errorObj, response, requestOptions);
} else {
options.failure(errorObj, response, requestOptions);
}
},
_onSuccess: function(response, requestOptions) {
var responseObj = Ext.decode(response.responseText);
var options = requestOptions.options;
if (responseObj.error) {
this.fireEvent('error', responseObj, response, requestOptions);
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, responseObj, response, requestOptions);
} else {
options.failure(responseObj, response, requestOptions);
}
} else {
if (Ext.type(options.success) != 'function') return;
if (options.scope) {
options.success.call(options.scope, responseObj.result, responseObj, response, requestOptions);
} else {
options.success(responseObj.result, responseObj, response, requestOptions);
}
}
},
_parseArgs: function(args) {
var params = [];
Ext.each(args, function(arg) {
params.push(arg);
});
var options = params[params.length - 1];
if (Ext.type(options) == 'object') {
var keys = Ext.keys(options), isOption = false;
Ext.each(this._optionKeys, function(key) {
if (keys.indexOf(key) > -1) isOption = true;
});
if (isOption) {
params.remove(options)
} else {
options = {}
}
} else {
options = {}
}
options.params = params;
return options;
},
_execute: function(method, options) {
options = options || {};
options.params = options.params || [];
options.id = this._id;
var request = Ext.encode({
method: method,
params: options.params,
id: options.id
});
this._id++;
return Ext.Ajax.request({
url: this._url,
method: 'POST',
success: this._onSuccess,
failure: this._onFailure,
scope: this,
jsonData: request,
options: options
});
},
_onFailure: function(response, requestOptions) {
var options = requestOptions.options;
errorObj = {
id: options.id,
result: null,
error: {
msg: 'HTTP: ' + response.status + ' ' + response.statusText,
code: 255
}
}
this.fireEvent('error', errorObj, response, requestOptions)
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, errorObj, response, requestOptions);
} else {
options.failure(errorObj, response, requestOptions);
}
},
_onSuccess: function(response, requestOptions) {
var responseObj = Ext.decode(response.responseText);
var options = requestOptions.options;
if (responseObj.error) {
this.fireEvent('error', responseObj, response, requestOptions);
if (Ext.type(options.failure) != 'function') return;
if (options.scope) {
options.failure.call(options.scope, responseObj, response, requestOptions);
} else {
options.failure(responseObj, response, requestOptions);
}
} else {
if (Ext.type(options.success) != 'function') return;
if (options.scope) {
options.success.call(options.scope, responseObj.result, responseObj, response, requestOptions);
} else {
options.success(responseObj.result, responseObj, response, requestOptions);
}
}
},
_parseArgs: function(args) {
var params = [];
Ext.each(args, function(arg) {
params.push(arg);
});
var options = params[params.length - 1];
if (Ext.type(options) == 'object') {
var keys = Ext.keys(options), isOption = false;
Ext.each(this._optionKeys, function(key) {
if (keys.indexOf(key) > -1) isOption = true;
});
if (isOption) {
params.remove(options)
} else {
options = {}
}
} else {
options = {}
}
options.params = params;
return options;
},
_setMethods: function(methods) {
var components = {}, self = this;
Ext.each(methods, function(method) {
var parts = method.split('.');
var component = components[parts[0]] || {};
var fn = function() {
var options = self._parseArgs(arguments);
return self._execute(method, options);
}
component[parts[1]] = fn;
components[parts[0]] = component;
});
for (var name in components) {
self[name] = components[name];
}
this._components = Ext.keys(components);
this.fireEvent('connected', this);
}
_setMethods: function(methods) {
var components = {}, self = this;
Ext.each(methods, function(method) {
var parts = method.split('.');
var component = components[parts[0]] || {};
var fn = function() {
var options = self._parseArgs(arguments);
return self._execute(method, options);
}
component[parts[1]] = fn;
components[parts[0]] = component;
});
for (var name in components) {
self[name] = components[name];
}
this._components = Ext.keys(components);
this.fireEvent('connected', this);
}
});

View file

@ -32,345 +32,345 @@
Deluge.ConnectionManager = Ext.extend(Ext.Window, {
layout: 'fit',
width: 300,
height: 220,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
title: _('Connection Manager'),
iconCls: 'x-deluge-connect-window-icon',
layout: 'fit',
width: 300,
height: 220,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
title: _('Connection Manager'),
iconCls: 'x-deluge-connect-window-icon',
initComponent: function() {
Deluge.ConnectionManager.superclass.initComponent.call(this);
this.on('hide', this.onHide, this);
this.on('show', this.onShow, this);
initComponent: function() {
Deluge.ConnectionManager.superclass.initComponent.call(this);
this.on('hide', this.onHide, this);
this.on('show', this.onShow, this);
deluge.events.on('login', this.onLogin, this);
deluge.events.on('logout', this.onLogout, this);
deluge.events.on('login', this.onLogin, this);
deluge.events.on('logout', this.onLogout, this);
this.addButton(_('Close'), this.onClose, this);
this.addButton(_('Connect'), this.onConnect, this);
this.addButton(_('Close'), this.onClose, this);
this.addButton(_('Connect'), this.onConnect, this);
this.list = new Ext.list.ListView({
store: new Ext.data.ArrayStore({
fields: [
{name: 'status', mapping: 3},
{name: 'host', mapping: 1},
{name: 'port', mapping: 2},
{name: 'version', mapping: 4}
],
id: 0
}),
columns: [{
header: _('Status'),
width: .24,
sortable: true,
dataIndex: 'status'
}, {
id:'host',
header: _('Host'),
width: .51,
sortable: true,
tpl: '{host}:{port}',
dataIndex: 'host'
}, {
header: _('Version'),
width: .25,
sortable: true,
tpl: '<tpl if="version">{version}</tpl>',
dataIndex: 'version'
}],
singleSelect: true,
listeners: {
'selectionchange': {fn: this.onSelectionChanged, scope: this}
}
});
this.list = new Ext.list.ListView({
store: new Ext.data.ArrayStore({
fields: [
{name: 'status', mapping: 3},
{name: 'host', mapping: 1},
{name: 'port', mapping: 2},
{name: 'version', mapping: 4}
],
id: 0
}),
columns: [{
header: _('Status'),
width: .24,
sortable: true,
dataIndex: 'status'
}, {
id:'host',
header: _('Host'),
width: .51,
sortable: true,
tpl: '{host}:{port}',
dataIndex: 'host'
}, {
header: _('Version'),
width: .25,
sortable: true,
tpl: '<tpl if="version">{version}</tpl>',
dataIndex: 'version'
}],
singleSelect: true,
listeners: {
'selectionchange': {fn: this.onSelectionChanged, scope: this}
}
});
this.panel = this.add({
autoScroll: true,
items: [this.list],
bbar: new Ext.Toolbar({
buttons: [
{
id: 'cm-add',
cls: 'x-btn-text-icon',
text: _('Add'),
iconCls: 'icon-add',
handler: this.onAddClick,
scope: this
}, {
id: 'cm-remove',
cls: 'x-btn-text-icon',
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onRemoveClick,
disabled: true,
scope: this
}, '->', {
id: 'cm-stop',
cls: 'x-btn-text-icon',
text: _('Stop Daemon'),
iconCls: 'icon-error',
handler: this.onStopClick,
disabled: true,
scope: this
}
]
})
});
this.update = this.update.createDelegate(this);
},
this.panel = this.add({
autoScroll: true,
items: [this.list],
bbar: new Ext.Toolbar({
buttons: [
{
id: 'cm-add',
cls: 'x-btn-text-icon',
text: _('Add'),
iconCls: 'icon-add',
handler: this.onAddClick,
scope: this
}, {
id: 'cm-remove',
cls: 'x-btn-text-icon',
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onRemoveClick,
disabled: true,
scope: this
}, '->', {
id: 'cm-stop',
cls: 'x-btn-text-icon',
text: _('Stop Daemon'),
iconCls: 'icon-error',
handler: this.onStopClick,
disabled: true,
scope: this
}
]
})
});
this.update = this.update.createDelegate(this);
},
/**
* Check to see if the the web interface is currently connected
* to a Deluge Daemon and show the Connection Manager if not.
*/
checkConnected: function() {
deluge.client.web.connected({
success: function(connected) {
if (connected) {
deluge.events.fire('connect');
} else {
this.show();
}
},
scope: this
});
},
/**
* Check to see if the the web interface is currently connected
* to a Deluge Daemon and show the Connection Manager if not.
*/
checkConnected: function() {
deluge.client.web.connected({
success: function(connected) {
if (connected) {
deluge.events.fire('connect');
} else {
this.show();
}
},
scope: this
});
},
disconnect: function(show) {
deluge.events.fire('disconnect');
if (show) {
if (this.isVisible()) return;
this.show();
}
},
disconnect: function(show) {
deluge.events.fire('disconnect');
if (show) {
if (this.isVisible()) return;
this.show();
}
},
loadHosts: function() {
deluge.client.web.get_hosts({
success: this.onGetHosts,
scope: this
});
},
loadHosts: function() {
deluge.client.web.get_hosts({
success: this.onGetHosts,
scope: this
});
},
update: function() {
this.list.getStore().each(function(r) {
deluge.client.web.get_host_status(r.id, {
success: this.onGetHostStatus,
scope: this
});
}, this);
},
update: function() {
this.list.getStore().each(function(r) {
deluge.client.web.get_host_status(r.id, {
success: this.onGetHostStatus,
scope: this
});
}, this);
},
/**
* Updates the buttons in the Connection Manager UI according to the
* passed in records host state.
* @param {Ext.data.Record} record The hosts record to update the UI for
*/
updateButtons: function(record) {
var button = this.buttons[1], status = record.get('status');
/**
* Updates the buttons in the Connection Manager UI according to the
* passed in records host state.
* @param {Ext.data.Record} record The hosts record to update the UI for
*/
updateButtons: function(record) {
var button = this.buttons[1], status = record.get('status');
// Update the Connect/Disconnect button
if (status == _('Connected')) {
button.enable();
button.setText(_('Disconnect'));
} else if (status == _('Offline')) {
button.disable();
} else {
button.enable();
button.setText(_('Connect'));
}
// Update the Connect/Disconnect button
if (status == _('Connected')) {
button.enable();
button.setText(_('Disconnect'));
} else if (status == _('Offline')) {
button.disable();
} else {
button.enable();
button.setText(_('Connect'));
}
// Update the Stop/Start Daemon button
if (status == _('Offline')) {
if (record.get('host') == '127.0.0.1' || record.get('host') == 'localhost') {
this.stopHostButton.enable();
this.stopHostButton.setText(_('Start Daemon'));
} else {
this.stopHostButton.disable();
}
} else {
this.stopHostButton.enable();
this.stopHostButton.setText(_('Stop Daemon'));
}
},
// Update the Stop/Start Daemon button
if (status == _('Offline')) {
if (record.get('host') == '127.0.0.1' || record.get('host') == 'localhost') {
this.stopHostButton.enable();
this.stopHostButton.setText(_('Start Daemon'));
} else {
this.stopHostButton.disable();
}
} else {
this.stopHostButton.enable();
this.stopHostButton.setText(_('Stop Daemon'));
}
},
// private
onAddClick: function(button, e) {
if (!this.addWindow) {
this.addWindow = new Deluge.AddConnectionWindow();
this.addWindow.on('hostadded', this.onHostAdded, this);
}
this.addWindow.show();
},
// private
onAddClick: function(button, e) {
if (!this.addWindow) {
this.addWindow = new Deluge.AddConnectionWindow();
this.addWindow.on('hostadded', this.onHostAdded, this);
}
this.addWindow.show();
},
// private
onHostAdded: function() {
this.loadHosts();
},
// private
onHostAdded: function() {
this.loadHosts();
},
// private
onClose: function(e) {
this.hide();
},
// private
onClose: function(e) {
this.hide();
},
// private
onConnect: function(e) {
var selected = this.list.getSelectedRecords()[0];
if (!selected) return;
// private
onConnect: function(e) {
var selected = this.list.getSelectedRecords()[0];
if (!selected) return;
if (selected.get('status') == _('Connected')) {
deluge.client.web.disconnect({
success: function(result) {
this.update(this);
deluge.events.fire('disconnect');
},
scope: this
});
} else {
var id = selected.id;
deluge.client.web.connect(id, {
success: function(methods) {
deluge.client.reloadMethods();
deluge.client.on('connected', function(e) {
deluge.events.fire('connect');
}, this, {single: true});
}
});
this.hide();
}
},
if (selected.get('status') == _('Connected')) {
deluge.client.web.disconnect({
success: function(result) {
this.update(this);
deluge.events.fire('disconnect');
},
scope: this
});
} else {
var id = selected.id;
deluge.client.web.connect(id, {
success: function(methods) {
deluge.client.reloadMethods();
deluge.client.on('connected', function(e) {
deluge.events.fire('connect');
}, this, {single: true});
}
});
this.hide();
}
},
// private
onGetHosts: function(hosts) {
this.list.getStore().loadData(hosts);
Ext.each(hosts, function(host) {
deluge.client.web.get_host_status(host[0], {
success: this.onGetHostStatus,
scope: this
});
}, this);
},
// private
onGetHosts: function(hosts) {
this.list.getStore().loadData(hosts);
Ext.each(hosts, function(host) {
deluge.client.web.get_host_status(host[0], {
success: this.onGetHostStatus,
scope: this
});
}, this);
},
// private
onGetHostStatus: function(host) {
var record = this.list.getStore().getById(host[0]);
record.set('status', host[3])
record.set('version', host[4])
record.commit();
if (this.list.getSelectedRecords()[0] == record) this.updateButtons(record);
},
// private
onGetHostStatus: function(host) {
var record = this.list.getStore().getById(host[0]);
record.set('status', host[3])
record.set('version', host[4])
record.commit();
if (this.list.getSelectedRecords()[0] == record) this.updateButtons(record);
},
// private
onHide: function() {
if (this.running) window.clearInterval(this.running);
},
// private
onHide: function() {
if (this.running) window.clearInterval(this.running);
},
// private
onLogin: function() {
if (deluge.config.first_login) {
Ext.MessageBox.confirm('Change password',
'As this is your first login, we recommend that you ' +
'change your password. Would you like to ' +
'do this now?', function(res) {
this.checkConnected();
if (res == 'yes') {
deluge.preferences.show();
deluge.preferences.selectPage('Interface');
}
deluge.client.web.set_config({first_login: false});
}, this);
} else {
this.checkConnected();
}
},
// private
onLogin: function() {
if (deluge.config.first_login) {
Ext.MessageBox.confirm('Change password',
'As this is your first login, we recommend that you ' +
'change your password. Would you like to ' +
'do this now?', function(res) {
this.checkConnected();
if (res == 'yes') {
deluge.preferences.show();
deluge.preferences.selectPage('Interface');
}
deluge.client.web.set_config({first_login: false});
}, this);
} else {
this.checkConnected();
}
},
// private
onLogout: function() {
this.disconnect();
if (!this.hidden && this.rendered) {
this.hide();
}
},
// private
onLogout: function() {
this.disconnect();
if (!this.hidden && this.rendered) {
this.hide();
}
},
// private
onRemoveClick: function(button) {
var connection = this.list.getSelectedRecords()[0];
if (!connection) return;
// private
onRemoveClick: function(button) {
var connection = this.list.getSelectedRecords()[0];
if (!connection) return;
deluge.client.web.remove_host(connection.id, {
success: function(result) {
if (!result) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
this.list.getStore().remove(connection);
}
},
scope: this
});
},
deluge.client.web.remove_host(connection.id, {
success: function(result) {
if (!result) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
this.list.getStore().remove(connection);
}
},
scope: this
});
},
// private
onSelectionChanged: function(list, selections) {
if (selections[0]) {
this.removeHostButton.enable();
this.stopHostButton.enable();
this.stopHostButton.setText(_('Stop Daemon'));
this.updateButtons(this.list.getRecord(selections[0]));
} else {
this.removeHostButton.disable();
this.stopHostButton.disable();
}
},
// private
onSelectionChanged: function(list, selections) {
if (selections[0]) {
this.removeHostButton.enable();
this.stopHostButton.enable();
this.stopHostButton.setText(_('Stop Daemon'));
this.updateButtons(this.list.getRecord(selections[0]));
} else {
this.removeHostButton.disable();
this.stopHostButton.disable();
}
},
// FIXME: Find out why this is being fired twice
// private
onShow: function() {
if (!this.addHostButton) {
var bbar = this.panel.getBottomToolbar();
this.addHostButton = bbar.items.get('cm-add');
this.removeHostButton = bbar.items.get('cm-remove');
this.stopHostButton = bbar.items.get('cm-stop');
}
this.loadHosts();
// private
onShow: function() {
if (!this.addHostButton) {
var bbar = this.panel.getBottomToolbar();
this.addHostButton = bbar.items.get('cm-add');
this.removeHostButton = bbar.items.get('cm-remove');
this.stopHostButton = bbar.items.get('cm-stop');
}
this.loadHosts();
if (this.running) return;
this.running = window.setInterval(this.update, 2000, this);
},
this.running = window.setInterval(this.update, 2000, this);
},
// private
onStopClick: function(button, e) {
var connection = this.list.getSelectedRecords()[0];
if (!connection) return;
// private
onStopClick: function(button, e) {
var connection = this.list.getSelectedRecords()[0];
if (!connection) return;
if (connection.get('status') == 'Offline') {
// This means we need to start the daemon
deluge.client.web.start_daemon(connection.get('port'));
} else {
// This means we need to stop the daemon
deluge.client.web.stop_daemon(connection.id, {
success: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
}
}
});
}
}
if (connection.get('status') == 'Offline') {
// This means we need to start the daemon
deluge.client.web.start_daemon(connection.get('port'));
} else {
// This means we need to stop the daemon
deluge.client.web.stop_daemon(connection.id, {
success: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
}
}
});
}
}
});

View file

@ -36,50 +36,50 @@ Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
// Add some additional functions to ext and setup some of the
// configurable parameters
Ext.apply(Ext, {
escapeHTML: function(text) {
text = String(text).replace('<', '&lt;').replace('>', '&gt;');
return text.replace('&', '&amp;');
},
escapeHTML: function(text) {
text = String(text).replace('<', '&lt;').replace('>', '&gt;');
return text.replace('&', '&amp;');
},
isObjectEmpty: function(obj) {
for(var i in obj) { return false; }
return true;
},
isObjectEmpty: function(obj) {
for(var i in obj) { return false; }
return true;
},
areObjectsEqual: function(obj1, obj2) {
var equal = true;
if (!obj1 || !obj2) return false;
for (var i in obj1) {
if (obj1[i] != obj2[i]) {
equal = false;
}
}
return equal;
},
keys: function(obj) {
var keys = [];
for (var i in obj) if (obj.hasOwnProperty(i))
{
keys.push(i);
}
return keys;
},
areObjectsEqual: function(obj1, obj2) {
var equal = true;
if (!obj1 || !obj2) return false;
for (var i in obj1) {
if (obj1[i] != obj2[i]) {
equal = false;
}
}
return equal;
},
keys: function(obj) {
var keys = [];
for (var i in obj) if (obj.hasOwnProperty(i))
{
keys.push(i);
}
return keys;
},
values: function(obj) {
var values = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
values.push(obj[i]);
}
}
return values;
},
splat: function(obj) {
var type = Ext.type(obj);
return (type) ? ((type != 'array') ? [obj] : obj) : [];
}
values: function(obj) {
var values = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
values.push(obj[i]);
}
}
return values;
},
splat: function(obj) {
var type = Ext.type(obj);
return (type) ? ((type != 'array') ? [obj] : obj) : [];
}
});
Ext.getKeys = Ext.keys;
Ext.BLANK_IMAGE_URL = deluge.config.base + 'images/s.gif';
@ -88,65 +88,65 @@ Ext.USE_NATIVE_JSON = true;
// Create the Deluge namespace
Ext.apply(Deluge, {
// private
pluginStore: {},
// private
progressTpl: '<div class="x-progress-wrap x-progress-renderered">' +
'<div class="x-progress-inner">' +
'<div style="width: {2}px" class="x-progress-bar">' +
'<div style="z-index: 99; width: {3}px" class="x-progress-text">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'<div class="x-progress-text x-progress-text-back">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'</div>',
// private
pluginStore: {},
// private
progressTpl: '<div class="x-progress-wrap x-progress-renderered">' +
'<div class="x-progress-inner">' +
'<div style="width: {2}px" class="x-progress-bar">' +
'<div style="z-index: 99; width: {3}px" class="x-progress-text">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'<div class="x-progress-text x-progress-text-back">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'</div>',
/**
* A method to create a progress bar that can be used by renderers
* to display a bar within a grid or tree.
* @param {Number} progress The bars progress
* @param {Number} width The width of the bar
* @param {String} text The text to display on the bar
* @param {Number} modified Amount to subtract from the width allowing for fixes
*/
progressBar: function(progress, width, text, modifier) {
modifier = Ext.value(modifier, 10);
var progressWidth = ((width / 100.0) * progress).toFixed(0);
var barWidth = progressWidth - 1;
var textWidth = ((progressWidth - modifier) > 0 ? progressWidth - modifier : 0);
return String.format(Deluge.progressTpl, text, width, barWidth, textWidth);
},
/**
* A method to create a progress bar that can be used by renderers
* to display a bar within a grid or tree.
* @param {Number} progress The bars progress
* @param {Number} width The width of the bar
* @param {String} text The text to display on the bar
* @param {Number} modified Amount to subtract from the width allowing for fixes
*/
progressBar: function(progress, width, text, modifier) {
modifier = Ext.value(modifier, 10);
var progressWidth = ((width / 100.0) * progress).toFixed(0);
var barWidth = progressWidth - 1;
var textWidth = ((progressWidth - modifier) > 0 ? progressWidth - modifier : 0);
return String.format(Deluge.progressTpl, text, width, barWidth, textWidth);
},
/**
* Constructs a new instance of the specified plugin.
* @param {String} name The plugin name to create
*/
createPlugin: function(name) {
return new Deluge.pluginStore[name]();
},
/**
* Constructs a new instance of the specified plugin.
* @param {String} name The plugin name to create
*/
createPlugin: function(name) {
return new Deluge.pluginStore[name]();
},
/**
* Check to see if a plugin has been registered.
* @param {String} name The plugin name to check
*/
hasPlugin: function(name) {
return (Deluge.pluginStore[name]) ? true : false;
},
/**
* Check to see if a plugin has been registered.
* @param {String} name The plugin name to check
*/
hasPlugin: function(name) {
return (Deluge.pluginStore[name]) ? true : false;
},
/**
* Register a plugin with the Deluge interface.
* @param {String} name The plugin name to register
* @param {Plugin} plugin The plugin to register
*/
registerPlugin: function(name, plugin) {
Deluge.pluginStore[name] = plugin;
}
/**
* Register a plugin with the Deluge interface.
* @param {String} name The plugin name to register
* @param {Plugin} plugin The plugin to register
*/
registerPlugin: function(name, plugin) {
Deluge.pluginStore[name] = plugin;
}
});
// Setup a space for plugins to insert themselves
@ -158,12 +158,12 @@ deluge.plugins = {};
// _('High Priority')
// _('Highest Priority')
FILE_PRIORITY = {
9: 'Mixed',
9: 'Mixed',
0: 'Do Not Download',
1: 'Normal Priority',
2: 'High Priority',
5: 'Highest Priority',
'Mixed': 9,
'Mixed': 9,
'Do Not Download': 0,
'Normal Priority': 1,
'High Priority': 2,
@ -171,9 +171,9 @@ FILE_PRIORITY = {
}
FILE_PRIORITY_CSS = {
9: 'x-mixed-download',
0: 'x-no-download',
1: 'x-normal-download',
2: 'x-high-download',
5: 'x-highest-download'
9: 'x-mixed-download',
0: 'x-no-download',
1: 'x-normal-download',
2: 'x-high-download',
5: 'x-highest-download'
}

View file

@ -37,58 +37,58 @@ Ext.ns('Deluge');
*/
Deluge.EditTrackerWindow = Ext.extend(Ext.Window, {
title: _('Edit Tracker'),
layout: 'fit',
width: 375,
height: 110,
plain: true,
closable: true,
resizable: false,
title: _('Edit Tracker'),
layout: 'fit',
width: 375,
height: 110,
plain: true,
closable: true,
resizable: false,
bodyStyle: 'padding: 5px',
buttonAlign: 'right',
closeAction: 'hide',
iconCls: 'x-deluge-edit-trackers',
initComponent: function() {
Deluge.EditTrackerWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Save'), this.onSaveClick, this);
this.on('hide', this.onHide, this);
this.form = this.add({
xtype: 'form',
defaultType: 'textfield',
baseCls: 'x-plain',
labelWidth: 55,
items: [{
fieldLabel: _('Tracker'),
name: 'tracker',
anchor: '100%'
}]
});
},
show: function(record) {
Deluge.EditTrackerWindow.superclass.show.call(this);
this.record = record;
this.form.getForm().findField('tracker').setValue(record.data['url']);
},
onCancelClick: function() {
this.hide();
},
onHide: function() {
this.form.getForm().findField('tracker').setValue('');
},
onSaveClick: function() {
var url = this.form.getForm().findField('tracker').getValue();
this.record.set('url', url);
this.record.commit();
this.hide();
}
bodyStyle: 'padding: 5px',
buttonAlign: 'right',
closeAction: 'hide',
iconCls: 'x-deluge-edit-trackers',
initComponent: function() {
Deluge.EditTrackerWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Save'), this.onSaveClick, this);
this.on('hide', this.onHide, this);
this.form = this.add({
xtype: 'form',
defaultType: 'textfield',
baseCls: 'x-plain',
labelWidth: 55,
items: [{
fieldLabel: _('Tracker'),
name: 'tracker',
anchor: '100%'
}]
});
},
show: function(record) {
Deluge.EditTrackerWindow.superclass.show.call(this);
this.record = record;
this.form.getForm().findField('tracker').setValue(record.data['url']);
},
onCancelClick: function() {
this.hide();
},
onHide: function() {
this.form.getForm().findField('tracker').setValue('');
},
onSaveClick: function() {
var url = this.form.getForm().findField('tracker').getValue();
this.record.set('url', url);
this.record.commit();
this.hide();
}
});

View file

@ -37,203 +37,203 @@ Ext.ns('Deluge');
*/
Deluge.EditTrackersWindow = Ext.extend(Ext.Window, {
title: _('Edit Trackers'),
layout: 'fit',
width: 350,
height: 220,
plain: true,
closable: true,
resizable: true,
title: _('Edit Trackers'),
layout: 'fit',
width: 350,
height: 220,
plain: true,
closable: true,
resizable: true,
bodyStyle: 'padding: 5px',
buttonAlign: 'right',
closeAction: 'hide',
iconCls: 'x-deluge-edit-trackers',
bodyStyle: 'padding: 5px',
buttonAlign: 'right',
closeAction: 'hide',
iconCls: 'x-deluge-edit-trackers',
initComponent: function() {
Deluge.EditTrackersWindow.superclass.initComponent.call(this);
initComponent: function() {
Deluge.EditTrackersWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Ok'), this.onOkClick, this);
this.addEvents('save');
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Ok'), this.onOkClick, this);
this.addEvents('save');
this.on('show', this.onShow, this);
this.on('save', this.onSave, this);
this.on('show', this.onShow, this);
this.on('save', this.onSave, this);
this.addWindow = new Deluge.AddTrackerWindow();
this.addWindow.on('add', this.onAddTrackers, this);
this.editWindow = new Deluge.EditTrackerWindow();
this.addWindow = new Deluge.AddTrackerWindow();
this.addWindow.on('add', this.onAddTrackers, this);
this.editWindow = new Deluge.EditTrackerWindow();
this.list = new Ext.list.ListView({
store: new Ext.data.JsonStore({
root: 'trackers',
fields: [
'tier',
'url'
]
}),
columns: [{
header: _('Tier'),
width: .1,
dataIndex: 'tier'
}, {
header: _('Tracker'),
width: .9,
dataIndex: 'url'
}],
columnSort: {
sortClasses: ['', '']
},
stripeRows: true,
singleSelect: true,
listeners: {
'dblclick': {fn: this.onListNodeDblClicked, scope: this},
'selectionchange': {fn: this.onSelect, scope: this}
}
});
this.list = new Ext.list.ListView({
store: new Ext.data.JsonStore({
root: 'trackers',
fields: [
'tier',
'url'
]
}),
columns: [{
header: _('Tier'),
width: .1,
dataIndex: 'tier'
}, {
header: _('Tracker'),
width: .9,
dataIndex: 'url'
}],
columnSort: {
sortClasses: ['', '']
},
stripeRows: true,
singleSelect: true,
listeners: {
'dblclick': {fn: this.onListNodeDblClicked, scope: this},
'selectionchange': {fn: this.onSelect, scope: this}
}
});
this.panel = this.add({
margins: '0 0 0 0',
items: [this.list],
autoScroll: true,
bbar: new Ext.Toolbar({
items: [
{
text: _('Up'),
iconCls: 'icon-up',
handler: this.onUpClick,
scope: this
}, {
text: _('Down'),
iconCls: 'icon-down',
handler: this.onDownClick,
scope: this
}, '->', {
text: _('Add'),
iconCls: 'icon-add',
handler: this.onAddClick,
scope: this
}, {
text: _('Edit'),
iconCls: 'icon-edit-trackers',
handler: this.onEditClick,
scope: this
}, {
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onRemoveClick,
scope: this
}
]
})
});
},
this.panel = this.add({
margins: '0 0 0 0',
items: [this.list],
autoScroll: true,
bbar: new Ext.Toolbar({
items: [
{
text: _('Up'),
iconCls: 'icon-up',
handler: this.onUpClick,
scope: this
}, {
text: _('Down'),
iconCls: 'icon-down',
handler: this.onDownClick,
scope: this
}, '->', {
text: _('Add'),
iconCls: 'icon-add',
handler: this.onAddClick,
scope: this
}, {
text: _('Edit'),
iconCls: 'icon-edit-trackers',
handler: this.onEditClick,
scope: this
}, {
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onRemoveClick,
scope: this
}
]
})
});
},
onAddClick: function() {
this.addWindow.show();
},
onAddClick: function() {
this.addWindow.show();
},
onAddTrackers: function(trackers) {
var store = this.list.getStore();
Ext.each(trackers, function(tracker) {
var duplicate = false, heightestTier = -1;
store.each(function(record) {
if (record.get('tier') > heightestTier) {
heightestTier = record.get('tier');
}
if (tracker == record.get('tracker')) {
duplicate = true;
return false;
}
}, this);
if (duplicate) return;
store.add(new store.recordType({'tier': heightestTier + 1, 'url': tracker}));
}, this);
},
onAddTrackers: function(trackers) {
var store = this.list.getStore();
Ext.each(trackers, function(tracker) {
var duplicate = false, heightestTier = -1;
store.each(function(record) {
if (record.get('tier') > heightestTier) {
heightestTier = record.get('tier');
}
if (tracker == record.get('tracker')) {
duplicate = true;
return false;
}
}, this);
if (duplicate) return;
store.add(new store.recordType({'tier': heightestTier + 1, 'url': tracker}));
}, this);
},
onCancelClick: function() {
this.hide();
},
onCancelClick: function() {
this.hide();
},
onEditClick: function() {
this.editWindow.show(this.list.getSelectedRecords()[0]);
},
onEditClick: function() {
this.editWindow.show(this.list.getSelectedRecords()[0]);
},
onHide: function() {
this.list.getStore().removeAll();
},
onHide: function() {
this.list.getStore().removeAll();
},
onListNodeDblClicked: function(list, index, node, e) {
this.editWindow.show(this.list.getRecord(node));
},
onListNodeDblClicked: function(list, index, node, e) {
this.editWindow.show(this.list.getRecord(node));
},
onOkClick: function() {
var trackers = [];
this.list.getStore().each(function(record) {
trackers.push({
'tier': record.get('tier'),
'url': record.get('url')
})
}, this);
onOkClick: function() {
var trackers = [];
this.list.getStore().each(function(record) {
trackers.push({
'tier': record.get('tier'),
'url': record.get('url')
})
}, this);
deluge.client.core.set_torrent_trackers(this.torrentId, trackers, {
failure: this.onSaveFail,
scope: this
});
deluge.client.core.set_torrent_trackers(this.torrentId, trackers, {
failure: this.onSaveFail,
scope: this
});
this.hide();
},
this.hide();
},
onRemoveClick: function() {
// Remove from the grid
this.list.getStore().remove(this.list.getSelectedRecords()[0]);
},
onRemoveClick: function() {
// Remove from the grid
this.list.getStore().remove(this.list.getSelectedRecords()[0]);
},
onRequestComplete: function(status) {
this.list.getStore().loadData(status);
this.list.getStore().sort('tier', 'ASC');
},
onRequestComplete: function(status) {
this.list.getStore().loadData(status);
this.list.getStore().sort('tier', 'ASC');
},
onSaveFail: function() {
onSaveFail: function() {
},
},
onSelect: function(list) {
if (list.getSelectionCount()) {
this.panel.getBottomToolbar().items.get(4).enable();
}
},
onSelect: function(list) {
if (list.getSelectionCount()) {
this.panel.getBottomToolbar().items.get(4).enable();
}
},
onShow: function() {
this.panel.getBottomToolbar().items.get(4).disable();
var r = deluge.torrents.getSelected();
this.torrentId = r.id;
deluge.client.core.get_torrent_status(r.id, ['trackers'], {
success: this.onRequestComplete,
scope: this
});
},
onShow: function() {
this.panel.getBottomToolbar().items.get(4).disable();
var r = deluge.torrents.getSelected();
this.torrentId = r.id;
deluge.client.core.get_torrent_status(r.id, ['trackers'], {
success: this.onRequestComplete,
scope: this
});
},
onDownClick: function() {
var r = this.list.getSelectedRecords()[0];
onDownClick: function() {
var r = this.list.getSelectedRecords()[0];
if (!r) return;
r.set('tier', r.get('tier') + 1);
r.store.sort('tier', 'ASC');
r.set('tier', r.get('tier') + 1);
r.store.sort('tier', 'ASC');
r.store.commitChanges();
this.list.select(r.store.indexOf(r));
},
},
onUpClick: function() {
var r = this.list.getSelectedRecords()[0];
onUpClick: function() {
var r = this.list.getSelectedRecords()[0];
if (!r) return;
if (r.get('tier') == 0) return;
r.set('tier', r.get('tier') - 1);
r.store.sort('tier', 'ASC');
if (r.get('tier') == 0) return;
r.set('tier', r.get('tier') - 1);
r.store.sort('tier', 'ASC');
r.store.commitChanges();
this.list.select(r.store.indexOf(r));
}
}
});

View file

@ -37,79 +37,79 @@
* Class for holding global events that occur within the UI.
*/
Deluge.EventsManager = Ext.extend(Ext.util.Observable, {
constructor: function() {
this.toRegister = [];
this.on('login', this.onLogin, this);
Deluge.EventsManager.superclass.constructor.call(this);
},
/**
* Append an event handler to this object.
*/
addListener: function(eventName, fn, scope, o) {
this.addEvents(eventName);
if (/[A-Z]/.test(eventName.substring(0, 1))) {
if (!deluge.client) {
this.toRegister.push(eventName);
} else {
deluge.client.web.register_event_listener(eventName);
}
}
Deluge.EventsManager.superclass.addListener.call(this, eventName, fn, scope, o);
},
constructor: function() {
this.toRegister = [];
this.on('login', this.onLogin, this);
Deluge.EventsManager.superclass.constructor.call(this);
},
/**
* Append an event handler to this object.
*/
addListener: function(eventName, fn, scope, o) {
this.addEvents(eventName);
if (/[A-Z]/.test(eventName.substring(0, 1))) {
if (!deluge.client) {
this.toRegister.push(eventName);
} else {
deluge.client.web.register_event_listener(eventName);
}
}
Deluge.EventsManager.superclass.addListener.call(this, eventName, fn, scope, o);
},
getEvents: function() {
deluge.client.web.get_events({
success: this.onGetEventsSuccess,
failure: this.onGetEventsFailure,
scope: this
});
},
getEvents: function() {
deluge.client.web.get_events({
success: this.onGetEventsSuccess,
failure: this.onGetEventsFailure,
scope: this
});
},
/**
* Starts the EventsManagerManager checking for events.
*/
start: function() {
Ext.each(this.toRegister, function(eventName) {
deluge.client.web.register_event_listener(eventName);
});
this.running = true;
this.errorCount = 0;
this.getEvents();
},
/**
* Starts the EventsManagerManager checking for events.
*/
start: function() {
Ext.each(this.toRegister, function(eventName) {
deluge.client.web.register_event_listener(eventName);
});
this.running = true;
this.errorCount = 0;
this.getEvents();
},
/**
* Stops the EventsManagerManager checking for events.
*/
stop: function() {
this.running = false;
},
/**
* Stops the EventsManagerManager checking for events.
*/
stop: function() {
this.running = false;
},
// private
onLogin: function() {
this.start();
},
// private
onLogin: function() {
this.start();
},
onGetEventsSuccess: function(events) {
if (!events) return;
Ext.each(events, function(event) {
var name = event[0], args = event[1];
args.splice(0, 0, name);
this.fireEvent.apply(this, args);
}, this);
if (this.running) this.getEvents();
},
onGetEventsSuccess: function(events) {
if (!events) return;
Ext.each(events, function(event) {
var name = event[0], args = event[1];
args.splice(0, 0, name);
this.fireEvent.apply(this, args);
}, this);
if (this.running) this.getEvents();
},
// private
onGetEventsFailure: function(result, error) {
// the request timed out or we had a communication failure
if (!this.running) return;
if (!error.isTimeout && this.errorCount++ >= 3) {
this.stop();
return;
}
this.getEvents();
}
// private
onGetEventsFailure: function(result, error) {
// the request timed out or we had a communication failure
if (!this.running) return;
if (!error.isTimeout && this.errorCount++ >= 3) {
this.stop();
return;
}
this.getEvents();
}
});
/**

View file

@ -33,30 +33,30 @@
Ext.namespace('Deluge');
Deluge.FileBrowser = Ext.extend(Ext.Window, {
title: _('File Browser'),
title: _('File Browser'),
width: 500,
height: 400,
width: 500,
height: 400,
initComponent: function() {
Deluge.FileBrowser.superclass.initComponent.call(this);
initComponent: function() {
Deluge.FileBrowser.superclass.initComponent.call(this);
this.add({
xtype: 'toolbar',
items: [{
text: _('Back'),
iconCls: 'icon-back'
}, {
text: _('Forward'),
iconCls: 'icon-forward'
}, {
text: _('Up'),
iconCls: 'icon-up'
}, {
text: _('Home'),
iconCls: 'icon-home'
}]
});
}
this.add({
xtype: 'toolbar',
items: [{
text: _('Back'),
iconCls: 'icon-back'
}, {
text: _('Forward'),
iconCls: 'icon-forward'
}, {
text: _('Up'),
iconCls: 'icon-up'
}, {
text: _('Home'),
iconCls: 'icon-home'
}]
});
}
});

View file

@ -39,132 +39,132 @@ Deluge.FilterPanel = Ext.extend(Ext.Panel, {
autoScroll: true,
border: false,
border: false,
show_zero: null,
show_zero: null,
initComponent: function() {
Deluge.FilterPanel.superclass.initComponent.call(this);
this.filterType = this.initialConfig.filter;
initComponent: function() {
Deluge.FilterPanel.superclass.initComponent.call(this);
this.filterType = this.initialConfig.filter;
var title = this.filterType.replace('_', ' '),
parts = title.split(' '),
title = '';
Ext.each(parts, function(p) {
fl = p.substring(0, 1).toUpperCase();
title += fl + p.substring(1) + ' ';
});
this.setTitle(_(title));
var title = this.filterType.replace('_', ' '),
parts = title.split(' '),
title = '';
Ext.each(parts, function(p) {
fl = p.substring(0, 1).toUpperCase();
title += fl + p.substring(1) + ' ';
});
this.setTitle(_(title));
if (Deluge.FilterPanel.templates[this.filterType]) {
var tpl = Deluge.FilterPanel.templates[this.filterType];
} else {
var tpl = '<div class="x-deluge-filter x-deluge-{filter:lowercase}">{filter} ({count})</div>';
}
if (Deluge.FilterPanel.templates[this.filterType]) {
var tpl = Deluge.FilterPanel.templates[this.filterType];
} else {
var tpl = '<div class="x-deluge-filter x-deluge-{filter:lowercase}">{filter} ({count})</div>';
}
this.list = this.add({
xtype: 'listview',
singleSelect: true,
hideHeaders: true,
reserveScrollOffset: true,
store: new Ext.data.ArrayStore({
idIndex: 0,
fields: ['filter', 'count']
}),
columns: [{
id: 'filter',
sortable: false,
tpl: tpl,
dataIndex: 'filter'
}]
});
this.relayEvents(this.list, ['selectionchange']);
},
this.list = this.add({
xtype: 'listview',
singleSelect: true,
hideHeaders: true,
reserveScrollOffset: true,
store: new Ext.data.ArrayStore({
idIndex: 0,
fields: ['filter', 'count']
}),
columns: [{
id: 'filter',
sortable: false,
tpl: tpl,
dataIndex: 'filter'
}]
});
this.relayEvents(this.list, ['selectionchange']);
},
/**
* Return the currently selected filter state
* @returns {String} the current filter state
*/
getState: function() {
if (!this.list.getSelectionCount()) return;
/**
* Return the currently selected filter state
* @returns {String} the current filter state
*/
getState: function() {
if (!this.list.getSelectionCount()) return;
var state = this.list.getSelectedRecords()[0];
if (state.id == 'All') return;
return state.id;
},
var state = this.list.getSelectedRecords()[0];
if (state.id == 'All') return;
return state.id;
},
/**
* Return the current states in the filter
*/
getStates: function() {
return this.states;
},
/**
* Return the current states in the filter
*/
getStates: function() {
return this.states;
},
/**
* Return the Store for the ListView of the FilterPanel
* @returns {Ext.data.Store} the ListView store
*/
getStore: function() {
return this.list.getStore();
},
/**
* Return the Store for the ListView of the FilterPanel
* @returns {Ext.data.Store} the ListView store
*/
getStore: function() {
return this.list.getStore();
},
/**
* Update the states in the FilterPanel
*/
updateStates: function(states) {
this.states = {};
Ext.each(states, function(state) {
this.states[state[0]] = state[1];
}, this);
/**
* Update the states in the FilterPanel
*/
updateStates: function(states) {
this.states = {};
Ext.each(states, function(state) {
this.states[state[0]] = state[1];
}, this);
var show_zero = (this.show_zero == null) ? deluge.config.sidebar_show_zero : this.show_zero;
if (!show_zero) {
var newStates = [];
Ext.each(states, function(state) {
if (state[1] > 0 || state[0] == _('All')) {
newStates.push(state);
}
});
states = newStates;
}
var show_zero = (this.show_zero == null) ? deluge.config.sidebar_show_zero : this.show_zero;
if (!show_zero) {
var newStates = [];
Ext.each(states, function(state) {
if (state[1] > 0 || state[0] == _('All')) {
newStates.push(state);
}
});
states = newStates;
}
var store = this.getStore();
var filters = {};
Ext.each(states, function(s, i) {
var record = store.getById(s[0]);
if (!record) {
record = new store.recordType({
filter: s[0],
count: s[1]
});
record.id = s[0];
store.insert(i, record);
}
record.beginEdit();
record.set('filter', s[0]);
record.set('count', s[1]);
record.endEdit();
filters[s[0]] = true;
}, this);
var store = this.getStore();
var filters = {};
Ext.each(states, function(s, i) {
var record = store.getById(s[0]);
if (!record) {
record = new store.recordType({
filter: s[0],
count: s[1]
});
record.id = s[0];
store.insert(i, record);
}
record.beginEdit();
record.set('filter', s[0]);
record.set('count', s[1]);
record.endEdit();
filters[s[0]] = true;
}, this);
store.each(function(record) {
if (filters[record.id]) return;
var r = this.list.getSelectedRecords()[0];
store.remove(record);
if (r.id == record.id) {
this.list.select(0);
}
}, this);
store.each(function(record) {
if (filters[record.id]) return;
var r = this.list.getSelectedRecords()[0];
store.remove(record);
if (r.id == record.id) {
this.list.select(0);
}
}, this);
store.commitChanges();
store.commitChanges();
if (!this.list.getSelectionCount()) {
this.list.select(0);
}
}
if (!this.list.getSelectionCount()) {
this.list.select(0);
}
}
});
Deluge.FilterPanel.templates = {
'tracker_host': '<div class="x-deluge-filter" style="background-image: url(' + deluge.config.base + 'tracker/{filter});">{filter} ({count})</div>'
'tracker_host': '<div class="x-deluge-filter" style="background-image: url(' + deluge.config.base + 'tracker/{filter});">{filter} ({count})</div>'
}

View file

@ -38,115 +38,115 @@
* @singleton
*/
Deluge.Formatters = {
/**
* Formats a date string in the locale's date representation based on the
* systems timezone.
*
* @param {Number} timestamp time in seconds since the Epoch
* @return {String} a string in the locale's date representation or ""
* if seconds < 0
*/
date: function(timestamp) {
function zeroPad(num, count) {
var numZeropad = num + '';
while (numZeropad.length < count) {
numZeropad = '0' + numZeropad;
}
return numZeropad;
}
timestamp = timestamp * 1000;
var date = new Date(timestamp);
return String.format('{0}/{1}/{2} {3}:{4}:{5}',
zeroPad(date.getDate(), 2), zeroPad(date.getMonth() + 1, 2), date.getFullYear(),
zeroPad(date.getHours(), 2), zeroPad(date.getMinutes(), 2), zeroPad(date.getSeconds(), 2));
},
/**
* Formats the bytes value into a string with KiB, MiB or GiB units.
*
* @param {Number} bytes the filesize in bytes
* @param {Boolean} showZero pass in true to displays 0 values
* @return {String} formatted string with KiB, MiB or GiB units.
*/
size: function(bytes, showZero) {
if (!bytes && !showZero) return '';
bytes = bytes / 1024.0;
if (bytes < 1024) { return bytes.toFixed(1) + ' KiB'; }
else { bytes = bytes / 1024; }
if (bytes < 1024) { return bytes.toFixed(1) + ' MiB'; }
else { bytes = bytes / 1024; }
return bytes.toFixed(1) + ' GiB'
},
/**
* Formats a string to display a transfer speed utilizing {@link #size}
*
* @param {Number} bytes the number of bytes per second
* @param {Boolean} showZero pass in true to displays 0 values
* @return {String} formatted string with KiB, MiB or GiB units.
*/
speed: function(bytes, showZero) {
return (!bytes && !showZero) ? '' : fsize(bytes, showZero) + '/s';
},
/**
* Formats a string to show time in a human readable form.
*
* @param {Number} time the number of seconds
* @return {String} a formatted time string. will return '' if seconds == 0
*/
timeRemaining: function(time) {
if (time == 0) { return '&infin;' }
/**
* Formats a date string in the locale's date representation based on the
* systems timezone.
*
* @param {Number} timestamp time in seconds since the Epoch
* @return {String} a string in the locale's date representation or ""
* if seconds < 0
*/
date: function(timestamp) {
function zeroPad(num, count) {
var numZeropad = num + '';
while (numZeropad.length < count) {
numZeropad = '0' + numZeropad;
}
return numZeropad;
}
timestamp = timestamp * 1000;
var date = new Date(timestamp);
return String.format('{0}/{1}/{2} {3}:{4}:{5}',
zeroPad(date.getDate(), 2), zeroPad(date.getMonth() + 1, 2), date.getFullYear(),
zeroPad(date.getHours(), 2), zeroPad(date.getMinutes(), 2), zeroPad(date.getSeconds(), 2));
},
/**
* Formats the bytes value into a string with KiB, MiB or GiB units.
*
* @param {Number} bytes the filesize in bytes
* @param {Boolean} showZero pass in true to displays 0 values
* @return {String} formatted string with KiB, MiB or GiB units.
*/
size: function(bytes, showZero) {
if (!bytes && !showZero) return '';
bytes = bytes / 1024.0;
if (bytes < 1024) { return bytes.toFixed(1) + ' KiB'; }
else { bytes = bytes / 1024; }
if (bytes < 1024) { return bytes.toFixed(1) + ' MiB'; }
else { bytes = bytes / 1024; }
return bytes.toFixed(1) + ' GiB'
},
/**
* Formats a string to display a transfer speed utilizing {@link #size}
*
* @param {Number} bytes the number of bytes per second
* @param {Boolean} showZero pass in true to displays 0 values
* @return {String} formatted string with KiB, MiB or GiB units.
*/
speed: function(bytes, showZero) {
return (!bytes && !showZero) ? '' : fsize(bytes, showZero) + '/s';
},
/**
* Formats a string to show time in a human readable form.
*
* @param {Number} time the number of seconds
* @return {String} a formatted time string. will return '' if seconds == 0
*/
timeRemaining: function(time) {
if (time == 0) { return '&infin;' }
time = time.toFixed(0);
if (time < 60) { return time + 's'; }
else { time = time / 60; }
if (time < 60) {
var minutes = Math.floor(time)
var seconds = Math.round(60 * (time - minutes))
if (seconds > 0) {
return minutes + 'm ' + seconds + 's';
} else {
return minutes + 'm'; }
}
else { time = time / 60; }
if (time < 24) {
var hours = Math.floor(time)
var minutes = Math.round(60 * (time - hours))
if (minutes > 0) {
return hours + 'h ' + minutes + 'm';
} else {
return hours + 'h';
}
}
else { time = time / 24; }
var days = Math.floor(time)
var hours = Math.round(24 * (time - days))
if (hours > 0) {
return days + 'd ' + hours + 'h';
} else {
return days + 'd';
}
},
/**
* Simply returns the value untouched, for when no formatting is required.
*
* @param {Mixed} value the value to be displayed
* @return the untouched value.
*/
plain: function(value) {
return value;
},
if (time < 60) { return time + 's'; }
else { time = time / 60; }
if (time < 60) {
var minutes = Math.floor(time)
var seconds = Math.round(60 * (time - minutes))
if (seconds > 0) {
return minutes + 'm ' + seconds + 's';
} else {
return minutes + 'm'; }
}
else { time = time / 60; }
if (time < 24) {
var hours = Math.floor(time)
var minutes = Math.round(60 * (time - hours))
if (minutes > 0) {
return hours + 'h ' + minutes + 'm';
} else {
return hours + 'h';
}
}
else { time = time / 24; }
var days = Math.floor(time)
var hours = Math.round(24 * (time - days))
if (hours > 0) {
return days + 'd ' + hours + 'h';
} else {
return days + 'd';
}
},
/**
* Simply returns the value untouched, for when no formatting is required.
*
* @param {Mixed} value the value to be displayed
* @return the untouched value.
*/
plain: function(value) {
return value;
},
cssClassEscape: function(value) {
return value.toLowerCase().replace('.', '_');
}
cssClassEscape: function(value) {
return value.toLowerCase().replace('.', '_');
}
}
var fsize = Deluge.Formatters.size;
var fspeed = Deluge.Formatters.speed;

View file

@ -37,13 +37,13 @@
*/
Deluge.Keys = {
/**
* Keys that are used within the torrent grid.
* <pre>['queue', 'name', 'total_size', 'state', 'progress', 'num_seeds',
* 'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
* 'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
* 'is_auto_managed', 'time_added', 'tracker_host']</pre>
*/
/**
* Keys that are used within the torrent grid.
* <pre>['queue', 'name', 'total_size', 'state', 'progress', 'num_seeds',
* 'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
* 'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
* 'is_auto_managed', 'time_added', 'tracker_host']</pre>
*/
Grid: [
'queue', 'name', 'total_size', 'state', 'progress', 'num_seeds',
'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
@ -54,22 +54,22 @@ Deluge.Keys = {
/**
* Keys used in the status tab of the statistics panel.
* These get updated to include the keys in {@link #Grid}.
* <pre>['total_done', 'total_payload_download', 'total_uploaded',
* 'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
* 'piece_length', 'is_auto_managed', 'active_time', 'seeding_time',
* 'seed_rank']</pre>
*/
* <pre>['total_done', 'total_payload_download', 'total_uploaded',
* 'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
* 'piece_length', 'is_auto_managed', 'active_time', 'seeding_time',
* 'seed_rank']</pre>
*/
Status: [
'total_done', 'total_payload_download', 'total_uploaded',
'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
'piece_length', 'is_auto_managed', 'active_time', 'seeding_time',
'seed_rank'
'seed_rank', 'last_seen_complete', 'owner', 'public', 'shared'
],
/**
* Keys used in the files tab of the statistics panel.
* <pre>['files', 'file_progress', 'file_priorities']</pre>
*/
*/
Files: [
'files', 'file_progress', 'file_priorities'
],
@ -77,25 +77,25 @@ Deluge.Keys = {
/**
* Keys used in the peers tab of the statistics panel.
* <pre>['peers']</pre>
*/
*/
Peers: [
'peers'
],
/**
* Keys used in the details tab of the statistics panel.
*/
*/
Details: [
'name', 'save_path', 'total_size', 'num_files', 'message',
'tracker', 'comment'
],
/**
* Keys used in the options tab of the statistics panel.
* <pre>['max_download_speed', 'max_upload_speed', 'max_connections', 'max_upload_slots',
* 'is_auto_managed', 'stop_at_ratio', 'stop_ratio', 'remove_at_ratio', 'private',
* 'prioritize_first_last']</pre>
*/
* Keys used in the options tab of the statistics panel.
* <pre>['max_download_speed', 'max_upload_speed', 'max_connections', 'max_upload_slots',
* 'is_auto_managed', 'stop_at_ratio', 'stop_ratio', 'remove_at_ratio', 'private',
* 'prioritize_first_last']</pre>
*/
Options: [
'max_download_speed', 'max_upload_speed', 'max_connections',
'max_upload_slots','is_auto_managed', 'stop_at_ratio', 'stop_ratio',

View file

@ -31,123 +31,123 @@
*/
Deluge.LoginWindow = Ext.extend(Ext.Window, {
firstShow: true,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'center',
closable: false,
closeAction: 'hide',
iconCls: 'x-deluge-login-window-icon',
layout: 'fit',
modal: true,
plain: true,
resizable: false,
title: _('Login'),
width: 300,
height: 120,
initComponent: function() {
Deluge.LoginWindow.superclass.initComponent.call(this);
this.on('show', this.onShow, this);
this.addButton({
text: _('Login'),
handler: this.onLogin,
scope: this
});
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
labelWidth: 55,
width: 300,
defaults: {width: 200},
defaultType: 'textfield'
});
firstShow: true,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'center',
closable: false,
closeAction: 'hide',
iconCls: 'x-deluge-login-window-icon',
layout: 'fit',
modal: true,
plain: true,
resizable: false,
title: _('Login'),
width: 300,
height: 120,
initComponent: function() {
Deluge.LoginWindow.superclass.initComponent.call(this);
this.on('show', this.onShow, this);
this.addButton({
text: _('Login'),
handler: this.onLogin,
scope: this
});
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
labelWidth: 55,
width: 300,
defaults: {width: 200},
defaultType: 'textfield'
});
this.passwordField = this.form.add({
xtype: 'textfield',
fieldLabel: _('Password'),
id: '_password',
name: 'password',
inputType: 'password'
});
this.passwordField.on('specialkey', this.onSpecialKey, this);
},
logout: function() {
deluge.events.fire('logout');
deluge.client.auth.delete_session({
success: function(result) {
this.show(true);
},
scope: this
});
},
show: function(skipCheck) {
if (this.firstShow) {
deluge.client.on('error', this.onClientError, this);
this.firstShow = false;
}
if (skipCheck) {
return Deluge.LoginWindow.superclass.show.call(this);
}
deluge.client.auth.check_session({
success: function(result) {
if (result) {
deluge.events.fire('login');
} else {
this.show(true);
}
},
failure: function(result) {
this.show(true);
},
scope: this
});
},
onSpecialKey: function(field, e) {
if (e.getKey() == 13) this.onLogin();
},
onLogin: function() {
var passwordField = this.passwordField;
deluge.client.auth.login(passwordField.getValue(), {
success: function(result) {
if (result) {
deluge.events.fire('login');
this.hide();
passwordField.setRawValue('');
} else {
Ext.MessageBox.show({
title: _('Login Failed'),
msg: _('You entered an incorrect password'),
buttons: Ext.MessageBox.OK,
modal: false,
fn: function() {
passwordField.focus(true, 10);
},
icon: Ext.MessageBox.WARNING,
iconCls: 'x-deluge-icon-warning'
});
}
},
scope: this
});
},
onClientError: function(errorObj, response, requestOptions) {
if (errorObj.error.code == 1) {
deluge.events.fire('logout');
this.show(true);
}
},
onShow: function() {
this.passwordField.focus(true, true);
}
this.passwordField = this.form.add({
xtype: 'textfield',
fieldLabel: _('Password'),
id: '_password',
name: 'password',
inputType: 'password'
});
this.passwordField.on('specialkey', this.onSpecialKey, this);
},
logout: function() {
deluge.events.fire('logout');
deluge.client.auth.delete_session({
success: function(result) {
this.show(true);
},
scope: this
});
},
show: function(skipCheck) {
if (this.firstShow) {
deluge.client.on('error', this.onClientError, this);
this.firstShow = false;
}
if (skipCheck) {
return Deluge.LoginWindow.superclass.show.call(this);
}
deluge.client.auth.check_session({
success: function(result) {
if (result) {
deluge.events.fire('login');
} else {
this.show(true);
}
},
failure: function(result) {
this.show(true);
},
scope: this
});
},
onSpecialKey: function(field, e) {
if (e.getKey() == 13) this.onLogin();
},
onLogin: function() {
var passwordField = this.passwordField;
deluge.client.auth.login(passwordField.getValue(), {
success: function(result) {
if (result) {
deluge.events.fire('login');
this.hide();
passwordField.setRawValue('');
} else {
Ext.MessageBox.show({
title: _('Login Failed'),
msg: _('You entered an incorrect password'),
buttons: Ext.MessageBox.OK,
modal: false,
fn: function() {
passwordField.focus(true, 10);
},
icon: Ext.MessageBox.WARNING,
iconCls: 'x-deluge-icon-warning'
});
}
},
scope: this
});
},
onClientError: function(errorObj, response, requestOptions) {
if (errorObj.error.code == 1) {
deluge.events.fire('logout');
this.show(true);
}
},
onShow: function() {
this.passwordField.focus(true, true);
}
});

View file

@ -31,240 +31,240 @@
*/
deluge.menus = {
onTorrentAction: function(item, e) {
var ids = deluge.torrents.getSelectedIds();
var action = item.initialConfig.torrentAction;
switch (action) {
case 'pause':
case 'resume':
deluge.client.core[action + '_torrent'](ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'top':
case 'up':
case 'down':
case 'bottom':
deluge.client.core['queue_' + action](ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'edit_trackers':
deluge.editTrackers.show();
break;
case 'update':
deluge.client.core.force_reannounce(ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'remove':
deluge.removeWindow.show(ids);
break;
case 'recheck':
deluge.client.core.force_recheck(ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'move':
deluge.moveStorage.show(ids);
break;
}
}
onTorrentAction: function(item, e) {
var ids = deluge.torrents.getSelectedIds();
var action = item.initialConfig.torrentAction;
switch (action) {
case 'pause':
case 'resume':
deluge.client.core[action + '_torrent'](ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'top':
case 'up':
case 'down':
case 'bottom':
deluge.client.core['queue_' + action](ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'edit_trackers':
deluge.editTrackers.show();
break;
case 'update':
deluge.client.core.force_reannounce(ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'remove':
deluge.removeWindow.show(ids);
break;
case 'recheck':
deluge.client.core.force_recheck(ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'move':
deluge.moveStorage.show(ids);
break;
}
}
}
deluge.menus.torrent = new Ext.menu.Menu({
id: 'torrentMenu',
items: [{
torrentAction: 'pause',
text: _('Pause'),
iconCls: 'icon-pause',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, {
torrentAction: 'resume',
text: _('Resume'),
iconCls: 'icon-resume',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, '-', {
text: _('Options'),
iconCls: 'icon-options',
menu: new Ext.menu.Menu({
items: [{
text: _('D/L Speed Limit'),
iconCls: 'x-deluge-downloading',
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
}, {
text: _('10 KiB/s')
}, {
text: _('30 KiB/s')
}, {
text: _('80 KiB/s')
}, {
text: _('300 KiB/s')
},{
text: _('Unlimited')
}]
})
}, {
text: _('U/L Speed Limit'),
iconCls: 'x-deluge-seeding',
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
}, {
text: _('10 KiB/s')
}, {
text: _('30 KiB/s')
}, {
text: _('80 KiB/s')
}, {
text: _('300 KiB/s')
},{
text: _('Unlimited')
}]
})
}, {
text: _('Connection Limit'),
iconCls: 'x-deluge-connections',
menu: new Ext.menu.Menu({
items: [{
text: _('50')
}, {
text: _('100')
}, {
text: _('200')
}, {
text: _('300')
}, {
text: _('500')
},{
text: _('Unlimited')
}]
})
}, {
text: _('Upload Slot Limit'),
iconCls: 'icon-upload-slots',
menu: new Ext.menu.Menu({
items: [{
text: _('0')
}, {
text: _('1')
}, {
text: _('2')
}, {
text: _('3')
}, {
text: _('5')
},{
text: _('Unlimited')
}]
})
}, {
id: 'auto_managed',
text: _('Auto Managed'),
checked: false
}]
})
}, '-', {
text: _('Queue'),
iconCls: 'icon-queue',
menu: new Ext.menu.Menu({
items: [{
torrentAction: 'top',
text: _('Top'),
iconCls: 'icon-top',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
},{
torrentAction: 'up',
text: _('Up'),
iconCls: 'icon-up',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
},{
torrentAction: 'down',
text: _('Down'),
iconCls: 'icon-down',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
},{
torrentAction: 'bottom',
text: _('Bottom'),
iconCls: 'icon-bottom',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}]
})
}, '-', {
torrentAction: 'update',
text: _('Update Tracker'),
iconCls: 'icon-update-tracker',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, {
torrentAction: 'edit_trackers',
text: _('Edit Trackers'),
iconCls: 'icon-edit-trackers',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, '-', {
torrentAction: 'remove',
text: _('Remove Torrent'),
iconCls: 'icon-remove',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, '-', {
torrentAction: 'recheck',
text: _('Force Recheck'),
iconCls: 'icon-recheck',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, {
torrentAction: 'move',
text: _('Move Storage'),
iconCls: 'icon-move',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}]
id: 'torrentMenu',
items: [{
torrentAction: 'pause',
text: _('Pause'),
iconCls: 'icon-pause',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, {
torrentAction: 'resume',
text: _('Resume'),
iconCls: 'icon-resume',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, '-', {
text: _('Options'),
iconCls: 'icon-options',
menu: new Ext.menu.Menu({
items: [{
text: _('D/L Speed Limit'),
iconCls: 'x-deluge-downloading',
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
}, {
text: _('10 KiB/s')
}, {
text: _('30 KiB/s')
}, {
text: _('80 KiB/s')
}, {
text: _('300 KiB/s')
},{
text: _('Unlimited')
}]
})
}, {
text: _('U/L Speed Limit'),
iconCls: 'x-deluge-seeding',
menu: new Ext.menu.Menu({
items: [{
text: _('5 KiB/s')
}, {
text: _('10 KiB/s')
}, {
text: _('30 KiB/s')
}, {
text: _('80 KiB/s')
}, {
text: _('300 KiB/s')
},{
text: _('Unlimited')
}]
})
}, {
text: _('Connection Limit'),
iconCls: 'x-deluge-connections',
menu: new Ext.menu.Menu({
items: [{
text: _('50')
}, {
text: _('100')
}, {
text: _('200')
}, {
text: _('300')
}, {
text: _('500')
},{
text: _('Unlimited')
}]
})
}, {
text: _('Upload Slot Limit'),
iconCls: 'icon-upload-slots',
menu: new Ext.menu.Menu({
items: [{
text: _('0')
}, {
text: _('1')
}, {
text: _('2')
}, {
text: _('3')
}, {
text: _('5')
},{
text: _('Unlimited')
}]
})
}, {
id: 'auto_managed',
text: _('Auto Managed'),
checked: false
}]
})
}, '-', {
text: _('Queue'),
iconCls: 'icon-queue',
menu: new Ext.menu.Menu({
items: [{
torrentAction: 'top',
text: _('Top'),
iconCls: 'icon-top',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
},{
torrentAction: 'up',
text: _('Up'),
iconCls: 'icon-up',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
},{
torrentAction: 'down',
text: _('Down'),
iconCls: 'icon-down',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
},{
torrentAction: 'bottom',
text: _('Bottom'),
iconCls: 'icon-bottom',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}]
})
}, '-', {
torrentAction: 'update',
text: _('Update Tracker'),
iconCls: 'icon-update-tracker',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, {
torrentAction: 'edit_trackers',
text: _('Edit Trackers'),
iconCls: 'icon-edit-trackers',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, '-', {
torrentAction: 'remove',
text: _('Remove Torrent'),
iconCls: 'icon-remove',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, '-', {
torrentAction: 'recheck',
text: _('Force Recheck'),
iconCls: 'icon-recheck',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}, {
torrentAction: 'move',
text: _('Move Storage'),
iconCls: 'icon-move',
handler: deluge.menus.onTorrentAction,
scope: deluge.menus
}]
});
deluge.menus.filePriorities = new Ext.menu.Menu({
id: 'filePrioritiesMenu',
items: [{
id: 'expandAll',
text: _('Expand All'),
iconCls: 'icon-expand-all'
}, '-', {
id: 'no_download',
text: _('Do Not Download'),
iconCls: 'icon-do-not-download',
filePriority: 0
}, {
id: 'normal',
text: _('Normal Priority'),
iconCls: 'icon-normal',
filePriority: 1
}, {
id: 'high',
text: _('High Priority'),
iconCls: 'icon-high',
filePriority: 2
}, {
id: 'highest',
text: _('Highest Priority'),
iconCls: 'icon-highest',
filePriority: 5
}]
id: 'filePrioritiesMenu',
items: [{
id: 'expandAll',
text: _('Expand All'),
iconCls: 'icon-expand-all'
}, '-', {
id: 'no_download',
text: _('Do Not Download'),
iconCls: 'icon-do-not-download',
filePriority: 0
}, {
id: 'normal',
text: _('Normal Priority'),
iconCls: 'icon-normal',
filePriority: 1
}, {
id: 'high',
text: _('High Priority'),
iconCls: 'icon-high',
filePriority: 2
}, {
id: 'highest',
text: _('Highest Priority'),
iconCls: 'icon-highest',
filePriority: 5
}]
});

View file

@ -32,73 +32,73 @@
Ext.namespace('Deluge');
Deluge.MoveStorage = Ext.extend(Ext.Window, {
constructor: function(config) {
config = Ext.apply({
title: _('Move Storage'),
width: 375,
height: 110,
layout: 'fit',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
iconCls: 'x-deluge-move-storage',
plain: true,
resizable: false
}, config);
Deluge.MoveStorage.superclass.constructor.call(this, config);
},
constructor: function(config) {
config = Ext.apply({
title: _('Move Storage'),
width: 375,
height: 110,
layout: 'fit',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
iconCls: 'x-deluge-move-storage',
plain: true,
resizable: false
}, config);
Deluge.MoveStorage.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.MoveStorage.superclass.initComponent.call(this);
initComponent: function() {
Deluge.MoveStorage.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancel, this);
this.addButton(_('Move'), this.onMove, this);
this.addButton(_('Cancel'), this.onCancel, this);
this.addButton(_('Move'), this.onMove, this);
this.form = this.add({
xtype: 'form',
border: false,
defaultType: 'textfield',
width: 300,
bodyStyle: 'padding: 5px'
});
this.form = this.add({
xtype: 'form',
border: false,
defaultType: 'textfield',
width: 300,
bodyStyle: 'padding: 5px'
});
this.moveLocation = this.form.add({
fieldLabel: _('Location'),
name: 'location',
width: 240
});
//this.form.add({
// xtype: 'button',
// text: _('Browse'),
// handler: function() {
// if (!this.fileBrowser) {
// this.fileBrowser = new Deluge.FileBrowser();
// }
// this.fileBrowser.show();
// },
// scope: this
//});
},
this.moveLocation = this.form.add({
fieldLabel: _('Location'),
name: 'location',
width: 240
});
//this.form.add({
// xtype: 'button',
// text: _('Browse'),
// handler: function() {
// if (!this.fileBrowser) {
// this.fileBrowser = new Deluge.FileBrowser();
// }
// this.fileBrowser.show();
// },
// scope: this
//});
},
hide: function() {
Deluge.MoveStorage.superclass.hide.call(this);
this.torrentIds = null;
},
hide: function() {
Deluge.MoveStorage.superclass.hide.call(this);
this.torrentIds = null;
},
show: function(torrentIds) {
Deluge.MoveStorage.superclass.show.call(this);
this.torrentIds = torrentIds;
},
show: function(torrentIds) {
Deluge.MoveStorage.superclass.show.call(this);
this.torrentIds = torrentIds;
},
onCancel: function() {
this.hide();
},
onCancel: function() {
this.hide();
},
onMove: function() {
var dest = this.moveLocation.getValue();
deluge.client.core.move_storage(this.torrentIds, dest);
this.hide();
}
onMove: function() {
var dest = this.moveLocation.getValue();
deluge.client.core.move_storage(this.torrentIds, dest);
this.hide();
}
});
deluge.moveStorage = new Deluge.MoveStorage();

View file

@ -38,177 +38,177 @@
*/
Deluge.MultiOptionsManager = Ext.extend(Deluge.OptionsManager, {
constructor: function(config) {
this.currentId = null;
this.stored = {};
Deluge.MultiOptionsManager.superclass.constructor.call(this, config);
},
/**
* Changes bound fields to use the specified id.
* @param {String} id
*/
changeId: function(id, dontUpdateBinds) {
var oldId = this.currentId;
this.currentId = id;
if (!dontUpdateBinds) {
for (var option in this.options) {
if (!this.binds[option]) continue;
Ext.each(this.binds[option], function(bind) {
bind.setValue(this.get(option));
}, this);
}
}
return oldId;
},
constructor: function(config) {
this.currentId = null;
this.stored = {};
Deluge.MultiOptionsManager.superclass.constructor.call(this, config);
},
/**
* Changes bound fields to use the specified id.
* @param {String} id
*/
changeId: function(id, dontUpdateBinds) {
var oldId = this.currentId;
this.currentId = id;
if (!dontUpdateBinds) {
for (var option in this.options) {
if (!this.binds[option]) continue;
Ext.each(this.binds[option], function(bind) {
bind.setValue(this.get(option));
}, this);
}
}
return oldId;
},
/**
* Changes all the changed values to be the default values
* @param {String} id
*/
commit: function() {
this.stored[this.currentId] = Ext.apply(this.stored[this.currentId], this.changed[this.currentId]);
this.reset();
},
/**
* Get the value for an option
* @param {String/Array} option A single option or an array of options to return.
* @returns {Object} the options value.
*/
get: function() {
if (arguments.length == 1) {
var option = arguments[0];
return (this.isDirty(option)) ? this.changed[this.currentId][option] : this.getDefault(option);
} else if (arguments.length == 0) {
var options = {};
for (var option in this.options) {
options[option] = (this.isDirty(option)) ? this.changed[this.currentId][option] : this.getDefault(option);
}
return options;
} else {
var options = {};
Ext.each(arguments, function(option) {
options[option] = (this.isDirty(option)) ? this.changed[this.currentId][option] : this.getDefault(option);
}, this);
return options;
}
},
/**
* Changes all the changed values to be the default values
* @param {String} id
*/
commit: function() {
this.stored[this.currentId] = Ext.apply(this.stored[this.currentId], this.changed[this.currentId]);
this.reset();
},
/**
* Get the value for an option
* @param {String/Array} option A single option or an array of options to return.
* @returns {Object} the options value.
*/
get: function() {
if (arguments.length == 1) {
var option = arguments[0];
return (this.isDirty(option)) ? this.changed[this.currentId][option] : this.getDefault(option);
} else if (arguments.length == 0) {
var options = {};
for (var option in this.options) {
options[option] = (this.isDirty(option)) ? this.changed[this.currentId][option] : this.getDefault(option);
}
return options;
} else {
var options = {};
Ext.each(arguments, function(option) {
options[option] = (this.isDirty(option)) ? this.changed[this.currentId][option] : this.getDefault(option);
}, this);
return options;
}
},
/**
* Get the default value for an option.
* @param {String} option A single option.
* @returns {Object} the value of the option
*/
getDefault: function(option) {
return (this.has(option)) ? this.stored[this.currentId][option] : this.options[option];
},
/**
* Get the default value for an option.
* @param {String} option A single option.
* @returns {Object} the value of the option
*/
getDefault: function(option) {
return (this.has(option)) ? this.stored[this.currentId][option] : this.options[option];
},
/**
* Returns the dirty (changed) values.
* @returns {Object} the changed options
*/
getDirty: function() {
return (this.changed[this.currentId]) ? this.changed[this.currentId] : {};
},
/**
* Returns the dirty (changed) values.
* @returns {Object} the changed options
*/
getDirty: function() {
return (this.changed[this.currentId]) ? this.changed[this.currentId] : {};
},
/**
* Check to see if the option has been changed.
* @param {String} option
* @returns {Boolean} true if the option has been changed, else false.
*/
isDirty: function(option) {
return (this.changed[this.currentId] && !Ext.isEmpty(this.changed[this.currentId][option]));
},
/**
* Check to see if the option has been changed.
* @param {String} option
* @returns {Boolean} true if the option has been changed, else false.
*/
isDirty: function(option) {
return (this.changed[this.currentId] && !Ext.isEmpty(this.changed[this.currentId][option]));
},
/**
* Check to see if an id has had an option set to something other than the
* default value.
* @param {String} option
* @returns {Boolean} true if the id has an option, else false.
*/
has: function(option) {
return (this.stored[this.currentId] && !Ext.isEmpty(this.stored[this.currentId][option]));
},
/**
* Check to see if an id has had an option set to something other than the
* default value.
* @param {String} option
* @returns {Boolean} true if the id has an option, else false.
*/
has: function(option) {
return (this.stored[this.currentId] && !Ext.isEmpty(this.stored[this.currentId][option]));
},
/**
* Reset the options back to the default values for the specified id.
*/
reset: function() {
if (this.changed[this.currentId]) delete this.changed[this.currentId];
if (this.stored[this.currentId]) delete this.stored[this.currentId];
},
/**
* Reset the options back to the default values for the specified id.
*/
reset: function() {
if (this.changed[this.currentId]) delete this.changed[this.currentId];
if (this.stored[this.currentId]) delete this.stored[this.currentId];
},
/**
* Reset the options back to their defaults for all ids.
*/
resetAll: function() {
this.changed = {};
this.stored = {};
this.changeId(null);
},
/**
* Reset the options back to their defaults for all ids.
*/
resetAll: function() {
this.changed = {};
this.stored = {};
this.changeId(null);
},
/**
* Sets the value of specified option for the passed in id.
* @param {String} id
* @param {String} option
* @param {Object} value The value for the option
*/
setDefault: function(option, value) {
if (option === undefined) {
return;
} else if (value === undefined) {
for (var key in option) {
this.setDefault(key, option[key]);
}
} else {
var oldValue = this.getDefault(option);
value = this.convertValueType(oldValue, value);
// If the value is the same as the old value there is
// no point in setting it again.
if (oldValue == value) return;
// Store the new default
if (!this.stored[this.currentId]) this.stored[this.currentId] = {};
this.stored[this.currentId][option] = value;
if (!this.isDirty(option)) {
this.fireEvent('changed', option, value, oldValue);
}
}
},
/**
* Sets the value of specified option for the passed in id.
* @param {String} id
* @param {String} option
* @param {Object} value The value for the option
*/
setDefault: function(option, value) {
if (option === undefined) {
return;
} else if (value === undefined) {
for (var key in option) {
this.setDefault(key, option[key]);
}
} else {
var oldValue = this.getDefault(option);
value = this.convertValueType(oldValue, value);
// If the value is the same as the old value there is
// no point in setting it again.
if (oldValue == value) return;
// Store the new default
if (!this.stored[this.currentId]) this.stored[this.currentId] = {};
this.stored[this.currentId][option] = value;
if (!this.isDirty(option)) {
this.fireEvent('changed', option, value, oldValue);
}
}
},
/**
* Update the value for the specified option and id.
* @param {String} id
* @param {String/Object} option or options to update
* @param {Object} [value];
*/
update: function(option, value) {
if (option === undefined) {
return;
} else if (value === undefined) {
for (var key in option) {
this.update(key, option[key]);
}
} else {
if (!this.changed[this.currentId]) this.changed[this.currentId] = {};
/**
* Update the value for the specified option and id.
* @param {String} id
* @param {String/Object} option or options to update
* @param {Object} [value];
*/
update: function(option, value) {
if (option === undefined) {
return;
} else if (value === undefined) {
for (var key in option) {
this.update(key, option[key]);
}
} else {
if (!this.changed[this.currentId]) this.changed[this.currentId] = {};
var defaultValue = this.getDefault(option);
value = this.convertValueType(defaultValue, value);
var oldValue = this.get(option);
if (oldValue == value) return;
var defaultValue = this.getDefault(option);
value = this.convertValueType(defaultValue, value);
var oldValue = this.get(option);
if (oldValue == value) return;
if (defaultValue == value) {
if (this.isDirty(option)) delete this.changed[this.currentId][option];
this.fireEvent('changed', option, value, oldValue);
return;
} else {
this.changed[this.currentId][option] = value;
this.fireEvent('changed', option, value, oldValue);
}
}
}
if (defaultValue == value) {
if (this.isDirty(option)) delete this.changed[this.currentId][option];
this.fireEvent('changed', option, value, oldValue);
return;
} else {
this.changed[this.currentId][option] = value;
this.fireEvent('changed', option, value, oldValue);
}
}
}
});

View file

@ -40,250 +40,250 @@ Ext.namespace('Deluge');
* @param {Object} config Configuration options
*/
Deluge.OptionsManager = Ext.extend(Ext.util.Observable, {
constructor: function(config) {
config = config || {};
this.binds = {};
this.changed = {};
this.options = (config && config['options']) || {};
this.focused = null;
constructor: function(config) {
config = config || {};
this.binds = {};
this.changed = {};
this.options = (config && config['options']) || {};
this.focused = null;
this.addEvents({
/**
* @event add
* Fires when an option is added
*/
'add': true,
this.addEvents({
/**
* @event add
* Fires when an option is added
*/
'add': true,
/**
* @event changed
* Fires when an option is changed
* @param {String} option The changed option
* @param {Mixed} value The options new value
* @param {Mixed} oldValue The options old value
*/
'changed': true,
/**
* @event changed
* Fires when an option is changed
* @param {String} option The changed option
* @param {Mixed} value The options new value
* @param {Mixed} oldValue The options old value
*/
'changed': true,
/**
* @event reset
* Fires when the options are reset
*/
'reset': true
});
this.on('changed', this.onChange, this);
/**
* @event reset
* Fires when the options are reset
*/
'reset': true
});
this.on('changed', this.onChange, this);
Deluge.OptionsManager.superclass.constructor.call(this);
},
Deluge.OptionsManager.superclass.constructor.call(this);
},
/**
* Add a set of default options and values to the options manager
* @param {Object} options The default options.
*/
addOptions: function(options) {
this.options = Ext.applyIf(this.options, options);
},
/**
* Binds a form field to the specified option.
* @param {String} option
* @param {Ext.form.Field} field
*/
bind: function(option, field) {
this.binds[option] = this.binds[option] || [];
this.binds[option].push(field);
field._doption = option;
/**
* Add a set of default options and values to the options manager
* @param {Object} options The default options.
*/
addOptions: function(options) {
this.options = Ext.applyIf(this.options, options);
},
/**
* Binds a form field to the specified option.
* @param {String} option
* @param {Ext.form.Field} field
*/
bind: function(option, field) {
this.binds[option] = this.binds[option] || [];
this.binds[option].push(field);
field._doption = option;
field.on('focus', this.onFieldFocus, this);
field.on('blur', this.onFieldBlur, this);
field.on('change', this.onFieldChange, this);
field.on('check', this.onFieldChange, this);
field.on('spin', this.onFieldChange, this);
return field;
},
field.on('focus', this.onFieldFocus, this);
field.on('blur', this.onFieldBlur, this);
field.on('change', this.onFieldChange, this);
field.on('check', this.onFieldChange, this);
field.on('spin', this.onFieldChange, this);
return field;
},
/**
* Changes all the changed values to be the default values
*/
commit: function() {
this.options = Ext.apply(this.options, this.changed);
this.reset();
},
/**
* Changes all the changed values to be the default values
*/
commit: function() {
this.options = Ext.apply(this.options, this.changed);
this.reset();
},
/**
* Converts the value so it matches the originals type
* @param {Mixed} oldValue The original value
* @param {Mixed} value The new value to convert
*/
convertValueType: function(oldValue, value) {
if (Ext.type(oldValue) != Ext.type(value)) {
switch (Ext.type(oldValue)) {
case 'string':
value = String(value);
break;
case 'number':
value = Number(value);
break;
case 'boolean':
if (Ext.type(value) == 'string') {
value = value.toLowerCase();
value = (value == 'true' || value == '1' || value == 'on') ? true : false;
} else {
value = Boolean(value);
}
break;
}
}
return value;
},
/**
* Converts the value so it matches the originals type
* @param {Mixed} oldValue The original value
* @param {Mixed} value The new value to convert
*/
convertValueType: function(oldValue, value) {
if (Ext.type(oldValue) != Ext.type(value)) {
switch (Ext.type(oldValue)) {
case 'string':
value = String(value);
break;
case 'number':
value = Number(value);
break;
case 'boolean':
if (Ext.type(value) == 'string') {
value = value.toLowerCase();
value = (value == 'true' || value == '1' || value == 'on') ? true : false;
} else {
value = Boolean(value);
}
break;
}
}
return value;
},
/**
* Get the value for an option or options.
* @param {String} [option] A single option or an array of options to return.
* @returns {Object} the options value.
*/
get: function() {
if (arguments.length == 1) {
var option = arguments[0];
return (this.isDirty(option)) ? this.changed[option] : this.options[option];
} else {
var options = {};
Ext.each(arguments, function(option) {
if (!this.has(option)) return;
options[option] = (this.isDirty(option)) ? this.changed[option] : this.options[option];
}, this);
return options;
}
},
/**
* Get the value for an option or options.
* @param {String} [option] A single option or an array of options to return.
* @returns {Object} the options value.
*/
get: function() {
if (arguments.length == 1) {
var option = arguments[0];
return (this.isDirty(option)) ? this.changed[option] : this.options[option];
} else {
var options = {};
Ext.each(arguments, function(option) {
if (!this.has(option)) return;
options[option] = (this.isDirty(option)) ? this.changed[option] : this.options[option];
}, this);
return options;
}
},
/**
* Get the default value for an option or options.
* @param {String|Array} [option] A single option or an array of options to return.
* @returns {Object} the value of the option
*/
getDefault: function(option) {
return this.options[option];
},
/**
* Get the default value for an option or options.
* @param {String|Array} [option] A single option or an array of options to return.
* @returns {Object} the value of the option
*/
getDefault: function(option) {
return this.options[option];
},
/**
* Returns the dirty (changed) values.
* @returns {Object} the changed options
*/
getDirty: function() {
return this.changed;
},
/**
* Returns the dirty (changed) values.
* @returns {Object} the changed options
*/
getDirty: function() {
return this.changed;
},
/**
* @param {String} [option] The option to check
* @returns {Boolean} true if the option has been changed from the default.
*/
isDirty: function(option) {
return !Ext.isEmpty(this.changed[option]);
},
/**
* @param {String} [option] The option to check
* @returns {Boolean} true if the option has been changed from the default.
*/
isDirty: function(option) {
return !Ext.isEmpty(this.changed[option]);
},
/**
* Check to see if an option exists in the options manager
* @param {String} option
* @returns {Boolean} true if the option exists, else false.
*/
has: function(option) {
return (this.options[option]);
},
/**
* Check to see if an option exists in the options manager
* @param {String} option
* @returns {Boolean} true if the option exists, else false.
*/
has: function(option) {
return (this.options[option]);
},
/**
* Reset the options back to the default values.
*/
reset: function() {
this.changed = {};
},
/**
* Reset the options back to the default values.
*/
reset: function() {
this.changed = {};
},
/**
* Sets the value of specified option(s) for the passed in id.
* @param {String} option
* @param {Object} value The value for the option
*/
set: function(option, value) {
if (option === undefined) {
return;
} else if (typeof option == 'object') {
var options = option;
this.options = Ext.apply(this.options, options);
for (var option in options) {
this.onChange(option, options[option]);
}
} else {
this.options[option] = value;
this.onChange(option, value)
}
},
/**
* Sets the value of specified option(s) for the passed in id.
* @param {String} option
* @param {Object} value The value for the option
*/
set: function(option, value) {
if (option === undefined) {
return;
} else if (typeof option == 'object') {
var options = option;
this.options = Ext.apply(this.options, options);
for (var option in options) {
this.onChange(option, options[option]);
}
} else {
this.options[option] = value;
this.onChange(option, value)
}
},
/**
* Update the value for the specified option and id.
* @param {String/Object} option or options to update
* @param {Object} [value];
*/
update: function(option, value) {
if (option === undefined) {
return;
} else if (value === undefined) {
for (var key in option) {
this.update(key, option[key]);
}
} else {
var defaultValue = this.getDefault(option);
value = this.convertValueType(defaultValue, value);
/**
* Update the value for the specified option and id.
* @param {String/Object} option or options to update
* @param {Object} [value];
*/
update: function(option, value) {
if (option === undefined) {
return;
} else if (value === undefined) {
for (var key in option) {
this.update(key, option[key]);
}
} else {
var defaultValue = this.getDefault(option);
value = this.convertValueType(defaultValue, value);
var oldValue = this.get(option);
if (oldValue == value) return;
var oldValue = this.get(option);
if (oldValue == value) return;
if (defaultValue == value) {
if (this.isDirty(option)) delete this.changed[option];
this.fireEvent('changed', option, value, oldValue);
return;
}
if (defaultValue == value) {
if (this.isDirty(option)) delete this.changed[option];
this.fireEvent('changed', option, value, oldValue);
return;
}
this.changed[option] = value;
this.fireEvent('changed', option, value, oldValue);
}
},
this.changed[option] = value;
this.fireEvent('changed', option, value, oldValue);
}
},
/**
* Lets the option manager know when a field is blurred so if a value
* so value changing operations can continue on that field.
*/
onFieldBlur: function(field, event) {
if (this.focused == field) {
this.focused = null;
}
},
/**
* Lets the option manager know when a field is blurred so if a value
* so value changing operations can continue on that field.
*/
onFieldBlur: function(field, event) {
if (this.focused == field) {
this.focused = null;
}
},
/**
* Stops a form fields value from being blocked by the change functions
* @param {Ext.form.Field} field
* @private
*/
onFieldChange: function(field, event) {
if (field.field) field = field.field // fix for spinners
this.update(field._doption, field.getValue());
},
/**
* Stops a form fields value from being blocked by the change functions
* @param {Ext.form.Field} field
* @private
*/
onFieldChange: function(field, event) {
if (field.field) field = field.field // fix for spinners
this.update(field._doption, field.getValue());
},
/**
* Lets the option manager know when a field is focused so if a value
* changing operation is performed it won't change the value of the
* field.
*/
onFieldFocus: function(field, event) {
this.focused = field;
},
/**
* Lets the option manager know when a field is focused so if a value
* changing operation is performed it won't change the value of the
* field.
*/
onFieldFocus: function(field, event) {
this.focused = field;
},
onChange: function(option, newValue, oldValue) {
// If we don't have a bind there's nothing to do.
if (Ext.isEmpty(this.binds[option])) return;
Ext.each(this.binds[option], function(bind) {
// The field is currently focused so we don't want to
// change it.
if (bind == this.focused) return;
// Set the form field to the new value.
bind.setValue(newValue);
}, this);
}
onChange: function(option, newValue, oldValue) {
// If we don't have a bind there's nothing to do.
if (Ext.isEmpty(this.binds[option])) return;
Ext.each(this.binds[option], function(bind) {
// The field is currently focused so we don't want to
// change it.
if (bind == this.focused) return;
// Set the form field to the new value.
bind.setValue(newValue);
}, this);
}
});

View file

@ -36,65 +36,65 @@ Ext.ns('Deluge');
* @extends Ext.Window
*/
Deluge.OtherLimitWindow = Ext.extend(Ext.Window, {
layout: 'fit',
width: 210,
height: 100,
layout: 'fit',
width: 210,
height: 100,
closeAction: 'hide',
closeAction: 'hide',
initComponent: function() {
Deluge.OtherLimitWindow.superclass.initComponent.call(this);
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
bodyStyle: 'padding: 5px',
layout: 'hbox',
layoutConfig: {
pack: 'start'
},
items: [{
xtype: 'spinnerfield',
name: 'limit'
}]
});
if (this.initialConfig.unit) {
this.form.add({
border: false,
baseCls: 'x-plain',
bodyStyle: 'padding: 5px',
html: this.initialConfig.unit
});
} else {
this.setSize(180, 100);
}
initComponent: function() {
Deluge.OtherLimitWindow.superclass.initComponent.call(this);
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
bodyStyle: 'padding: 5px',
layout: 'hbox',
layoutConfig: {
pack: 'start'
},
items: [{
xtype: 'spinnerfield',
name: 'limit'
}]
});
if (this.initialConfig.unit) {
this.form.add({
border: false,
baseCls: 'x-plain',
bodyStyle: 'padding: 5px',
html: this.initialConfig.unit
});
} else {
this.setSize(180, 100);
}
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Ok'), this.onOkClick, this);
this.afterMethod('show', this.doFocusField, this);
},
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Ok'), this.onOkClick, this);
this.afterMethod('show', this.doFocusField, this);
},
setValue: function(value) {
this.form.getForm().setValues({limit: value});
},
setValue: function(value) {
this.form.getForm().setValues({limit: value});
},
onCancelClick: function() {
this.form.getForm().reset();
this.hide();
},
onCancelClick: function() {
this.form.getForm().reset();
this.hide();
},
onOkClick: function() {
var config = {};
config[this.group] = this.form.getForm().getValues().limit;
deluge.client.core.set_config(config, {
success: function() {
deluge.ui.update();
}
});
this.hide();
},
onOkClick: function() {
var config = {};
config[this.group] = this.form.getForm().getValues().limit;
deluge.client.core.set_config(config, {
success: function() {
deluge.ui.update();
}
});
this.hide();
},
doFocusField: function() {
this.form.getForm().findField('limit').focus(true, 10);
}
doFocusField: function() {
this.form.getForm().findField('limit').focus(true, 10);
}
});

View file

@ -37,91 +37,91 @@ Ext.ns('Deluge');
*/
Deluge.Plugin = Ext.extend(Ext.util.Observable, {
/**
* The plugins name
* @property name
* @type {String}
*/
name: null,
/**
* The plugins name
* @property name
* @type {String}
*/
name: null,
constructor: function(config) {
this.isDelugePlugin = true;
this.addEvents({
/**
* @event enabled
* @param {Plugin} plugin the plugin instance
*/
"enabled": true,
constructor: function(config) {
this.isDelugePlugin = true;
this.addEvents({
/**
* @event enabled
* @param {Plugin} plugin the plugin instance
*/
"enabled": true,
/**
* @event disabled
* @param {Plugin} plugin the plugin instance
*/
"disabled": true
});
Deluge.Plugin.superclass.constructor.call(this, config);
},
/**
* Disables the plugin, firing the "{@link #disabled}" event and
* then executing the plugins clean up method onDisabled.
*/
disable: function() {
this.fireEvent("disabled", this);
if (this.onDisable) this.onDisable();
},
/**
* Enables the plugin, firing the "{@link #enabled}" event and
* then executes the plugins setup method, onEnabled.
*/
enable: function() {
this.fireEvent("enable", this);
if (this.onEnable) this.onEnable();
},
/**
* @event disabled
* @param {Plugin} plugin the plugin instance
*/
"disabled": true
});
Deluge.Plugin.superclass.constructor.call(this, config);
},
/**
* Disables the plugin, firing the "{@link #disabled}" event and
* then executing the plugins clean up method onDisabled.
*/
disable: function() {
this.fireEvent("disabled", this);
if (this.onDisable) this.onDisable();
},
/**
* Enables the plugin, firing the "{@link #enabled}" event and
* then executes the plugins setup method, onEnabled.
*/
enable: function() {
this.fireEvent("enable", this);
if (this.onEnable) this.onEnable();
},
registerTorrentStatus: function(key, header, options) {
options = options || {};
var cc = options.colCfg || {}, sc = options.storeCfg || {};
sc = Ext.apply(sc, {name: key});
deluge.torrents.meta.fields.push(sc);
deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
registerTorrentStatus: function(key, header, options) {
options = options || {};
var cc = options.colCfg || {}, sc = options.storeCfg || {};
sc = Ext.apply(sc, {name: key});
deluge.torrents.meta.fields.push(sc);
deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
cc = Ext.apply(cc, {
header: header,
dataIndex: key
});
var cols = deluge.torrents.columns.slice(0);
cols.push(cc);
deluge.torrents.colModel.setConfig(cols);
deluge.torrents.columns = cols;
cc = Ext.apply(cc, {
header: header,
dataIndex: key
});
var cols = deluge.torrents.columns.slice(0);
cols.push(cc);
deluge.torrents.colModel.setConfig(cols);
deluge.torrents.columns = cols;
Deluge.Keys.Grid.push(key);
deluge.torrents.getView().refresh(true);
},
Deluge.Keys.Grid.push(key);
deluge.torrents.getView().refresh(true);
},
deregisterTorrentStatus: function(key) {
var fields = [];
Ext.each(deluge.torrents.meta.fields, function(field) {
if (field.name != key) fields.push(field);
});
deluge.torrents.meta.fields = fields;
deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
deregisterTorrentStatus: function(key) {
var fields = [];
Ext.each(deluge.torrents.meta.fields, function(field) {
if (field.name != key) fields.push(field);
});
deluge.torrents.meta.fields = fields;
deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
var cols = [];
Ext.each(deluge.torrents.columns, function(col) {
if (col.dataIndex != key) cols.push(col);
});
deluge.torrents.colModel.setConfig(cols);
deluge.torrents.columns = cols;
var cols = [];
Ext.each(deluge.torrents.columns, function(col) {
if (col.dataIndex != key) cols.push(col);
});
deluge.torrents.colModel.setConfig(cols);
deluge.torrents.columns = cols;
var keys = [];
Ext.each(Deluge.Keys.Grid, function(k) {
if (k == key) keys.push(k);
});
Deluge.Keys.Grid = keys;
deluge.torrents.getView().refresh(true);
}
var keys = [];
Ext.each(Deluge.Keys.Grid, function(k) {
if (k == key) keys.push(k);
});
Deluge.Keys.Grid = keys;
deluge.torrents.getView().refresh(true);
}
});
Ext.ns('Deluge.plugins');

View file

@ -39,7 +39,7 @@ Deluge.RemoveWindow = Ext.extend(Ext.Window, {
title: _('Remove Torrent'),
layout: 'fit',
width: 350,
height: 100,
height: 100,
buttonAlign: 'right',
closeAction: 'hide',
@ -49,50 +49,50 @@ Deluge.RemoveWindow = Ext.extend(Ext.Window, {
bodyStyle: 'padding: 5px; padding-left: 10px;',
html: 'Are you sure you wish to remove the torrent (s)?',
initComponent: function() {
Deluge.RemoveWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancel, this);
this.addButton(_('Remove With Data'), this.onRemoveData, this);
this.addButton(_('Remove Torrent'), this.onRemove, this);
},
remove: function(removeData) {
Ext.each(this.torrentIds, function(torrentId) {
deluge.client.core.remove_torrent(torrentId, removeData, {
success: function() {
this.onRemoved(torrentId);
},
scope: this,
torrentId: torrentId
});
}, this);
},
show: function(ids) {
Deluge.RemoveWindow.superclass.show.call(this);
this.torrentIds = ids;
},
onCancel: function() {
this.hide();
this.torrentIds = null;
},
onRemove: function() {
this.remove(false);
},
onRemoveData: function() {
this.remove(true);
},
onRemoved: function(torrentId) {
deluge.events.fire('torrentRemoved', torrentId);
this.hide();
deluge.ui.update();
}
initComponent: function() {
Deluge.RemoveWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancel, this);
this.addButton(_('Remove With Data'), this.onRemoveData, this);
this.addButton(_('Remove Torrent'), this.onRemove, this);
},
remove: function(removeData) {
Ext.each(this.torrentIds, function(torrentId) {
deluge.client.core.remove_torrent(torrentId, removeData, {
success: function() {
this.onRemoved(torrentId);
},
scope: this,
torrentId: torrentId
});
}, this);
},
show: function(ids) {
Deluge.RemoveWindow.superclass.show.call(this);
this.torrentIds = ids;
},
onCancel: function() {
this.hide();
this.torrentIds = null;
},
onRemove: function() {
this.remove(false);
},
onRemoveData: function() {
this.remove(true);
},
onRemoved: function(torrentId) {
deluge.events.fire('torrentRemoved', torrentId);
this.hide();
deluge.ui.update();
}
});
deluge.removeWindow = new Deluge.RemoveWindow();

View file

@ -41,122 +41,122 @@
*/
Deluge.Sidebar = Ext.extend(Ext.Panel, {
// private
panels: {},
// private
panels: {},
// private
selected: null,
// private
selected: null,
constructor: function(config) {
config = Ext.apply({
id: 'sidebar',
region: 'west',
cls: 'deluge-sidebar',
title: _('Filters'),
layout: 'accordion',
split: true,
width: 200,
minSize: 175,
collapsible: true,
margins: '5 0 0 5',
cmargins: '5 0 0 5'
}, config);
Deluge.Sidebar.superclass.constructor.call(this, config);
},
constructor: function(config) {
config = Ext.apply({
id: 'sidebar',
region: 'west',
cls: 'deluge-sidebar',
title: _('Filters'),
layout: 'accordion',
split: true,
width: 200,
minSize: 175,
collapsible: true,
margins: '5 0 0 5',
cmargins: '5 0 0 5'
}, config);
Deluge.Sidebar.superclass.constructor.call(this, config);
},
// private
initComponent: function() {
Deluge.Sidebar.superclass.initComponent.call(this);
deluge.events.on("disconnect", this.onDisconnect, this);
},
// private
initComponent: function() {
Deluge.Sidebar.superclass.initComponent.call(this);
deluge.events.on("disconnect", this.onDisconnect, this);
},
createFilter: function(filter, states) {
var panel = new Deluge.FilterPanel({
filter: filter
});
panel.on('selectionchange', function(view, nodes) {
deluge.ui.update();
});
this.add(panel);
this.doLayout();
this.panels[filter] = panel;
createFilter: function(filter, states) {
var panel = new Deluge.FilterPanel({
filter: filter
});
panel.on('selectionchange', function(view, nodes) {
deluge.ui.update();
});
this.add(panel);
this.doLayout();
this.panels[filter] = panel;
panel.header.on('click', function(header) {
if (!deluge.config.sidebar_multiple_filters) {
deluge.ui.update();
}
if (!panel.list.getSelectionCount()) {
panel.list.select(0);
}
});
this.fireEvent('filtercreate', this, panel);
panel.header.on('click', function(header) {
if (!deluge.config.sidebar_multiple_filters) {
deluge.ui.update();
}
if (!panel.list.getSelectionCount()) {
panel.list.select(0);
}
});
this.fireEvent('filtercreate', this, panel);
panel.updateStates(states);
this.fireEvent('afterfiltercreate', this, panel);
},
panel.updateStates(states);
this.fireEvent('afterfiltercreate', this, panel);
},
getFilter: function(filter) {
return this.panels[filter];
},
getFilter: function(filter) {
return this.panels[filter];
},
getFilterStates: function() {
var states = {}
getFilterStates: function() {
var states = {}
if (deluge.config.sidebar_multiple_filters) {
// Grab the filters from each of the filter panels
this.items.each(function(panel) {
var state = panel.getState();
if (state == null) return;
states[panel.filterType] = state;
}, this);
} else {
var panel = this.getLayout().activeItem;
if (panel) {
var state = panel.getState();
if (!state == null) return;
states[panel.filterType] = state;
}
}
if (deluge.config.sidebar_multiple_filters) {
// Grab the filters from each of the filter panels
this.items.each(function(panel) {
var state = panel.getState();
if (state == null) return;
states[panel.filterType] = state;
}, this);
} else {
var panel = this.getLayout().activeItem;
if (panel) {
var state = panel.getState();
if (!state == null) return;
states[panel.filterType] = state;
}
}
return states;
},
return states;
},
hasFilter: function(filter) {
return (this.panels[filter]) ? true : false;
},
hasFilter: function(filter) {
return (this.panels[filter]) ? true : false;
},
// private
onDisconnect: function() {
for (var filter in this.panels) {
this.remove(this.panels[filter]);
}
this.panels = {};
this.selected = null;
},
// private
onDisconnect: function() {
for (var filter in this.panels) {
this.remove(this.panels[filter]);
}
this.panels = {};
this.selected = null;
},
onFilterSelect: function(selModel, rowIndex, record) {
deluge.ui.update();
},
onFilterSelect: function(selModel, rowIndex, record) {
deluge.ui.update();
},
update: function(filters) {
for (var filter in filters) {
var states = filters[filter];
if (Ext.getKeys(this.panels).indexOf(filter) > -1) {
this.panels[filter].updateStates(states);
} else {
this.createFilter(filter, states);
}
}
update: function(filters) {
for (var filter in filters) {
var states = filters[filter];
if (Ext.getKeys(this.panels).indexOf(filter) > -1) {
this.panels[filter].updateStates(states);
} else {
this.createFilter(filter, states);
}
}
// Perform a cleanup of fitlers that aren't enabled any more
Ext.each(Ext.keys(this.panels), function(filter) {
if (Ext.keys(filters).indexOf(filter) == -1) {
// We need to remove the panel
this.remove(this.panels[filter]);
this.doLayout();
delete this.panels[filter];
}
}, this);
}
// Perform a cleanup of fitlers that aren't enabled any more
Ext.each(Ext.keys(this.panels), function(filter) {
if (Ext.keys(filters).indexOf(filter) == -1) {
// We need to remove the panel
this.remove(this.panels[filter]);
this.doLayout();
delete this.panels[filter];
}
}, this);
}
});

View file

@ -32,284 +32,284 @@
Ext.namespace('Deluge');
Deluge.Statusbar = Ext.extend(Ext.ux.StatusBar, {
constructor: function(config) {
config = Ext.apply({
id: 'deluge-statusbar',
defaultIconCls: 'x-deluge-statusbar x-not-connected',
defaultText: _('Not Connected')
}, config);
Deluge.Statusbar.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.Statusbar.superclass.initComponent.call(this);
deluge.events.on('connect', this.onConnect, this);
deluge.events.on('disconnect', this.onDisconnect, this);
},
createButtons: function() {
this.buttons = this.add({
id: 'statusbar-connections',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-connections',
tooltip: _('Connections'),
menu: new Deluge.StatusbarMenu({
items: [{
text: '50',
value: '50',
group: 'max_connections_global',
checked: false
},{
text: '100',
value: '100',
group: 'max_connections_global',
checked: false
},{
text: '200',
value: '200',
group: 'max_connections_global',
checked: false
},{
text: '300',
value: '300',
group: 'max_connections_global',
checked: false
},{
text: '500',
value: '500',
group: 'max_connections_global',
checked: false
},{
text: _('Unlimited'),
value: '-1',
group: 'max_connections_global',
checked: false
},'-',{
text: _('Other'),
value: 'other',
group: 'max_connections_global',
checked: false
}],
otherWin: {
title: _('Set Maximum Connections')
}
})
}, '-', {
id: 'statusbar-downspeed',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-downloading',
tooltip: _('Download Speed'),
menu: new Deluge.StatusbarMenu({
items: [{
value: '5',
text: '5 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '10',
text: '10 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '30',
text: '30 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '80',
text: '80 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '300',
text: '300 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '-1',
text: _('Unlimited'),
group: 'max_download_speed',
checked: false
},'-',{
value: 'other',
text: _('Other'),
group: 'max_download_speed',
checked: false
}],
otherWin: {
title: _('Set Maximum Download Speed'),
unit: _('Kib/s')
}
})
}, '-', {
id: 'statusbar-upspeed',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-seeding',
tooltip: _('Upload Speed'),
menu: new Deluge.StatusbarMenu({
items: [{
value: '5',
text: '5 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '10',
text: '10 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '30',
text: '30 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '80',
text: '80 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '300',
text: '300 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '-1',
text: _('Unlimited'),
group: 'max_upload_speed',
checked: false
},'-',{
value: 'other',
text: _('Other'),
group: 'max_upload_speed',
checked: false
}],
otherWin: {
title: _('Set Maximum Upload Speed'),
unit: _('Kib/s')
}
})
}, '-', {
id: 'statusbar-traffic',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-traffic',
tooltip: _('Protocol Traffic Download/Upload'),
handler: function() {
deluge.preferences.show();
deluge.preferences.selectPage('Network');
}
}, '-', {
id: 'statusbar-dht',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-dht',
tooltip: _('DHT Nodes')
}, '-', {
id: 'statusbar-freespace',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-freespace',
tooltip: _('Freespace in download location'),
handler: function() {
deluge.preferences.show();
deluge.preferences.selectPage('Downloads');
}
});
this.created = true;
},
onConnect: function() {
this.setStatus({
iconCls: 'x-connected',
text: ''
});
if (!this.created) {
this.createButtons();
} else {
Ext.each(this.buttons, function(item) {
item.show();
item.enable();
});
}
this.doLayout();
},
constructor: function(config) {
config = Ext.apply({
id: 'deluge-statusbar',
defaultIconCls: 'x-deluge-statusbar x-not-connected',
defaultText: _('Not Connected')
}, config);
Deluge.Statusbar.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.Statusbar.superclass.initComponent.call(this);
deluge.events.on('connect', this.onConnect, this);
deluge.events.on('disconnect', this.onDisconnect, this);
},
createButtons: function() {
this.buttons = this.add({
id: 'statusbar-connections',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-connections',
tooltip: _('Connections'),
menu: new Deluge.StatusbarMenu({
items: [{
text: '50',
value: '50',
group: 'max_connections_global',
checked: false
},{
text: '100',
value: '100',
group: 'max_connections_global',
checked: false
},{
text: '200',
value: '200',
group: 'max_connections_global',
checked: false
},{
text: '300',
value: '300',
group: 'max_connections_global',
checked: false
},{
text: '500',
value: '500',
group: 'max_connections_global',
checked: false
},{
text: _('Unlimited'),
value: '-1',
group: 'max_connections_global',
checked: false
},'-',{
text: _('Other'),
value: 'other',
group: 'max_connections_global',
checked: false
}],
otherWin: {
title: _('Set Maximum Connections')
}
})
}, '-', {
id: 'statusbar-downspeed',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-downloading',
tooltip: _('Download Speed'),
menu: new Deluge.StatusbarMenu({
items: [{
value: '5',
text: '5 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '10',
text: '10 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '30',
text: '30 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '80',
text: '80 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '300',
text: '300 KiB/s',
group: 'max_download_speed',
checked: false
},{
value: '-1',
text: _('Unlimited'),
group: 'max_download_speed',
checked: false
},'-',{
value: 'other',
text: _('Other'),
group: 'max_download_speed',
checked: false
}],
otherWin: {
title: _('Set Maximum Download Speed'),
unit: _('Kib/s')
}
})
}, '-', {
id: 'statusbar-upspeed',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-seeding',
tooltip: _('Upload Speed'),
menu: new Deluge.StatusbarMenu({
items: [{
value: '5',
text: '5 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '10',
text: '10 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '30',
text: '30 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '80',
text: '80 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '300',
text: '300 KiB/s',
group: 'max_upload_speed',
checked: false
},{
value: '-1',
text: _('Unlimited'),
group: 'max_upload_speed',
checked: false
},'-',{
value: 'other',
text: _('Other'),
group: 'max_upload_speed',
checked: false
}],
otherWin: {
title: _('Set Maximum Upload Speed'),
unit: _('Kib/s')
}
})
}, '-', {
id: 'statusbar-traffic',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-traffic',
tooltip: _('Protocol Traffic Download/Upload'),
handler: function() {
deluge.preferences.show();
deluge.preferences.selectPage('Network');
}
}, '-', {
id: 'statusbar-dht',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-dht',
tooltip: _('DHT Nodes')
}, '-', {
id: 'statusbar-freespace',
text: ' ',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-freespace',
tooltip: _('Freespace in download location'),
handler: function() {
deluge.preferences.show();
deluge.preferences.selectPage('Downloads');
}
});
this.created = true;
},
onConnect: function() {
this.setStatus({
iconCls: 'x-connected',
text: ''
});
if (!this.created) {
this.createButtons();
} else {
Ext.each(this.buttons, function(item) {
item.show();
item.enable();
});
}
this.doLayout();
},
onDisconnect: function() {
this.clearStatus({useDefaults:true});
Ext.each(this.buttons, function(item) {
item.hide();
item.disable();
});
this.doLayout();
},
update: function(stats) {
if (!stats) return;
function addSpeed(val) {return val + ' KiB/s'}
var updateStat = function(name, config) {
var item = this.items.get('statusbar-' + name);
if (config.limit.value > 0) {
var value = (config.value.formatter) ? config.value.formatter(config.value.value, true) : config.value.value;
var limit = (config.limit.formatter) ? config.limit.formatter(config.limit.value, true) : config.limit.value;
var str = String.format(config.format, value, limit);
} else {
var str = (config.value.formatter) ? config.value.formatter(config.value.value, true) : config.value.value;
}
item.setText(str);
onDisconnect: function() {
this.clearStatus({useDefaults:true});
Ext.each(this.buttons, function(item) {
item.hide();
item.disable();
});
this.doLayout();
},
update: function(stats) {
if (!stats) return;
function addSpeed(val) {return val + ' KiB/s'}
var updateStat = function(name, config) {
var item = this.items.get('statusbar-' + name);
if (config.limit.value > 0) {
var value = (config.value.formatter) ? config.value.formatter(config.value.value, true) : config.value.value;
var limit = (config.limit.formatter) ? config.limit.formatter(config.limit.value, true) : config.limit.value;
var str = String.format(config.format, value, limit);
} else {
var str = (config.value.formatter) ? config.value.formatter(config.value.value, true) : config.value.value;
}
item.setText(str);
if (!item.menu) return;
item.menu.setValue(config.limit.value);
}.createDelegate(this);
updateStat('connections', {
value: {value: stats.num_connections},
limit: {value: stats.max_num_connections},
format: '{0} ({1})'
});
if (!item.menu) return;
item.menu.setValue(config.limit.value);
}.createDelegate(this);
updateStat('connections', {
value: {value: stats.num_connections},
limit: {value: stats.max_num_connections},
format: '{0} ({1})'
});
updateStat('downspeed', {
value: {
value: stats.download_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_download,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('downspeed', {
value: {
value: stats.download_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_download,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('upspeed', {
value: {
value: stats.upload_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_upload,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('upspeed', {
value: {
value: stats.upload_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_upload,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('traffic', {
value: {
value: stats.download_protocol_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.upload_protocol_rate,
formatter: Deluge.Formatters.speed
},
format: '{0}/{1}'
});
updateStat('traffic', {
value: {
value: stats.download_protocol_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.upload_protocol_rate,
formatter: Deluge.Formatters.speed
},
format: '{0}/{1}'
});
this.items.get('statusbar-dht').setText(stats.dht_nodes);
this.items.get('statusbar-freespace').setText(fsize(stats.free_space));
}
this.items.get('statusbar-dht').setText(stats.dht_nodes);
this.items.get('statusbar-freespace').setText(fsize(stats.free_space));
}
});

View file

@ -37,20 +37,20 @@ Ext.ns('Deluge');
* @extends Ext.menu.Menu
*/
Deluge.StatusbarMenu = Ext.extend(Ext.menu.Menu, {
initComponent: function() {
Deluge.StatusbarMenu.superclass.initComponent.call(this);
this.otherWin = new Deluge.OtherLimitWindow(this.initialConfig.otherWin || {});
initComponent: function() {
Deluge.StatusbarMenu.superclass.initComponent.call(this);
this.otherWin = new Deluge.OtherLimitWindow(this.initialConfig.otherWin || {});
this.items.each(function(item) {
if (item.getXType() != 'menucheckitem') return;
if (item.value == 'other') {
item.on('click', this.onOtherClicked, this);
} else {
item.on('checkchange', this.onLimitChanged, this);
}
}, this);
},
this.items.each(function(item) {
if (item.getXType() != 'menucheckitem') return;
if (item.value == 'other') {
item.on('click', this.onOtherClicked, this);
} else {
item.on('checkchange', this.onLimitChanged, this);
}
}, this);
},
setValue: function(value) {
var beenSet = false;
@ -81,20 +81,20 @@ Deluge.StatusbarMenu = Ext.extend(Ext.menu.Menu, {
other.resumeEvents();
},
onLimitChanged: function(item, checked) {
if (!checked || item.value == 'other') return; // we don't care about unchecks or other
var config = {}
config[item.group] = item.value
deluge.client.core.set_config(config, {
success: function() {
deluge.ui.update();
}
});
},
onLimitChanged: function(item, checked) {
if (!checked || item.value == 'other') return; // we don't care about unchecks or other
var config = {}
config[item.group] = item.value
deluge.client.core.set_config(config, {
success: function() {
deluge.ui.update();
}
});
},
onOtherClicked: function(item, e) {
this.otherWin.group = item.group;
this.otherWin.setValue(this.value);
this.otherWin.show();
}
onOtherClicked: function(item, e) {
this.otherWin.group = item.group;
this.otherWin.setValue(this.value);
this.otherWin.show();
}
});

View file

@ -36,157 +36,157 @@
* @extends Ext.Toolbar
*/
Deluge.Toolbar = Ext.extend(Ext.Toolbar, {
constructor: function(config) {
config = Ext.apply({
items: [
{
id: 'create',
disabled: true,
text: _('Create'),
iconCls: 'icon-create',
handler: this.onTorrentAction
},{
id: 'add',
disabled: true,
text: _('Add'),
iconCls: 'icon-add',
handler: this.onTorrentAdd
},{
id: 'remove',
disabled: true,
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onTorrentAction
},'|',{
id: 'pause',
disabled: true,
text: _('Pause'),
iconCls: 'icon-pause',
handler: this.onTorrentAction
},{
id: 'resume',
disabled: true,
text: _('Resume'),
iconCls: 'icon-resume',
handler: this.onTorrentAction
},'|',{
id: 'up',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Up'),
iconCls: 'icon-up',
handler: this.onTorrentAction
},{
id: 'down',
disabled: true,
text: _('Down'),
iconCls: 'icon-down',
handler: this.onTorrentAction
},'|',{
id: 'preferences',
text: _('Preferences'),
iconCls: 'x-deluge-preferences',
handler: this.onPreferencesClick,
scope: this
},{
id: 'connectionman',
text: _('Connection Manager'),
iconCls: 'x-deluge-connection-manager',
handler: this.onConnectionManagerClick,
scope: this
},'->',{
id: 'help',
iconCls: 'icon-help',
text: _('Help'),
handler: this.onHelpClick,
scope: this
},{
id: 'logout',
iconCls: 'icon-logout',
disabled: true,
text: _('Logout'),
handler: this.onLogout,
scope: this
}
]
}, config);
Deluge.Toolbar.superclass.constructor.call(this, config);
},
constructor: function(config) {
config = Ext.apply({
items: [
{
id: 'create',
disabled: true,
text: _('Create'),
iconCls: 'icon-create',
handler: this.onTorrentAction
},{
id: 'add',
disabled: true,
text: _('Add'),
iconCls: 'icon-add',
handler: this.onTorrentAdd
},{
id: 'remove',
disabled: true,
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onTorrentAction
},'|',{
id: 'pause',
disabled: true,
text: _('Pause'),
iconCls: 'icon-pause',
handler: this.onTorrentAction
},{
id: 'resume',
disabled: true,
text: _('Resume'),
iconCls: 'icon-resume',
handler: this.onTorrentAction
},'|',{
id: 'up',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Up'),
iconCls: 'icon-up',
handler: this.onTorrentAction
},{
id: 'down',
disabled: true,
text: _('Down'),
iconCls: 'icon-down',
handler: this.onTorrentAction
},'|',{
id: 'preferences',
text: _('Preferences'),
iconCls: 'x-deluge-preferences',
handler: this.onPreferencesClick,
scope: this
},{
id: 'connectionman',
text: _('Connection Manager'),
iconCls: 'x-deluge-connection-manager',
handler: this.onConnectionManagerClick,
scope: this
},'->',{
id: 'help',
iconCls: 'icon-help',
text: _('Help'),
handler: this.onHelpClick,
scope: this
},{
id: 'logout',
iconCls: 'icon-logout',
disabled: true,
text: _('Logout'),
handler: this.onLogout,
scope: this
}
]
}, config);
Deluge.Toolbar.superclass.constructor.call(this, config);
},
connectedButtons: [
'add', 'remove', 'pause', 'resume', 'up', 'down'
],
initComponent: function() {
Deluge.Toolbar.superclass.initComponent.call(this);
deluge.events.on('connect', this.onConnect, this);
deluge.events.on('login', this.onLogin, this);
},
onConnect: function() {
Ext.each(this.connectedButtons, function(buttonId) {
this.items.get(buttonId).enable();
}, this);
},
onDisconnect: function() {
Ext.each(this.connectedButtons, function(buttonId) {
this.items.get(buttonId).disable();
}, this);
},
onLogin: function() {
this.items.get('logout').enable();
},
onLogout: function() {
this.items.get('logout').disable();
deluge.login.logout();
},
onConnectionManagerClick: function() {
deluge.connectionManager.show();
},
onHelpClick: function() {
window.open('http://dev.deluge-torrent.org/wiki/UserGuide');
},
onPreferencesClick: function() {
deluge.preferences.show();
},
onTorrentAction: function(item) {
var selection = deluge.torrents.getSelections();
var ids = [];
Ext.each(selection, function(record) {
ids.push(record.id);
});
switch (item.id) {
case 'remove':
deluge.removeWindow.show(ids);
break;
case 'pause':
case 'resume':
deluge.client.core[item.id + '_torrent'](ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'up':
case 'down':
deluge.client.core['queue_' + item.id](ids, {
success: function() {
deluge.ui.update();
}
});
break;
}
},
onTorrentAdd: function() {
deluge.add.show();
}
connectedButtons: [
'add', 'remove', 'pause', 'resume', 'up', 'down'
],
initComponent: function() {
Deluge.Toolbar.superclass.initComponent.call(this);
deluge.events.on('connect', this.onConnect, this);
deluge.events.on('login', this.onLogin, this);
},
onConnect: function() {
Ext.each(this.connectedButtons, function(buttonId) {
this.items.get(buttonId).enable();
}, this);
},
onDisconnect: function() {
Ext.each(this.connectedButtons, function(buttonId) {
this.items.get(buttonId).disable();
}, this);
},
onLogin: function() {
this.items.get('logout').enable();
},
onLogout: function() {
this.items.get('logout').disable();
deluge.login.logout();
},
onConnectionManagerClick: function() {
deluge.connectionManager.show();
},
onHelpClick: function() {
window.open('http://dev.deluge-torrent.org/wiki/UserGuide');
},
onPreferencesClick: function() {
deluge.preferences.show();
},
onTorrentAction: function(item) {
var selection = deluge.torrents.getSelections();
var ids = [];
Ext.each(selection, function(record) {
ids.push(record.id);
});
switch (item.id) {
case 'remove':
deluge.removeWindow.show(ids);
break;
case 'pause':
case 'resume':
deluge.client.core[item.id + '_torrent'](ids, {
success: function() {
deluge.ui.update();
}
});
break;
case 'up':
case 'down':
deluge.client.core['queue_' + item.id](ids, {
success: function() {
deluge.ui.update();
}
});
break;
}
},
onTorrentAdd: function() {
deluge.add.show();
}
});

View file

@ -1,6 +1,6 @@
/*!
* Deluge.TorrentGrid.js
*
*
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@ -32,323 +32,347 @@
(function() {
/* Renderers for the Torrent Grid */
function queueRenderer(value) {
return (value == -1) ? '' : value + 1;
}
function torrentNameRenderer(value, p, r) {
return String.format('<div class="torrent-name x-deluge-{0}">{1}</div>', r.data['state'].toLowerCase(), value);
}
function torrentSpeedRenderer(value) {
if (!value) return;
return fspeed(value);
}
function torrentProgressRenderer(value, p, r) {
value = new Number(value);
var progress = value;
var text = r.data['state'] + ' ' + value.toFixed(2) + '%';
var width = new Number(this.style.match(/\w+:\s*(\d+)\w+/)[1]);
return Deluge.progressBar(value, width - 8, text);
}
function seedsRenderer(value, p, r) {
if (r.data['total_seeds'] > -1) {
return String.format('{0} ({1})', value, r.data['total_seeds']);
} else {
return value;
}
}
function peersRenderer(value, p, r) {
if (r.data['total_peers'] > -1) {
return String.format('{0} ({1})', value, r.data['total_peers']);
} else {
return value;
}
}
function availRenderer(value, p, r) {
return (value < 0) ? '&infin;' : new Number(value).toFixed(3);
}
function trackerRenderer(value, p, r) {
return String.format('<div style="background: url(' + deluge.config.base + 'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>', value);
}
function etaSorter(eta) {
return eta * -1;
}
/* Renderers for the Torrent Grid */
function queueRenderer(value) {
return (value == -1) ? '' : value + 1;
}
function torrentNameRenderer(value, p, r) {
return String.format('<div class="torrent-name x-deluge-{0}">{1}</div>', r.data['state'].toLowerCase(), value);
}
function torrentSpeedRenderer(value) {
if (!value) return;
return fspeed(value);
}
function torrentProgressRenderer(value, p, r) {
value = new Number(value);
var progress = value;
var text = r.data['state'] + ' ' + value.toFixed(2) + '%';
var width = new Number(this.style.match(/\w+:\s*(\d+)\w+/)[1]);
return Deluge.progressBar(value, width - 8, text);
}
function seedsRenderer(value, p, r) {
if (r.data['total_seeds'] > -1) {
return String.format('{0} ({1})', value, r.data['total_seeds']);
} else {
return value;
}
}
function peersRenderer(value, p, r) {
if (r.data['total_peers'] > -1) {
return String.format('{0} ({1})', value, r.data['total_peers']);
} else {
return value;
}
}
function availRenderer(value, p, r) {
return (value < 0) ? '&infin;' : new Number(value).toFixed(3);
}
function trackerRenderer(value, p, r) {
return String.format('<div style="background: url(' + deluge.config.base + 'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>', value);
}
/**
* Deluge.TorrentGrid Class
*
* @author Damien Churchill <damoxc@gmail.com>
* @version 1.3
*
* @class Deluge.TorrentGrid
* @extends Ext.grid.GridPanel
* @constructor
* @param {Object} config Configuration options
*/
Deluge.TorrentGrid = Ext.extend(Ext.grid.GridPanel, {
function etaSorter(eta) {
return eta * -1;
}
// object to store contained torrent ids
torrents: {},
/**
* Deluge.TorrentGrid Class
*
* @author Damien Churchill <damoxc@gmail.com>
* @version 1.3
*
* @class Deluge.TorrentGrid
* @extends Ext.grid.GridPanel
* @constructor
* @param {Object} config Configuration options
*/
Deluge.TorrentGrid = Ext.extend(Ext.grid.GridPanel, {
columns: [{
id:'queue',
header: _('#'),
width: 30,
sortable: true,
renderer: queueRenderer,
dataIndex: 'queue'
}, {
id:'name',
header: _('Name'),
width: 150,
sortable: true,
renderer: torrentNameRenderer,
dataIndex: 'name'
}, {
header: _('Size'),
width: 75,
sortable: true,
renderer: fsize,
dataIndex: 'total_size'
}, {
header: _('Progress'),
width: 150,
sortable: true,
renderer: torrentProgressRenderer,
dataIndex: 'progress'
}, {
header: _('Seeders'),
width: 60,
sortable: true,
renderer: seedsRenderer,
dataIndex: 'num_seeds'
}, {
header: _('Peers'),
width: 60,
sortable: true,
renderer: peersRenderer,
dataIndex: 'num_peers'
}, {
header: _('Down Speed'),
width: 80,
sortable: true,
renderer: torrentSpeedRenderer,
dataIndex: 'download_payload_rate'
}, {
header: _('Up Speed'),
width: 80,
sortable: true,
renderer: torrentSpeedRenderer,
dataIndex: 'upload_payload_rate'
}, {
header: _('ETA'),
width: 60,
sortable: true,
renderer: ftime,
dataIndex: 'eta'
}, {
header: _('Ratio'),
width: 60,
sortable: true,
renderer: availRenderer,
dataIndex: 'ratio'
}, {
header: _('Avail'),
width: 60,
sortable: true,
renderer: availRenderer,
dataIndex: 'distributed_copies'
}, {
header: _('Added'),
width: 80,
sortable: true,
renderer: fdate,
dataIndex: 'time_added'
}, {
header: _('Tracker'),
width: 120,
sortable: true,
renderer: trackerRenderer,
dataIndex: 'tracker_host'
}, {
header: _('Save Path'),
width: 120,
sortable: true,
renderer: fplain,
dataIndex: 'save_path'
}],
// object to store contained torrent ids
torrents: {},
meta: {
root: 'torrents',
idProperty: 'id',
fields: [
{name: 'queue', sortType: Deluge.data.SortTypes.asQueuePosition},
{name: 'name'},
{name: 'total_size', type: 'int'},
{name: 'state'},
{name: 'progress', type: 'float'},
{name: 'num_seeds', type: 'int'},
{name: 'total_seeds', type: 'int'},
{name: 'num_peers', type: 'int'},
{name: 'total_peers', type: 'int'},
{name: 'download_payload_rate', type: 'int'},
{name: 'upload_payload_speed', type: 'int'},
{name: 'eta', type: 'int', sortType: etaSorter},
{name: 'ratio', type: 'float'},
{name: 'distributed_copies', type: 'float'},
{name: 'time_added', type: 'int'},
{name: 'tracker_host'},
{name: 'save_path'}
]
},
columns: [{
id:'queue',
header: _('#'),
width: 30,
sortable: true,
renderer: queueRenderer,
dataIndex: 'queue'
}, {
id:'name',
header: _('Name'),
width: 150,
sortable: true,
renderer: torrentNameRenderer,
dataIndex: 'name'
}, {
header: _('Size'),
width: 75,
sortable: true,
renderer: fsize,
dataIndex: 'total_size'
}, {
header: _('Progress'),
width: 150,
sortable: true,
renderer: torrentProgressRenderer,
dataIndex: 'progress'
}, {
header: _('Seeders'),
width: 60,
sortable: true,
renderer: seedsRenderer,
dataIndex: 'num_seeds'
}, {
header: _('Peers'),
width: 60,
sortable: true,
renderer: peersRenderer,
dataIndex: 'num_peers'
}, {
header: _('Down Speed'),
width: 80,
sortable: true,
renderer: torrentSpeedRenderer,
dataIndex: 'download_payload_rate'
}, {
header: _('Up Speed'),
width: 80,
sortable: true,
renderer: torrentSpeedRenderer,
dataIndex: 'upload_payload_rate'
}, {
header: _('ETA'),
width: 60,
sortable: true,
renderer: ftime,
dataIndex: 'eta'
}, {
header: _('Ratio'),
width: 60,
sortable: true,
renderer: availRenderer,
dataIndex: 'ratio'
}, {
header: _('Avail'),
width: 60,
sortable: true,
renderer: availRenderer,
dataIndex: 'distributed_copies'
}, {
header: _('Added'),
width: 80,
sortable: true,
renderer: fdate,
dataIndex: 'time_added'
}, {
header: _('Last Seen Complete'),
width: 80,
sortable: true,
renderer: fdate,
dataIndex: 'last_seen_complete'
}, {
header: _('Tracker'),
width: 120,
sortable: true,
renderer: trackerRenderer,
dataIndex: 'tracker_host'
}, {
header: _('Save Path'),
width: 120,
sortable: true,
renderer: fplain,
dataIndex: 'save_path'
}, {
header: _('Owner'),
width: 80,
sortable: true,
renderer: fplain,
dataIndex: 'owner'
}, {
header: _('Public'),
width: 80,
sortable: true,
renderer: fplain,
dataIndex: 'public'
}, {
header: _('Shared'),
width: 80,
sortable: true,
renderer: fplain,
dataIndex: 'shared'
}],
constructor: function(config) {
config = Ext.apply({
id: 'torrentGrid',
store: new Ext.data.JsonStore(this.meta),
columns: this.columns,
region: 'center',
cls: 'deluge-torrents',
stripeRows: true,
autoExpandColumn: 'name',
deferredRender:false,
autoScroll:true,
margins: '5 5 0 0',
stateful: true,
view: new Ext.ux.grid.BufferView({
rowHeight: 26,
scrollDelay: false
})
}, config);
Deluge.TorrentGrid.superclass.constructor.call(this, config);
},
meta: {
root: 'torrents',
idProperty: 'id',
fields: [
{name: 'queue', sortType: Deluge.data.SortTypes.asQueuePosition},
{name: 'name'},
{name: 'total_size', type: 'int'},
{name: 'state'},
{name: 'progress', type: 'float'},
{name: 'num_seeds', type: 'int'},
{name: 'total_seeds', type: 'int'},
{name: 'num_peers', type: 'int'},
{name: 'total_peers', type: 'int'},
{name: 'download_payload_rate', type: 'int'},
{name: 'upload_payload_speed', type: 'int'},
{name: 'eta', type: 'int', sortType: etaSorter},
{name: 'ratio', type: 'float'},
{name: 'distributed_copies', type: 'float'},
{name: 'time_added', type: 'int'},
{name: 'tracker_host'},
{name: 'save_path'}
]
},
initComponent: function() {
Deluge.TorrentGrid.superclass.initComponent.call(this);
deluge.events.on('torrentRemoved', this.onTorrentRemoved, this);
deluge.events.on('disconnect', this.onDisconnect, this);
constructor: function(config) {
config = Ext.apply({
id: 'torrentGrid',
store: new Ext.data.JsonStore(this.meta),
columns: this.columns,
region: 'center',
cls: 'deluge-torrents',
stripeRows: true,
autoExpandColumn: 'name',
deferredRender:false,
autoScroll:true,
margins: '5 5 0 0',
stateful: true,
view: new Ext.ux.grid.BufferView({
rowHeight: 26,
scrollDelay: false
})
}, config);
Deluge.TorrentGrid.superclass.constructor.call(this, config);
},
this.on('rowcontextmenu', function(grid, rowIndex, e) {
e.stopEvent();
var selection = grid.getSelectionModel();
if (!selection.hasSelection()) {
selection.selectRow(rowIndex);
}
deluge.menus.torrent.showAt(e.getPoint());
});
},
initComponent: function() {
Deluge.TorrentGrid.superclass.initComponent.call(this);
deluge.events.on('torrentRemoved', this.onTorrentRemoved, this);
deluge.events.on('disconnect', this.onDisconnect, this);
/**
* Returns the record representing the torrent at the specified index.
*
* @param index {int} The row index of the torrent you wish to retrieve.
* @return {Ext.data.Record} The record representing the torrent.
*/
getTorrent: function(index) {
return this.getStore().getAt(index);
},
this.on('rowcontextmenu', function(grid, rowIndex, e) {
e.stopEvent();
var selection = grid.getSelectionModel();
if (!selection.hasSelection()) {
selection.selectRow(rowIndex);
}
deluge.menus.torrent.showAt(e.getPoint());
});
},
/**
* Returns the currently selected record.
* @ return {Array/Ext.data.Record} The record(s) representing the rows
*/
getSelected: function() {
return this.getSelectionModel().getSelected();
},
/**
* Returns the record representing the torrent at the specified index.
*
* @param index {int} The row index of the torrent you wish to retrieve.
* @return {Ext.data.Record} The record representing the torrent.
*/
getTorrent: function(index) {
return this.getStore().getAt(index);
},
/**
* Returns the currently selected records.
*/
getSelections: function() {
return this.getSelectionModel().getSelections();
},
/**
* Returns the currently selected record.
* @ return {Array/Ext.data.Record} The record(s) representing the rows
*/
getSelected: function() {
return this.getSelectionModel().getSelected();
},
/**
* Return the currently selected torrent id.
* @return {String} The currently selected id.
*/
getSelectedId: function() {
return this.getSelectionModel().getSelected().id
},
/**
* Returns the currently selected records.
*/
getSelections: function() {
return this.getSelectionModel().getSelections();
},
/**
* Return the currently selected torrent ids.
* @return {Array} The currently selected ids.
*/
getSelectedIds: function() {
var ids = [];
Ext.each(this.getSelectionModel().getSelections(), function(r) {
ids.push(r.id);
});
return ids;
},
/**
* Return the currently selected torrent id.
* @return {String} The currently selected id.
*/
getSelectedId: function() {
return this.getSelectionModel().getSelected().id
},
update: function(torrents, wipe) {
var store = this.getStore();
/**
* Return the currently selected torrent ids.
* @return {Array} The currently selected ids.
*/
getSelectedIds: function() {
var ids = [];
Ext.each(this.getSelectionModel().getSelections(), function(r) {
ids.push(r.id);
});
return ids;
},
// Need to perform a complete reload of the torrent grid.
if (wipe) {
store.removeAll();
this.torrents = {};
}
update: function(torrents, wipe) {
var store = this.getStore();
var newTorrents = [];
// Need to perform a complete reload of the torrent grid.
if (wipe) {
store.removeAll();
this.torrents = {};
}
// Update and add any new torrents.
for (var t in torrents) {
var torrent = torrents[t];
var newTorrents = [];
if (this.torrents[t]) {
var record = store.getById(t);
record.beginEdit();
for (var k in torrent) {
if (record.get(k) != torrent[k]) {
record.set(k, torrent[k]);
}
}
record.endEdit();
} else {
var record = new Deluge.data.Torrent(torrent);
record.id = t;
this.torrents[t] = 1;
newTorrents.push(record);
}
}
store.add(newTorrents);
// Update and add any new torrents.
for (var t in torrents) {
var torrent = torrents[t];
// Remove any torrents that should not be in the store.
store.each(function(record) {
if (!torrents[record.id]) {
store.remove(record);
delete this.torrents[record.id];
}
}, this);
store.commitChanges();
if (this.torrents[t]) {
var record = store.getById(t);
record.beginEdit();
for (var k in torrent) {
if (record.get(k) != torrent[k]) {
record.set(k, torrent[k]);
}
}
record.endEdit();
} else {
var record = new Deluge.data.Torrent(torrent);
record.id = t;
this.torrents[t] = 1;
newTorrents.push(record);
}
}
store.add(newTorrents);
var sortState = store.getSortState()
if (!sortState) return;
store.sort(sortState.field, sortState.direction);
},
// Remove any torrents that should not be in the store.
store.each(function(record) {
if (!torrents[record.id]) {
store.remove(record);
delete this.torrents[record.id];
}
}, this);
store.commitChanges();
// private
onDisconnect: function() {
this.getStore().removeAll();
this.torrents = {};
},
var sortState = store.getSortState()
if (!sortState) return;
store.sort(sortState.field, sortState.direction);
},
// private
onTorrentRemoved: function(torrentIds) {
var selModel = this.getSelectionModel();
Ext.each(torrentIds, function(torrentId) {
var record = this.getStore().getById(torrentId);
if (selModel.isSelected(record)) {
selModel.deselectRow(this.getStore().indexOf(record));
}
this.getStore().remove(record);
delete this.torrents[torrentId];
}, this);
}
// private
onDisconnect: function() {
this.getStore().removeAll();
this.torrents = {};
},
// private
onTorrentRemoved: function(torrentIds) {
var selModel = this.getSelectionModel();
Ext.each(torrentIds, function(torrentId) {
var record = this.getStore().getById(torrentId);
if (selModel.isSelected(record)) {
selModel.deselectRow(this.getStore().indexOf(record));
}
this.getStore().remove(record);
delete this.torrents[torrentId];
}, this);
}
});
deluge.torrents = new Deluge.TorrentGrid();
})();

View file

@ -38,234 +38,234 @@
*/
deluge.ui = {
errorCount: 0,
errorCount: 0,
filters: null,
filters: null,
/**
* @description Create all the interface components, the json-rpc client
* and set up various events that the UI will utilise.
*/
initialize: function() {
deluge.add = new Deluge.add.AddWindow();
deluge.details = new Deluge.details.DetailsPanel();
deluge.connectionManager = new Deluge.ConnectionManager();
deluge.editTrackers = new Deluge.EditTrackersWindow();
deluge.login = new Deluge.LoginWindow();
deluge.preferences = new Deluge.preferences.PreferencesWindow();
deluge.sidebar = new Deluge.Sidebar();
deluge.statusbar = new Deluge.Statusbar();
deluge.toolbar = new Deluge.Toolbar();
/**
* @description Create all the interface components, the json-rpc client
* and set up various events that the UI will utilise.
*/
initialize: function() {
deluge.add = new Deluge.add.AddWindow();
deluge.details = new Deluge.details.DetailsPanel();
deluge.connectionManager = new Deluge.ConnectionManager();
deluge.editTrackers = new Deluge.EditTrackersWindow();
deluge.login = new Deluge.LoginWindow();
deluge.preferences = new Deluge.preferences.PreferencesWindow();
deluge.sidebar = new Deluge.Sidebar();
deluge.statusbar = new Deluge.Statusbar();
deluge.toolbar = new Deluge.Toolbar();
this.MainPanel = new Ext.Panel({
id: 'mainPanel',
iconCls: 'x-deluge-main-panel',
title: 'Deluge',
layout: 'border',
tbar: deluge.toolbar,
items: [
deluge.sidebar,
deluge.details,
deluge.torrents
],
bbar: deluge.statusbar
});
this.MainPanel = new Ext.Panel({
id: 'mainPanel',
iconCls: 'x-deluge-main-panel',
title: 'Deluge',
layout: 'border',
tbar: deluge.toolbar,
items: [
deluge.sidebar,
deluge.details,
deluge.torrents
],
bbar: deluge.statusbar
});
this.Viewport = new Ext.Viewport({
layout: 'fit',
items: [this.MainPanel]
});
this.Viewport = new Ext.Viewport({
layout: 'fit',
items: [this.MainPanel]
});
deluge.events.on("connect", this.onConnect, this);
deluge.events.on("disconnect", this.onDisconnect, this);
deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
deluge.client = new Ext.ux.util.RpcClient({
url: deluge.config.base + 'json'
});
deluge.events.on("connect", this.onConnect, this);
deluge.events.on("disconnect", this.onDisconnect, this);
deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
deluge.client = new Ext.ux.util.RpcClient({
url: deluge.config.base + 'json'
});
// enable all the already active plugins
for (var plugin in Deluge.pluginStore) {
plugin = Deluge.createPlugin(plugin);
plugin.enable();
deluge.plugins[plugin.name] = plugin;
}
// enable all the already active plugins
for (var plugin in Deluge.pluginStore) {
plugin = Deluge.createPlugin(plugin);
plugin.enable();
deluge.plugins[plugin.name] = plugin;
}
// Initialize quicktips so all the tooltip configs start working.
Ext.QuickTips.init();
// Initialize quicktips so all the tooltip configs start working.
Ext.QuickTips.init();
deluge.client.on('connected', function(e) {
deluge.login.show();
}, this, {single: true});
deluge.client.on('connected', function(e) {
deluge.login.show();
}, this, {single: true});
this.update = this.update.createDelegate(this);
this.checkConnection = this.checkConnection.createDelegate(this);
this.update = this.update.createDelegate(this);
this.checkConnection = this.checkConnection.createDelegate(this);
this.originalTitle = document.title;
},
this.originalTitle = document.title;
},
checkConnection: function() {
deluge.client.web.connected({
success: this.onConnectionSuccess,
failure: this.onConnectionError,
scope: this
});
},
checkConnection: function() {
deluge.client.web.connected({
success: this.onConnectionSuccess,
failure: this.onConnectionError,
scope: this
});
},
update: function() {
var filters = deluge.sidebar.getFilterStates();
this.oldFilters = this.filters;
this.filters = filters;
update: function() {
var filters = deluge.sidebar.getFilterStates();
this.oldFilters = this.filters;
this.filters = filters;
deluge.client.web.update_ui(Deluge.Keys.Grid, filters, {
success: this.onUpdate,
failure: this.onUpdateError,
scope: this
});
deluge.details.update();
},
deluge.client.web.update_ui(Deluge.Keys.Grid, filters, {
success: this.onUpdate,
failure: this.onUpdateError,
scope: this
});
deluge.details.update();
},
onConnectionError: function(error) {
onConnectionError: function(error) {
},
},
onConnectionSuccess: function(result) {
deluge.statusbar.setStatus({
iconCls: 'x-deluge-statusbar icon-ok',
text: _('Connection restored')
});
clearInterval(this.checking);
if (!result) {
deluge.connectionManager.show();
}
},
onConnectionSuccess: function(result) {
deluge.statusbar.setStatus({
iconCls: 'x-deluge-statusbar icon-ok',
text: _('Connection restored')
});
clearInterval(this.checking);
if (!result) {
deluge.connectionManager.show();
}
},
onUpdateError: function(error) {
if (this.errorCount == 2) {
Ext.MessageBox.show({
title: 'Lost Connection',
msg: 'The connection to the webserver has been lost!',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR
});
deluge.events.fire('disconnect');
deluge.statusbar.setStatus({
text: 'Lost connection to webserver'}
);
this.checking = setInterval(this.checkConnection, 2000);
}
this.errorCount++;
},
onUpdateError: function(error) {
if (this.errorCount == 2) {
Ext.MessageBox.show({
title: 'Lost Connection',
msg: 'The connection to the webserver has been lost!',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR
});
deluge.events.fire('disconnect');
deluge.statusbar.setStatus({
text: 'Lost connection to webserver'}
);
this.checking = setInterval(this.checkConnection, 2000);
}
this.errorCount++;
},
/**
* @static
* @private
* Updates the various components in the interface.
*/
onUpdate: function(data) {
if (!data['connected']) {
deluge.connectionManager.disconnect(true);
return;
}
/**
* @static
* @private
* Updates the various components in the interface.
*/
onUpdate: function(data) {
if (!data['connected']) {
deluge.connectionManager.disconnect(true);
return;
}
if (deluge.config.show_session_speed) {
document.title = this.originalTitle +
' (Down: ' + fspeed(data['stats'].download_rate, true) +
' Up: ' + fspeed(data['stats'].upload_rate, true) + ')';
}
if (Ext.areObjectsEqual(this.filters, this.oldFilters)) {
deluge.torrents.update(data['torrents']);
} else {
deluge.torrents.update(data['torrents'], true);
}
deluge.statusbar.update(data['stats']);
deluge.sidebar.update(data['filters']);
this.errorCount = 0;
},
if (deluge.config.show_session_speed) {
document.title = this.originalTitle +
' (Down: ' + fspeed(data['stats'].download_rate, true) +
' Up: ' + fspeed(data['stats'].upload_rate, true) + ')';
}
if (Ext.areObjectsEqual(this.filters, this.oldFilters)) {
deluge.torrents.update(data['torrents']);
} else {
deluge.torrents.update(data['torrents'], true);
}
deluge.statusbar.update(data['stats']);
deluge.sidebar.update(data['filters']);
this.errorCount = 0;
},
/**
* @static
* @private
* Start the Deluge UI polling the server and update the interface.
*/
onConnect: function() {
if (!this.running) {
this.running = setInterval(this.update, 2000);
this.update();
}
deluge.client.web.get_plugins({
success: this.onGotPlugins,
scope: this
});
},
/**
* @static
* @private
* Start the Deluge UI polling the server and update the interface.
*/
onConnect: function() {
if (!this.running) {
this.running = setInterval(this.update, 2000);
this.update();
}
deluge.client.web.get_plugins({
success: this.onGotPlugins,
scope: this
});
},
/**
* @static
* @private
*/
onDisconnect: function() {
this.stop();
},
/**
* @static
* @private
*/
onDisconnect: function() {
this.stop();
},
onGotPlugins: function(plugins) {
Ext.each(plugins.enabled_plugins, function(plugin) {
if (deluge.plugins[plugin]) return;
deluge.client.web.get_plugin_resources(plugin, {
success: this.onGotPluginResources,
scope: this
});
}, this);
},
onGotPlugins: function(plugins) {
Ext.each(plugins.enabled_plugins, function(plugin) {
if (deluge.plugins[plugin]) return;
deluge.client.web.get_plugin_resources(plugin, {
success: this.onGotPluginResources,
scope: this
});
}, this);
},
onPluginEnabled: function(pluginName) {
if (deluge.plugins[pluginName]) {
deluge.plugins[pluginName].enable();
} else {
deluge.client.web.get_plugin_resources(pluginName, {
success: this.onGotPluginResources,
scope: this
});
}
},
onPluginEnabled: function(pluginName) {
if (deluge.plugins[pluginName]) {
deluge.plugins[pluginName].enable();
} else {
deluge.client.web.get_plugin_resources(pluginName, {
success: this.onGotPluginResources,
scope: this
});
}
},
onGotPluginResources: function(resources) {
var scripts = (Deluge.debug) ? resources.debug_scripts : resources.scripts;
Ext.each(scripts, function(script) {
Ext.ux.JSLoader({
url: deluge.config.base + script,
onLoad: this.onPluginLoaded,
pluginName: resources.name
});
}, this);
},
onGotPluginResources: function(resources) {
var scripts = (Deluge.debug) ? resources.debug_scripts : resources.scripts;
Ext.each(scripts, function(script) {
Ext.ux.JSLoader({
url: deluge.config.base + script,
onLoad: this.onPluginLoaded,
pluginName: resources.name
});
}, this);
},
onPluginDisabled: function(pluginName) {
deluge.plugins[pluginName].disable();
},
onPluginDisabled: function(pluginName) {
deluge.plugins[pluginName].disable();
},
onPluginLoaded: function(options) {
// This could happen if the plugin has multiple scripts
if (!Deluge.hasPlugin(options.pluginName)) return;
onPluginLoaded: function(options) {
// This could happen if the plugin has multiple scripts
if (!Deluge.hasPlugin(options.pluginName)) return;
// Enable the plugin
plugin = Deluge.createPlugin(options.pluginName);
plugin.enable();
deluge.plugins[plugin.name] = plugin;
},
// Enable the plugin
plugin = Deluge.createPlugin(options.pluginName);
plugin.enable();
deluge.plugins[plugin.name] = plugin;
},
/**
* @static
* Stop the Deluge UI polling the server and clear the interface.
*/
stop: function() {
if (this.running) {
clearInterval(this.running);
this.running = false;
deluge.torrents.getStore().removeAll();
}
}
/**
* @static
* Stop the Deluge UI polling the server and clear the interface.
*/
stop: function() {
if (this.running) {
clearInterval(this.running);
this.running = false;
deluge.torrents.getStore().removeAll();
}
}
}
Ext.onReady(function(e) {
deluge.ui.initialize();
deluge.ui.initialize();
});

View file

@ -34,195 +34,195 @@ Ext.namespace('Deluge.add');
Deluge.add.AddWindow = Ext.extend(Deluge.add.Window, {
title: _('Add Torrents'),
layout: 'border',
width: 470,
height: 450,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
iconCls: 'x-deluge-add-window-icon',
title: _('Add Torrents'),
layout: 'border',
width: 470,
height: 450,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
iconCls: 'x-deluge-add-window-icon',
initComponent: function() {
Deluge.add.AddWindow.superclass.initComponent.call(this);
initComponent: function() {
Deluge.add.AddWindow.superclass.initComponent.call(this);
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Add'), this.onAddClick, this);
function torrentRenderer(value, p, r) {
if (r.data['info_hash']) {
return String.format('<div class="x-deluge-add-torrent-name">{0}</div>', value);
} else {
return String.format('<div class="x-deluge-add-torrent-name-loading">{0}</div>', value);
}
}
this.addButton(_('Cancel'), this.onCancelClick, this);
this.addButton(_('Add'), this.onAddClick, this);
function torrentRenderer(value, p, r) {
if (r.data['info_hash']) {
return String.format('<div class="x-deluge-add-torrent-name">{0}</div>', value);
} else {
return String.format('<div class="x-deluge-add-torrent-name-loading">{0}</div>', value);
}
}
this.list = new Ext.list.ListView({
store: new Ext.data.SimpleStore({
fields: [
{name: 'info_hash', mapping: 1},
{name: 'text', mapping: 2}
],
id: 0
}),
columns: [{
id: 'torrent',
width: 150,
sortable: true,
renderer: torrentRenderer,
dataIndex: 'text'
}],
stripeRows: true,
singleSelect: true,
listeners: {
'selectionchange': {
fn: this.onSelect,
scope: this
}
},
hideHeaders: true,
autoExpandColumn: 'torrent',
autoScroll: true
});
this.list = new Ext.list.ListView({
store: new Ext.data.SimpleStore({
fields: [
{name: 'info_hash', mapping: 1},
{name: 'text', mapping: 2}
],
id: 0
}),
columns: [{
id: 'torrent',
width: 150,
sortable: true,
renderer: torrentRenderer,
dataIndex: 'text'
}],
stripeRows: true,
singleSelect: true,
listeners: {
'selectionchange': {
fn: this.onSelect,
scope: this
}
},
hideHeaders: true,
autoExpandColumn: 'torrent',
autoScroll: true
});
this.add({
region: 'center',
items: [this.list],
margins: '5 5 5 5',
bbar: new Ext.Toolbar({
items: [{
iconCls: 'x-deluge-add-file',
text: _('File'),
handler: this.onFile,
scope: this
}, {
text: _('Url'),
iconCls: 'icon-add-url',
handler: this.onUrl,
scope: this
}, {
text: _('Infohash'),
iconCls: 'icon-add-magnet',
disabled: true
}, '->', {
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onRemove,
scope: this
}]
})
});
this.optionsPanel = this.add(new Deluge.add.OptionsPanel());
this.on('hide', this.onHide, this);
this.on('show', this.onShow, this);
},
this.add({
region: 'center',
items: [this.list],
margins: '5 5 5 5',
bbar: new Ext.Toolbar({
items: [{
iconCls: 'x-deluge-add-file',
text: _('File'),
handler: this.onFile,
scope: this
}, {
text: _('Url'),
iconCls: 'icon-add-url',
handler: this.onUrl,
scope: this
}, {
text: _('Infohash'),
iconCls: 'icon-add-magnet',
disabled: true
}, '->', {
text: _('Remove'),
iconCls: 'icon-remove',
handler: this.onRemove,
scope: this
}]
})
});
this.optionsPanel = this.add(new Deluge.add.OptionsPanel());
this.on('hide', this.onHide, this);
this.on('show', this.onShow, this);
},
clear: function() {
this.list.getStore().removeAll();
this.optionsPanel.clear();
},
clear: function() {
this.list.getStore().removeAll();
this.optionsPanel.clear();
},
onAddClick: function() {
var torrents = [];
if (!this.list) return;
this.list.getStore().each(function(r) {
var id = r.get('info_hash');
torrents.push({
path: this.optionsPanel.getFilename(id),
options: this.optionsPanel.getOptions(id)
});
}, this);
onAddClick: function() {
var torrents = [];
if (!this.list) return;
this.list.getStore().each(function(r) {
var id = r.get('info_hash');
torrents.push({
path: this.optionsPanel.getFilename(id),
options: this.optionsPanel.getOptions(id)
});
}, this);
deluge.client.web.add_torrents(torrents, {
success: function(result) {
}
})
this.clear();
this.hide();
},
deluge.client.web.add_torrents(torrents, {
success: function(result) {
}
})
this.clear();
this.hide();
},
onCancelClick: function() {
this.clear();
this.hide();
},
onCancelClick: function() {
this.clear();
this.hide();
},
onFile: function() {
if (!this.file) this.file = new Deluge.add.FileWindow();
this.file.show();
},
onFile: function() {
if (!this.file) this.file = new Deluge.add.FileWindow();
this.file.show();
},
onHide: function() {
this.optionsPanel.setActiveTab(0);
this.optionsPanel.files.setDisabled(true);
this.optionsPanel.form.setDisabled(true);
},
onHide: function() {
this.optionsPanel.setActiveTab(0);
this.optionsPanel.files.setDisabled(true);
this.optionsPanel.form.setDisabled(true);
},
onRemove: function() {
if (!this.list.getSelectionCount()) return;
var torrent = this.list.getSelectedRecords()[0];
this.list.getStore().remove(torrent);
this.optionsPanel.clear();
if (this.torrents && this.torrents[torrent.id]) delete this.torrents[torrent.id];
},
onRemove: function() {
if (!this.list.getSelectionCount()) return;
var torrent = this.list.getSelectedRecords()[0];
this.list.getStore().remove(torrent);
this.optionsPanel.clear();
if (this.torrents && this.torrents[torrent.id]) delete this.torrents[torrent.id];
},
onSelect: function(list, selections) {
if (selections.length) {
var record = this.list.getRecord(selections[0]);
this.optionsPanel.setTorrent(record.get('info_hash'));
this.optionsPanel.files.setDisabled(false);
this.optionsPanel.form.setDisabled(false);
} else {
this.optionsPanel.files.setDisabled(true);
this.optionsPanel.form.setDisabled(true);
}
},
onSelect: function(list, selections) {
if (selections.length) {
var record = this.list.getRecord(selections[0]);
this.optionsPanel.setTorrent(record.get('info_hash'));
this.optionsPanel.files.setDisabled(false);
this.optionsPanel.form.setDisabled(false);
} else {
this.optionsPanel.files.setDisabled(true);
this.optionsPanel.form.setDisabled(true);
}
},
onShow: function() {
if (!this.url) {
this.url = new Deluge.add.UrlWindow();
this.url.on('beforeadd', this.onTorrentBeforeAdd, this);
this.url.on('add', this.onTorrentAdd, this);
}
onShow: function() {
if (!this.url) {
this.url = new Deluge.add.UrlWindow();
this.url.on('beforeadd', this.onTorrentBeforeAdd, this);
this.url.on('add', this.onTorrentAdd, this);
}
if (!this.file) {
this.file = new Deluge.add.FileWindow();
this.file.on('beforeadd', this.onTorrentBeforeAdd, this);
this.file.on('add', this.onTorrentAdd, this);
}
this.optionsPanel.form.getDefaults();
},
if (!this.file) {
this.file = new Deluge.add.FileWindow();
this.file.on('beforeadd', this.onTorrentBeforeAdd, this);
this.file.on('add', this.onTorrentAdd, this);
}
this.optionsPanel.form.getDefaults();
},
onTorrentBeforeAdd: function(torrentId, text) {
var store = this.list.getStore();
store.loadData([[torrentId, null, text]], true);
},
onTorrentBeforeAdd: function(torrentId, text) {
var store = this.list.getStore();
store.loadData([[torrentId, null, text]], true);
},
onTorrentAdd: function(torrentId, info) {
var r = this.list.getStore().getById(torrentId);
if (!info) {
Ext.MessageBox.show({
title: _('Error'),
msg: _('Not a valid torrent'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
this.list.getStore().remove(r);
} else {
r.set('info_hash', info['info_hash']);
r.set('text', info['name']);
this.list.getStore().commitChanges();
this.optionsPanel.addTorrent(info);
}
},
onTorrentAdd: function(torrentId, info) {
var r = this.list.getStore().getById(torrentId);
if (!info) {
Ext.MessageBox.show({
title: _('Error'),
msg: _('Not a valid torrent'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
this.list.getStore().remove(r);
} else {
r.set('info_hash', info['info_hash']);
r.set('text', info['name']);
this.list.getStore().commitChanges();
this.optionsPanel.addTorrent(info);
}
},
onUrl: function(button, event) {
this.url.show();
}
onUrl: function(button, event) {
this.url.show();
}
});

View file

@ -37,80 +37,80 @@ Ext.ns('Deluge.add');
*/
Deluge.add.FileWindow = Ext.extend(Deluge.add.Window, {
title: _('Add from File'),
layout: 'fit',
width: 350,
height: 115,
modal: true,
plain: true,
buttonAlign: 'center',
closeAction: 'hide',
bodyStyle: 'padding: 10px 5px;',
iconCls: 'x-deluge-add-file',
title: _('Add from File'),
layout: 'fit',
width: 350,
height: 115,
modal: true,
plain: true,
buttonAlign: 'center',
closeAction: 'hide',
bodyStyle: 'padding: 10px 5px;',
iconCls: 'x-deluge-add-file',
initComponent: function() {
Deluge.add.FileWindow.superclass.initComponent.call(this);
this.addButton(_('Add'), this.onAddClick, this);
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
labelWidth: 35,
autoHeight: true,
fileUpload: true,
items: [{
xtype: 'fileuploadfield',
id: 'torrentFile',
width: 280,
emptyText: _('Select a torrent'),
fieldLabel: _('File'),
name: 'file',
buttonCfg: {
text: _('Browse') + '...'
}
}]
});
},
// private
onAddClick: function(field, e) {
if (this.form.getForm().isValid()) {
this.torrentId = this.createTorrentId();
this.form.getForm().submit({
url: '/upload',
waitMsg: _('Uploading your torrent...'),
failure: this.onUploadFailure,
success: this.onUploadSuccess,
scope: this
});
var name = this.form.getForm().findField('torrentFile').value;
name = name.split('\\').slice(-1)[0];
this.fireEvent('beforeadd', this.torrentId, name);
}
},
// private
onGotInfo: function(info, obj, response, request) {
info['filename'] = request.options.filename;
this.fireEvent('add', this.torrentId, info);
},
initComponent: function() {
Deluge.add.FileWindow.superclass.initComponent.call(this);
this.addButton(_('Add'), this.onAddClick, this);
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
labelWidth: 35,
autoHeight: true,
fileUpload: true,
items: [{
xtype: 'fileuploadfield',
id: 'torrentFile',
width: 280,
emptyText: _('Select a torrent'),
fieldLabel: _('File'),
name: 'file',
buttonCfg: {
text: _('Browse') + '...'
}
}]
});
},
// private
onAddClick: function(field, e) {
if (this.form.getForm().isValid()) {
this.torrentId = this.createTorrentId();
this.form.getForm().submit({
url: '/upload',
waitMsg: _('Uploading your torrent...'),
failure: this.onUploadFailure,
success: this.onUploadSuccess,
scope: this
});
var name = this.form.getForm().findField('torrentFile').value;
name = name.split('\\').slice(-1)[0];
this.fireEvent('beforeadd', this.torrentId, name);
}
},
// private
onGotInfo: function(info, obj, response, request) {
info['filename'] = request.options.filename;
this.fireEvent('add', this.torrentId, info);
},
// private
onUploadFailure: function(form, action) {
this.hide();
},
// private
onUploadSuccess: function(fp, upload) {
this.hide();
if (upload.result.success) {
var filename = upload.result.files[0];
this.form.getForm().findField('torrentFile').setValue('');
deluge.client.web.get_torrent_info(filename, {
success: this.onGotInfo,
scope: this,
filename: filename
});
}
}
// private
onUploadFailure: function(form, action) {
this.hide();
},
// private
onUploadSuccess: function(fp, upload) {
this.hide();
if (upload.result.success) {
var filename = upload.result.files[0];
this.form.getForm().findField('torrentFile').setValue('');
deluge.client.web.get_torrent_info(filename, {
success: this.onGotInfo,
scope: this,
filename: filename
});
}
}
});

View file

@ -37,78 +37,78 @@ Ext.ns('Deluge.add');
*/
Deluge.add.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
layout: 'fit',
title: _('Files'),
layout: 'fit',
title: _('Files'),
autoScroll: true,
animate: false,
border: false,
disabled: true,
rootVisible: false,
autoScroll: true,
animate: false,
border: false,
disabled: true,
rootVisible: false,
columns: [{
header: _('Filename'),
width: 295,
dataIndex: 'filename'
},{
header: _('Size'),
width: 60,
dataIndex: 'size',
tpl: new Ext.XTemplate('{size:this.fsize}', {
fsize: function(v) {
return fsize(v);
}
})
},{
header: _('Download'),
width: 65,
dataIndex: 'download',
tpl: new Ext.XTemplate('{download:this.format}', {
format: function(v) {
return '<div rel="chkbox" class="x-grid3-check-col'+(v?'-on':'')+'"> </div>';
}
})
}],
columns: [{
header: _('Filename'),
width: 295,
dataIndex: 'filename'
},{
header: _('Size'),
width: 60,
dataIndex: 'size',
tpl: new Ext.XTemplate('{size:this.fsize}', {
fsize: function(v) {
return fsize(v);
}
})
},{
header: _('Download'),
width: 65,
dataIndex: 'download',
tpl: new Ext.XTemplate('{download:this.format}', {
format: function(v) {
return '<div rel="chkbox" class="x-grid3-check-col'+(v?'-on':'')+'"> </div>';
}
})
}],
initComponent: function() {
Deluge.add.FilesTab.superclass.initComponent.call(this);
this.on('click', this.onNodeClick, this);
},
initComponent: function() {
Deluge.add.FilesTab.superclass.initComponent.call(this);
this.on('click', this.onNodeClick, this);
},
clearFiles: function() {
var root = this.getRootNode();
if (!root.hasChildNodes()) return;
root.cascade(function(node) {
if (!node.parentNode || !node.getOwnerTree()) return;
node.remove();
});
},
clearFiles: function() {
var root = this.getRootNode();
if (!root.hasChildNodes()) return;
root.cascade(function(node) {
if (!node.parentNode || !node.getOwnerTree()) return;
node.remove();
});
},
setDownload: function(node, value, suppress) {
node.attributes.download = value;
node.ui.updateColumns();
setDownload: function(node, value, suppress) {
node.attributes.download = value;
node.ui.updateColumns();
if (node.isLeaf()) {
if (!suppress) {
return this.fireEvent('fileschecked', [node], value, !value);
}
} else {
var nodes = [node];
node.cascade(function(n) {
n.attributes.download = value;
n.ui.updateColumns();
nodes.push(n);
}, this);
if (!suppress) {
return this.fireEvent('fileschecked', nodes, value, !value);
}
}
},
if (node.isLeaf()) {
if (!suppress) {
return this.fireEvent('fileschecked', [node], value, !value);
}
} else {
var nodes = [node];
node.cascade(function(n) {
n.attributes.download = value;
n.ui.updateColumns();
nodes.push(n);
}, this);
if (!suppress) {
return this.fireEvent('fileschecked', nodes, value, !value);
}
}
},
onNodeClick: function(node, e) {
var el = new Ext.Element(e.target);
if (el.getAttribute('rel') == 'chkbox') {
this.setDownload(node, !node.attributes.download);
}
}
onNodeClick: function(node, e) {
var el = new Ext.Element(e.target);
if (el.getAttribute('rel') == 'chkbox') {
this.setDownload(node, !node.attributes.download);
}
}
});

View file

@ -33,127 +33,127 @@ Ext.ns('Deluge.add');
Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
torrents: {},
torrents: {},
// layout options
region: 'south',
margins: '5 5 5 5',
activeTab: 0,
height: 220,
// layout options
region: 'south',
margins: '5 5 5 5',
activeTab: 0,
height: 220,
initComponent: function() {
Deluge.add.OptionsPanel.superclass.initComponent.call(this);
this.files = this.add(new Deluge.add.FilesTab());
this.form = this.add(new Deluge.add.OptionsTab());
initComponent: function() {
Deluge.add.OptionsPanel.superclass.initComponent.call(this);
this.files = this.add(new Deluge.add.FilesTab());
this.form = this.add(new Deluge.add.OptionsTab());
this.files.on('fileschecked', this.onFilesChecked, this);
},
this.files.on('fileschecked', this.onFilesChecked, this);
},
addTorrent: function(torrent) {
this.torrents[torrent['info_hash']] = torrent;
var fileIndexes = {};
this.walkFileTree(torrent['files_tree'], function(filename, type, entry, parent) {
if (type != 'file') return;
fileIndexes[entry.index] = entry.download;
}, this);
addTorrent: function(torrent) {
this.torrents[torrent['info_hash']] = torrent;
var fileIndexes = {};
this.walkFileTree(torrent['files_tree'], function(filename, type, entry, parent) {
if (type != 'file') return;
fileIndexes[entry.index] = entry.download;
}, this);
var priorities = [];
Ext.each(Ext.keys(fileIndexes), function(index) {
priorities[index] = fileIndexes[index];
});
var oldId = this.form.optionsManager.changeId(torrent['info_hash'], true);
this.form.optionsManager.setDefault('file_priorities', priorities);
this.form.optionsManager.changeId(oldId, true);
},
var priorities = [];
Ext.each(Ext.keys(fileIndexes), function(index) {
priorities[index] = fileIndexes[index];
});
var oldId = this.form.optionsManager.changeId(torrent['info_hash'], true);
this.form.optionsManager.setDefault('file_priorities', priorities);
this.form.optionsManager.changeId(oldId, true);
},
clear: function() {
this.files.clearFiles();
this.form.optionsManager.resetAll();
},
clear: function() {
this.files.clearFiles();
this.form.optionsManager.resetAll();
},
getFilename: function(torrentId) {
return this.torrents[torrentId]['filename'];
},
getFilename: function(torrentId) {
return this.torrents[torrentId]['filename'];
},
getOptions: function(torrentId) {
var oldId = this.form.optionsManager.changeId(torrentId, true);
var options = this.form.optionsManager.get();
this.form.optionsManager.changeId(oldId, true);
Ext.each(options['file_priorities'], function(priority, index) {
options['file_priorities'][index] = (priority) ? 1 : 0;
});
return options;
},
getOptions: function(torrentId) {
var oldId = this.form.optionsManager.changeId(torrentId, true);
var options = this.form.optionsManager.get();
this.form.optionsManager.changeId(oldId, true);
Ext.each(options['file_priorities'], function(priority, index) {
options['file_priorities'][index] = (priority) ? 1 : 0;
});
return options;
},
setTorrent: function(torrentId) {
if (!torrentId) return;
setTorrent: function(torrentId) {
if (!torrentId) return;
this.torrentId = torrentId;
this.form.optionsManager.changeId(torrentId);
this.files.clearFiles();
var root = this.files.getRootNode();
var priorities = this.form.optionsManager.get('file_priorities');
this.torrentId = torrentId;
this.form.optionsManager.changeId(torrentId);
this.files.clearFiles();
var root = this.files.getRootNode();
var priorities = this.form.optionsManager.get('file_priorities');
this.walkFileTree(this.torrents[torrentId]['files_tree'], function(filename, type, entry, parentNode) {
var node = new Ext.tree.TreeNode({
download: (entry.index) ? priorities[entry.index] : true,
filename: filename,
fileindex: entry.index,
leaf: type != 'dir',
size: entry.length
});
parentNode.appendChild(node);
if (type == 'dir') return node;
}, this, root);
root.firstChild.expand();
},
this.walkFileTree(this.torrents[torrentId]['files_tree'], function(filename, type, entry, parentNode) {
var node = new Ext.tree.TreeNode({
download: (entry.index) ? priorities[entry.index] : true,
filename: filename,
fileindex: entry.index,
leaf: type != 'dir',
size: entry.length
});
parentNode.appendChild(node);
if (type == 'dir') return node;
}, this, root);
root.firstChild.expand();
},
walkFileTree: function(files, callback, scope, parentNode) {
for (var filename in files.contents) {
var entry = files.contents[filename];
var type = entry.type;
walkFileTree: function(files, callback, scope, parentNode) {
for (var filename in files.contents) {
var entry = files.contents[filename];
var type = entry.type;
if (scope) {
var ret = callback.apply(scope, [filename, type, entry, parentNode]);
} else {
var ret = callback(filename, type, entry, parentNode);
}
if (type == 'dir') this.walkFileTree(entry, callback, scope, ret);
}
},
if (scope) {
var ret = callback.apply(scope, [filename, type, entry, parentNode]);
} else {
var ret = callback(filename, type, entry, parentNode);
}
if (type == 'dir') this.walkFileTree(entry, callback, scope, ret);
}
},
onFilesChecked: function(nodes, newValue, oldValue) {
if (this.form.optionsManager.get('compact_allocation')) {
Ext.Msg.show({
title: _('Unable to set file priority!'),
msg: _('File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?'),
buttons: Ext.Msg.YESNO,
fn: function(result) {
if (result == 'yes') {
this.form.optionsManager.update('compact_allocation', false);
Ext.each(nodes, function(node) {
if (node.attributes.fileindex < 0) return;
var priorities = this.form.optionsManager.get('file_priorities');
priorities[node.attributes.fileindex] = newValue;
this.form.optionsManager.update('file_priorities', priorities);
}, this);
} else {
this.files.setDownload(nodes[0], oldValue, true);
}
},
scope: this,
icon: Ext.MessageBox.QUESTION
});
} else {
Ext.each(nodes, function(node) {
if (node.attributes.fileindex < 0) return;
var priorities = this.form.optionsManager.get('file_priorities');
priorities[node.attributes.fileindex] = newValue;
this.form.optionsManager.update('file_priorities', priorities);
}, this);
}
}
onFilesChecked: function(nodes, newValue, oldValue) {
if (this.form.optionsManager.get('compact_allocation')) {
Ext.Msg.show({
title: _('Unable to set file priority!'),
msg: _('File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?'),
buttons: Ext.Msg.YESNO,
fn: function(result) {
if (result == 'yes') {
this.form.optionsManager.update('compact_allocation', false);
Ext.each(nodes, function(node) {
if (node.attributes.fileindex < 0) return;
var priorities = this.form.optionsManager.get('file_priorities');
priorities[node.attributes.fileindex] = newValue;
this.form.optionsManager.update('file_priorities', priorities);
}, this);
} else {
this.files.setDownload(nodes[0], oldValue, true);
}
},
scope: this,
icon: Ext.MessageBox.QUESTION
});
} else {
Ext.each(nodes, function(node) {
if (node.attributes.fileindex < 0) return;
var priorities = this.form.optionsManager.get('file_priorities');
priorities[node.attributes.fileindex] = newValue;
this.form.optionsManager.update('file_priorities', priorities);
}, this);
}
}
});

View file

@ -37,148 +37,148 @@ Ext.ns('Deluge.add');
*/
Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
title: _('Options'),
height: 170,
title: _('Options'),
height: 170,
border: false,
bodyStyle: 'padding: 5px',
disabled: true,
labelWidth: 1,
border: false,
bodyStyle: 'padding: 5px',
disabled: true,
labelWidth: 1,
initComponent: function() {
Deluge.add.OptionsTab.superclass.initComponent.call(this);
initComponent: function() {
Deluge.add.OptionsTab.superclass.initComponent.call(this);
this.optionsManager = new Deluge.MultiOptionsManager();
this.optionsManager = new Deluge.MultiOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
title: _('Download Location'),
border: false,
autoHeight: true,
defaultType: 'textfield',
labelWidth: 1,
fieldLabel: '',
style: 'padding-bottom: 5px; margin-bottom: 0px;'
});
var fieldset = this.add({
xtype: 'fieldset',
title: _('Download Location'),
border: false,
autoHeight: true,
defaultType: 'textfield',
labelWidth: 1,
fieldLabel: '',
style: 'padding-bottom: 5px; margin-bottom: 0px;'
});
this.optionsManager.bind('download_location', fieldset.add({
fieldLabel: '',
name: 'download_location',
width: 400,
labelSeparator: ''
}));
var panel = this.add({
border: false,
layout: 'column',
defaultType: 'fieldset'
});
fieldset = panel.add({
title: _('Allocation'),
border: false,
autoHeight: true,
defaultType: 'radio',
width: 100
});
this.optionsManager.bind('download_location', fieldset.add({
fieldLabel: '',
name: 'download_location',
width: 400,
labelSeparator: ''
}));
var panel = this.add({
border: false,
layout: 'column',
defaultType: 'fieldset'
});
fieldset = panel.add({
title: _('Allocation'),
border: false,
autoHeight: true,
defaultType: 'radio',
width: 100
});
this.optionsManager.bind('compact_allocation', fieldset.add({
xtype: 'radiogroup',
columns: 1,
vertical: true,
labelSeparator: '',
items: [{
name: 'compact_allocation',
value: false,
inputValue: false,
boxLabel: _('Full'),
fieldLabel: '',
labelSeparator: ''
}, {
name: 'compact_allocation',
value: true,
inputValue: true,
boxLabel: _('Compact'),
fieldLabel: '',
labelSeparator: ''
}]
}));
this.optionsManager.bind('compact_allocation', fieldset.add({
xtype: 'radiogroup',
columns: 1,
vertical: true,
labelSeparator: '',
items: [{
name: 'compact_allocation',
value: false,
inputValue: false,
boxLabel: _('Full'),
fieldLabel: '',
labelSeparator: ''
}, {
name: 'compact_allocation',
value: true,
inputValue: true,
boxLabel: _('Compact'),
fieldLabel: '',
labelSeparator: ''
}]
}));
fieldset = panel.add({
title: _('Bandwidth'),
border: false,
autoHeight: true,
labelWidth: 100,
width: 200,
defaultType: 'spinnerfield'
});
this.optionsManager.bind('max_download_speed', fieldset.add({
fieldLabel: _('Max Down Speed'),
labelStyle: 'margin-left: 10px',
name: 'max_download_speed',
width: 60
}));
this.optionsManager.bind('max_upload_speed', fieldset.add({
fieldLabel: _('Max Up Speed'),
labelStyle: 'margin-left: 10px',
name: 'max_upload_speed',
width: 60
}));
this.optionsManager.bind('max_connections', fieldset.add({
fieldLabel: _('Max Connections'),
labelStyle: 'margin-left: 10px',
name: 'max_connections',
width: 60
}));
this.optionsManager.bind('max_upload_slots', fieldset.add({
fieldLabel: _('Max Upload Slots'),
labelStyle: 'margin-left: 10px',
name: 'max_upload_slots',
width: 60
}));
fieldset = panel.add({
title: _('General'),
border: false,
autoHeight: true,
defaultType: 'checkbox'
});
this.optionsManager.bind('add_paused', fieldset.add({
name: 'add_paused',
boxLabel: _('Add In Paused State'),
fieldLabel: '',
labelSeparator: ''
}));
this.optionsManager.bind('prioritize_first_last_pieces', fieldset.add({
name: 'prioritize_first_last_pieces',
boxLabel: _('Prioritize First/Last Pieces'),
fieldLabel: '',
labelSeparator: ''
}));
},
fieldset = panel.add({
title: _('Bandwidth'),
border: false,
autoHeight: true,
labelWidth: 100,
width: 200,
defaultType: 'spinnerfield'
});
this.optionsManager.bind('max_download_speed', fieldset.add({
fieldLabel: _('Max Down Speed'),
labelStyle: 'margin-left: 10px',
name: 'max_download_speed',
width: 60
}));
this.optionsManager.bind('max_upload_speed', fieldset.add({
fieldLabel: _('Max Up Speed'),
labelStyle: 'margin-left: 10px',
name: 'max_upload_speed',
width: 60
}));
this.optionsManager.bind('max_connections', fieldset.add({
fieldLabel: _('Max Connections'),
labelStyle: 'margin-left: 10px',
name: 'max_connections',
width: 60
}));
this.optionsManager.bind('max_upload_slots', fieldset.add({
fieldLabel: _('Max Upload Slots'),
labelStyle: 'margin-left: 10px',
name: 'max_upload_slots',
width: 60
}));
fieldset = panel.add({
title: _('General'),
border: false,
autoHeight: true,
defaultType: 'checkbox'
});
this.optionsManager.bind('add_paused', fieldset.add({
name: 'add_paused',
boxLabel: _('Add In Paused State'),
fieldLabel: '',
labelSeparator: ''
}));
this.optionsManager.bind('prioritize_first_last_pieces', fieldset.add({
name: 'prioritize_first_last_pieces',
boxLabel: _('Prioritize First/Last Pieces'),
fieldLabel: '',
labelSeparator: ''
}));
},
getDefaults: function() {
var keys = ['add_paused','compact_allocation','download_location',
'max_connections_per_torrent','max_download_speed_per_torrent',
'max_upload_slots_per_torrent','max_upload_speed_per_torrent',
'prioritize_first_last_pieces'];
getDefaults: function() {
var keys = ['add_paused','compact_allocation','download_location',
'max_connections_per_torrent','max_download_speed_per_torrent',
'max_upload_slots_per_torrent','max_upload_speed_per_torrent',
'prioritize_first_last_pieces'];
deluge.client.core.get_config_values(keys, {
success: function(config) {
var options = {
'file_priorities': [],
'add_paused': config.add_paused,
'compact_allocation': config.compact_allocation,
'download_location': config.download_location,
'max_connections': config.max_connections_per_torrent,
'max_download_speed': config.max_download_speed_per_torrent,
'max_upload_slots': config.max_upload_slots_per_torrent,
'max_upload_speed': config.max_upload_speed_per_torrent,
'prioritize_first_last_pieces': config.prioritize_first_last_pieces
}
this.optionsManager.options = options;
this.optionsManager.resetAll();
},
scope: this
});
}
deluge.client.core.get_config_values(keys, {
success: function(config) {
var options = {
'file_priorities': [],
'add_paused': config.add_paused,
'compact_allocation': config.compact_allocation,
'download_location': config.download_location,
'max_connections': config.max_connections_per_torrent,
'max_download_speed': config.max_download_speed_per_torrent,
'max_upload_slots': config.max_upload_slots_per_torrent,
'max_upload_speed': config.max_upload_speed_per_torrent,
'prioritize_first_last_pieces': config.prioritize_first_last_pieces
}
this.optionsManager.options = options;
this.optionsManager.resetAll();
},
scope: this
});
}
});

View file

@ -45,9 +45,9 @@ Deluge.add.Window = Ext.extend(Ext.Window, {
);
},
/**
* Create an id for the torrent before we have any info about it.
*/
/**
* Create an id for the torrent before we have any info about it.
*/
createTorrentId: function() {
return new Date().getTime();
}

View file

@ -43,27 +43,27 @@ Ext.namespace('Deluge.data');
* @param {Object} data The peer data
*/
Deluge.data.Peer = Ext.data.Record.create([
{
name: 'country',
type: 'string'
}, {
name: 'ip',
type: 'string',
sortType: Deluge.data.SortTypes.asIPAddress
}, {
name: 'client',
type: 'string'
}, {
name: 'progress',
type: 'float'
}, {
name: 'down_speed',
type: 'int'
}, {
name: 'up_speed',
type: 'int'
}, {
name: 'seed',
type: 'int'
}
{
name: 'country',
type: 'string'
}, {
name: 'ip',
type: 'string',
sortType: Deluge.data.SortTypes.asIPAddress
}, {
name: 'client',
type: 'string'
}, {
name: 'progress',
type: 'float'
}, {
name: 'down_speed',
type: 'int'
}, {
name: 'up_speed',
type: 'int'
}, {
name: 'seed',
type: 'int'
}
]);

View file

@ -41,12 +41,12 @@ Ext.namespace('Deluge.data');
* @singleton
*/
Deluge.data.SortTypes = {
asIPAddress: function(value) {
var d = value.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);
return ((((((+d[1])*256)+(+d[2]))*256)+(+d[3]))*256)+(+d[4]);
},
asIPAddress: function(value) {
var d = value.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);
return ((((((+d[1])*256)+(+d[2]))*256)+(+d[3]))*256)+(+d[4]);
},
asQueuePosition: function(value) {
return (value > -1) ? value : Number.MAX_VALUE;
}
asQueuePosition: function(value) {
return (value > -1) ? value : Number.MAX_VALUE;
}
}

View file

@ -43,52 +43,52 @@ Ext.namespace('Deluge.data');
* @param {Object} data The torrents data
*/
Deluge.data.Torrent = Ext.data.Record.create([{
name: 'queue',
type: 'int'
}, {
name: 'name',
type: 'string'
}, {
name: 'total_size',
type: 'int'
}, {
name: 'state',
type: 'string'
}, {
name: 'progress',
type: 'int'
}, {
name: 'num_seeds',
type: 'int'
}, {
name: 'total_seeds',
type: 'int'
}, {
name: 'num_peers',
type: 'int'
}, {
name: 'total_peers',
type: 'int'
}, {
name: 'download_payload_rate',
type: 'int'
}, {
name: 'upload_payload_rate',
type: 'int'
}, {
name: 'eta',
type: 'int'
}, {
name: 'ratio',
type: 'float'
}, {
name: 'distributed_copies',
type: 'float'
}, {
name: 'time_added',
type: 'int'
}, {
name: 'tracker_host',
type: 'string'
}
name: 'queue',
type: 'int'
}, {
name: 'name',
type: 'string'
}, {
name: 'total_size',
type: 'int'
}, {
name: 'state',
type: 'string'
}, {
name: 'progress',
type: 'int'
}, {
name: 'num_seeds',
type: 'int'
}, {
name: 'total_seeds',
type: 'int'
}, {
name: 'num_peers',
type: 'int'
}, {
name: 'total_peers',
type: 'int'
}, {
name: 'download_payload_rate',
type: 'int'
}, {
name: 'upload_payload_rate',
type: 'int'
}, {
name: 'eta',
type: 'int'
}, {
name: 'ratio',
type: 'float'
}, {
name: 'distributed_copies',
type: 'float'
}, {
name: 'time_added',
type: 'int'
}, {
name: 'tracker_host',
type: 'string'
}
]);

View file

@ -36,69 +36,69 @@ Ext.namespace('Deluge.details');
*/
Deluge.details.DetailsPanel = Ext.extend(Ext.TabPanel, {
region: 'south',
id: 'torrentDetails',
split: true,
height: 210,
minSize: 100,
collapsible: true,
margins: '0 5 5 5',
activeTab: 0,
initComponent: function() {
Deluge.details.DetailsPanel.superclass.initComponent.call(this);
this.add(new Deluge.details.StatusTab());
this.add(new Deluge.details.DetailsTab());
this.add(new Deluge.details.FilesTab());
this.add(new Deluge.details.PeersTab());
this.add(new Deluge.details.OptionsTab());
},
clear: function() {
this.items.each(function(panel) {
if (panel.clear) {
panel.clear.defer(100, panel);
panel.disable();
}
});
},
update: function(tab) {
var torrent = deluge.torrents.getSelected();
if (!torrent) {
this.clear();
return;
}
this.items.each(function(tab) {
if (tab.disabled) tab.enable();
});
tab = tab || this.getActiveTab();
if (tab.update) tab.update(torrent.id);
},
/* Event Handlers */
// We need to add the events in onRender since Deluge.Torrents hasn't
// been created yet.
onRender: function(ct, position) {
Deluge.details.DetailsPanel.superclass.onRender.call(this, ct, position);
deluge.events.on('disconnect', this.clear, this);
deluge.torrents.on('rowclick', this.onTorrentsClick, this);
this.on('tabchange', this.onTabChange, this);
deluge.torrents.getSelectionModel().on('selectionchange', function(selModel) {
if (!selModel.hasSelection()) this.clear();
}, this);
},
onTabChange: function(panel, tab) {
this.update(tab);
},
onTorrentsClick: function(grid, rowIndex, e) {
this.update();
}
region: 'south',
id: 'torrentDetails',
split: true,
height: 210,
minSize: 100,
collapsible: true,
margins: '0 5 5 5',
activeTab: 0,
initComponent: function() {
Deluge.details.DetailsPanel.superclass.initComponent.call(this);
this.add(new Deluge.details.StatusTab());
this.add(new Deluge.details.DetailsTab());
this.add(new Deluge.details.FilesTab());
this.add(new Deluge.details.PeersTab());
this.add(new Deluge.details.OptionsTab());
},
clear: function() {
this.items.each(function(panel) {
if (panel.clear) {
panel.clear.defer(100, panel);
panel.disable();
}
});
},
update: function(tab) {
var torrent = deluge.torrents.getSelected();
if (!torrent) {
this.clear();
return;
}
this.items.each(function(tab) {
if (tab.disabled) tab.enable();
});
tab = tab || this.getActiveTab();
if (tab.update) tab.update(torrent.id);
},
/* Event Handlers */
// We need to add the events in onRender since Deluge.Torrents hasn't
// been created yet.
onRender: function(ct, position) {
Deluge.details.DetailsPanel.superclass.onRender.call(this, ct, position);
deluge.events.on('disconnect', this.clear, this);
deluge.torrents.on('rowclick', this.onTorrentsClick, this);
this.on('tabchange', this.onTabChange, this);
deluge.torrents.getSelectionModel().on('selectionchange', function(selModel) {
if (!selModel.hasSelection()) this.clear();
}, this);
},
onTabChange: function(panel, tab) {
this.update(tab);
},
onTorrentsClick: function(grid, rowIndex, e) {
this.update();
}
});

View file

@ -1,115 +1,115 @@
/*
Script: Deluge.Details.Details.js
The details tab displayed in the details panel.
The details tab displayed in the details panel.
Copyright:
(C) Damien Churchill 2009-2010 <damoxc@gmail.com>
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.
(C) Damien Churchill 2009-2010 <damoxc@gmail.com>
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.
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.
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.
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.
*/
Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
title: _('Details'),
title: _('Details'),
fields: {},
fields: {},
queuedItems: {},
queuedItems: {},
oldData: {},
oldData: {},
initComponent: function() {
Deluge.details.DetailsTab.superclass.initComponent.call(this);
this.addItem('torrent_name', _('Name'));
this.addItem('hash', _('Hash'));
this.addItem('path', _('Path'));
this.addItem('size', _('Total Size'));
this.addItem('files', _('# of files'));
this.addItem('comment', _('Comment'));
this.addItem('status', _('Status'));
this.addItem('tracker', _('Tracker'));
},
initComponent: function() {
Deluge.details.DetailsTab.superclass.initComponent.call(this);
this.addItem('torrent_name', _('Name'));
this.addItem('hash', _('Hash'));
this.addItem('path', _('Path'));
this.addItem('size', _('Total Size'));
this.addItem('files', _('# of files'));
this.addItem('comment', _('Comment'));
this.addItem('status', _('Status'));
this.addItem('tracker', _('Tracker'));
},
onRender: function(ct, position) {
Deluge.details.DetailsTab.superclass.onRender.call(this, ct, position);
this.body.setStyle('padding', '10px');
this.dl = Ext.DomHelper.append(this.body, {tag: 'dl'}, true);
onRender: function(ct, position) {
Deluge.details.DetailsTab.superclass.onRender.call(this, ct, position);
this.body.setStyle('padding', '10px');
this.dl = Ext.DomHelper.append(this.body, {tag: 'dl'}, true);
for (var id in this.queuedItems) {
this.doAddItem(id, this.queuedItems[id]);
}
},
for (var id in this.queuedItems) {
this.doAddItem(id, this.queuedItems[id]);
}
},
addItem: function(id, label) {
if (!this.rendered) {
this.queuedItems[id] = label;
} else {
this.doAddItem(id, label);
}
},
addItem: function(id, label) {
if (!this.rendered) {
this.queuedItems[id] = label;
} else {
this.doAddItem(id, label);
}
},
// private
doAddItem: function(id, label) {
Ext.DomHelper.append(this.dl, {tag: 'dt', cls: id, html: label + ':'});
this.fields[id] = Ext.DomHelper.append(this.dl, {tag: 'dd', cls: id, html: ''}, true);
},
// private
doAddItem: function(id, label) {
Ext.DomHelper.append(this.dl, {tag: 'dt', cls: id, html: label + ':'});
this.fields[id] = Ext.DomHelper.append(this.dl, {tag: 'dd', cls: id, html: ''}, true);
},
clear: function() {
if (!this.fields) return;
for (var k in this.fields) {
this.fields[k].dom.innerHTML = '';
}
this.oldData = {}
},
clear: function() {
if (!this.fields) return;
for (var k in this.fields) {
this.fields[k].dom.innerHTML = '';
}
this.oldData = {}
},
update: function(torrentId) {
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Details, {
success: this.onRequestComplete,
scope: this,
torrentId: torrentId
});
},
update: function(torrentId) {
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Details, {
success: this.onRequestComplete,
scope: this,
torrentId: torrentId
});
},
onRequestComplete: function(torrent, request, response, options) {
var data = {
torrent_name: torrent.name,
hash: options.options.torrentId,
path: torrent.save_path,
size: fsize(torrent.total_size),
files: torrent.num_files,
status: torrent.message,
tracker: torrent.tracker,
comment: torrent.comment
};
onRequestComplete: function(torrent, request, response, options) {
var data = {
torrent_name: torrent.name,
hash: options.options.torrentId,
path: torrent.save_path,
size: fsize(torrent.total_size),
files: torrent.num_files,
status: torrent.message,
tracker: torrent.tracker,
comment: torrent.comment
};
for (var field in this.fields) {
if (!Ext.isDefined(data[field])) continue; // this is a field we aren't responsible for.
if (data[field] == this.oldData[field]) continue;
this.fields[field].dom.innerHTML = Ext.escapeHTML(data[field]);
}
this.oldData = data;
}
for (var field in this.fields) {
if (!Ext.isDefined(data[field])) continue; // this is a field we aren't responsible for.
if (data[field] == this.oldData[field]) continue;
this.fields[field].dom.innerHTML = Ext.escapeHTML(data[field]);
}
this.oldData = data;
}
});

View file

@ -29,200 +29,200 @@
* this exception statement from your version. If you delete this exception
* statement from all source files in the program, then also delete it here.
*/
Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
title: _('Files'),
title: _('Files'),
autoScroll: true,
rootVisible: false,
autoScroll: true,
rootVisible: false,
columns: [{
header: _('Filename'),
width: 330,
dataIndex: 'filename'
}, {
header: _('Size'),
width: 150,
dataIndex: 'size',
tpl: new Ext.XTemplate('{size:this.fsize}', {
fsize: function(v) { return fsize(v); }
})
}, {
xtype: 'tgrendercolumn',
header: _('Progress'),
width: 150,
dataIndex: 'progress',
renderer: function(v) {
var progress = v * 100;
return Deluge.progressBar(progress, this.col.width, progress.toFixed(2) + '%', 0);
}
}, {
header: _('Priority'),
width: 150,
dataIndex: 'priority',
tpl: new Ext.XTemplate('<tpl if="!isNaN(priority)">' +
'<div class="{priority:this.getClass}">' +
'{priority:this.getName}' +
'</div></tpl>', {
getClass: function(v) {
return FILE_PRIORITY_CSS[v];
},
columns: [{
header: _('Filename'),
width: 330,
dataIndex: 'filename'
}, {
header: _('Size'),
width: 150,
dataIndex: 'size',
tpl: new Ext.XTemplate('{size:this.fsize}', {
fsize: function(v) { return fsize(v); }
})
}, {
xtype: 'tgrendercolumn',
header: _('Progress'),
width: 150,
dataIndex: 'progress',
renderer: function(v) {
var progress = v * 100;
return Deluge.progressBar(progress, this.col.width, progress.toFixed(2) + '%', 0);
}
}, {
header: _('Priority'),
width: 150,
dataIndex: 'priority',
tpl: new Ext.XTemplate('<tpl if="!isNaN(priority)">' +
'<div class="{priority:this.getClass}">' +
'{priority:this.getName}' +
'</div></tpl>', {
getClass: function(v) {
return FILE_PRIORITY_CSS[v];
},
getName: function(v) {
return _(FILE_PRIORITY[v]);
}
})
}],
selModel: new Ext.tree.MultiSelectionModel(),
getName: function(v) {
return _(FILE_PRIORITY[v]);
}
})
}],
selModel: new Ext.tree.MultiSelectionModel(),
initComponent: function() {
Deluge.details.FilesTab.superclass.initComponent.call(this);
this.setRootNode(new Ext.tree.TreeNode({text: 'Files'}));
},
initComponent: function() {
Deluge.details.FilesTab.superclass.initComponent.call(this);
this.setRootNode(new Ext.tree.TreeNode({text: 'Files'}));
},
clear: function() {
var root = this.getRootNode();
if (!root.hasChildNodes()) return;
root.cascade(function(node) {
var parentNode = node.parentNode;
if (!parentNode) return;
if (!parentNode.ownerTree) return;
parentNode.removeChild(node);
});
},
clear: function() {
var root = this.getRootNode();
if (!root.hasChildNodes()) return;
root.cascade(function(node) {
var parentNode = node.parentNode;
if (!parentNode) return;
if (!parentNode.ownerTree) return;
parentNode.removeChild(node);
});
},
createFileTree: function(files) {
function walk(files, parentNode) {
for (var file in files.contents) {
var item = files.contents[file];
if (item.type == 'dir') {
walk(item, parentNode.appendChild(new Ext.tree.TreeNode({
text: file,
filename: file,
size: item.size,
progress: item.progress,
priority: item.priority
})));
} else {
parentNode.appendChild(new Ext.tree.TreeNode({
text: file,
filename: file,
fileIndex: item.index,
size: item.size,
progress: item.progress,
priority: item.priority,
leaf: true,
iconCls: 'x-deluge-file',
uiProvider: Ext.ux.tree.TreeGridNodeUI
}));
}
}
}
var root = this.getRootNode();
walk(files, root);
root.firstChild.expand();
},
createFileTree: function(files) {
function walk(files, parentNode) {
for (var file in files.contents) {
var item = files.contents[file];
if (item.type == 'dir') {
walk(item, parentNode.appendChild(new Ext.tree.TreeNode({
text: file,
filename: file,
size: item.size,
progress: item.progress,
priority: item.priority
})));
} else {
parentNode.appendChild(new Ext.tree.TreeNode({
text: file,
filename: file,
fileIndex: item.index,
size: item.size,
progress: item.progress,
priority: item.priority,
leaf: true,
iconCls: 'x-deluge-file',
uiProvider: Ext.ux.tree.TreeGridNodeUI
}));
}
}
}
var root = this.getRootNode();
walk(files, root);
root.firstChild.expand();
},
update: function(torrentId) {
if (this.torrentId != torrentId) {
this.clear();
this.torrentId = torrentId;
}
deluge.client.web.get_torrent_files(torrentId, {
success: this.onRequestComplete,
scope: this,
torrentId: torrentId
});
},
update: function(torrentId) {
if (this.torrentId != torrentId) {
this.clear();
this.torrentId = torrentId;
}
deluge.client.web.get_torrent_files(torrentId, {
success: this.onRequestComplete,
scope: this,
torrentId: torrentId
});
},
updateFileTree: function(files) {
function walk(files, parentNode) {
for (var file in files.contents) {
var item = files.contents[file];
var node = parentNode.findChild('filename', file);
node.attributes.size = item.size;
node.attributes.progress = item.progress;
node.attributes.priority = item.priority;
node.ui.updateColumns();
if (item.type == 'dir') {
walk(item, node);
}
}
}
walk(files, this.getRootNode());
},
updateFileTree: function(files) {
function walk(files, parentNode) {
for (var file in files.contents) {
var item = files.contents[file];
var node = parentNode.findChild('filename', file);
node.attributes.size = item.size;
node.attributes.progress = item.progress;
node.attributes.priority = item.priority;
node.ui.updateColumns();
if (item.type == 'dir') {
walk(item, node);
}
}
}
walk(files, this.getRootNode());
},
onRender: function(ct, position) {
Deluge.details.FilesTab.superclass.onRender.call(this, ct, position);
deluge.menus.filePriorities.on('itemclick', this.onItemClick, this);
this.on('contextmenu', this.onContextMenu, this);
this.sorter = new Ext.tree.TreeSorter(this, {
folderSort: true
});
},
onContextMenu: function(node, e) {
e.stopEvent();
var selModel = this.getSelectionModel();
if (selModel.getSelectedNodes().length < 2) {
selModel.clearSelections();
node.select();
}
deluge.menus.filePriorities.showAt(e.getPoint());
},
onItemClick: function(baseItem, e) {
switch (baseItem.id) {
case 'expandAll':
this.expandAll();
break;
default:
var indexes = {};
function walk(node) {
if (Ext.isEmpty(node.attributes.fileIndex)) return;
indexes[node.attributes.fileIndex] = node.attributes.priority;
}
this.getRootNode().cascade(walk);
onRender: function(ct, position) {
Deluge.details.FilesTab.superclass.onRender.call(this, ct, position);
deluge.menus.filePriorities.on('itemclick', this.onItemClick, this);
this.on('contextmenu', this.onContextMenu, this);
this.sorter = new Ext.tree.TreeSorter(this, {
folderSort: true
});
},
onContextMenu: function(node, e) {
e.stopEvent();
var selModel = this.getSelectionModel();
if (selModel.getSelectedNodes().length < 2) {
selModel.clearSelections();
node.select();
}
deluge.menus.filePriorities.showAt(e.getPoint());
},
onItemClick: function(baseItem, e) {
switch (baseItem.id) {
case 'expandAll':
this.expandAll();
break;
default:
var indexes = {};
function walk(node) {
if (Ext.isEmpty(node.attributes.fileIndex)) return;
indexes[node.attributes.fileIndex] = node.attributes.priority;
}
this.getRootNode().cascade(walk);
var nodes = this.getSelectionModel().getSelectedNodes();
Ext.each(nodes, function(node) {
if (!node.isLeaf()) {
function setPriorities(node) {
if (Ext.isEmpty(node.attributes.fileIndex)) return;
indexes[node.attributes.fileIndex] = baseItem.filePriority;
}
node.cascade(setPriorities);
} else if (!Ext.isEmpty(node.attributes.fileIndex)) {
indexes[node.attributes.fileIndex] = baseItem.filePriority;
return;
}
});
var priorities = new Array(Ext.keys(indexes).length);
for (var index in indexes) {
priorities[index] = indexes[index];
}
var nodes = this.getSelectionModel().getSelectedNodes();
Ext.each(nodes, function(node) {
if (!node.isLeaf()) {
function setPriorities(node) {
if (Ext.isEmpty(node.attributes.fileIndex)) return;
indexes[node.attributes.fileIndex] = baseItem.filePriority;
}
node.cascade(setPriorities);
} else if (!Ext.isEmpty(node.attributes.fileIndex)) {
indexes[node.attributes.fileIndex] = baseItem.filePriority;
return;
}
});
var priorities = new Array(Ext.keys(indexes).length);
for (var index in indexes) {
priorities[index] = indexes[index];
}
deluge.client.core.set_torrent_file_priorities(this.torrentId, priorities, {
success: function() {
Ext.each(nodes, function(node) {
node.setColumnValue(3, baseItem.filePriority);
});
},
scope: this
});
break;
}
},
onRequestComplete: function(files, options) {
if (!this.getRootNode().hasChildNodes()) {
this.createFileTree(files);
} else {
this.updateFileTree(files);
}
}
deluge.client.core.set_torrent_file_priorities(this.torrentId, priorities, {
success: function() {
Ext.each(nodes, function(node) {
node.setColumnValue(3, baseItem.filePriority);
});
},
scope: this
});
break;
}
},
onRequestComplete: function(files, options) {
if (!this.getRootNode().hasChildNodes()) {
this.createFileTree(files);
} else {
this.updateFileTree(files);
}
}
});

View file

@ -33,382 +33,382 @@
Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
constructor: function(config) {
config = Ext.apply({
autoScroll: true,
bodyStyle: 'padding: 5px;',
border: false,
cls: 'x-deluge-options',
defaults: {
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
},
deferredRender: false,
layout: 'column',
title: _('Options')
}, config);
Deluge.details.OptionsTab.superclass.constructor.call(this, config);
},
constructor: function(config) {
config = Ext.apply({
autoScroll: true,
bodyStyle: 'padding: 5px;',
border: false,
cls: 'x-deluge-options',
defaults: {
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
},
deferredRender: false,
layout: 'column',
title: _('Options')
}, config);
Deluge.details.OptionsTab.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.details.OptionsTab.superclass.initComponent.call(this);
initComponent: function() {
Deluge.details.OptionsTab.superclass.initComponent.call(this);
this.fieldsets = {}, this.fields = {};
this.optionsManager = new Deluge.MultiOptionsManager({
options: {
'max_download_speed': -1,
'max_upload_speed': -1,
'max_connections': -1,
'max_upload_slots': -1,
'auto_managed': false,
'stop_at_ratio': false,
'stop_ratio': 2.0,
'remove_at_ratio': false,
'move_completed': false,
this.fieldsets = {}, this.fields = {};
this.optionsManager = new Deluge.MultiOptionsManager({
options: {
'max_download_speed': -1,
'max_upload_speed': -1,
'max_connections': -1,
'max_upload_slots': -1,
'auto_managed': false,
'stop_at_ratio': false,
'stop_ratio': 2.0,
'remove_at_ratio': false,
'move_completed': false,
'move_completed_path': '',
'private': false,
'prioritize_first_last': false
}
});
'private': false,
'prioritize_first_last': false
}
});
/*
* Bandwidth Options
*/
this.fieldsets.bandwidth = this.add({
xtype: 'fieldset',
defaultType: 'spinnerfield',
bodyStyle: 'padding: 5px',
/*
* Bandwidth Options
*/
this.fieldsets.bandwidth = this.add({
xtype: 'fieldset',
defaultType: 'spinnerfield',
bodyStyle: 'padding: 5px',
layout: 'table',
layoutConfig: {columns: 3},
labelWidth: 150,
layout: 'table',
layoutConfig: {columns: 3},
labelWidth: 150,
style: 'margin-left: 10px; margin-right: 5px; padding: 5px',
title: _('Bandwidth'),
width: 250
});
style: 'margin-left: 10px; margin-right: 5px; padding: 5px',
title: _('Bandwidth'),
width: 250
});
/*
* Max Download Speed
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Download Speed'),
forId: 'max_download_speed',
cls: 'x-deluge-options-label'
});
this.fields.max_download_speed = this.fieldsets.bandwidth.add({
id: 'max_download_speed',
name: 'max_download_speed',
width: 70,
strategy: {
xtype: 'number',
decimalPrecision: 1,
minValue: -1,
maxValue: 99999
}
});
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('KiB/s'),
style: 'margin-left: 10px'
});
/*
* Max Download Speed
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Download Speed'),
forId: 'max_download_speed',
cls: 'x-deluge-options-label'
});
this.fields.max_download_speed = this.fieldsets.bandwidth.add({
id: 'max_download_speed',
name: 'max_download_speed',
width: 70,
strategy: {
xtype: 'number',
decimalPrecision: 1,
minValue: -1,
maxValue: 99999
}
});
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('KiB/s'),
style: 'margin-left: 10px'
});
/*
* Max Upload Speed
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Upload Speed'),
forId: 'max_upload_speed',
cls: 'x-deluge-options-label'
});
this.fields.max_upload_speed = this.fieldsets.bandwidth.add({
id: 'max_upload_speed',
name: 'max_upload_speed',
width: 70,
value: -1,
strategy: {
xtype: 'number',
decimalPrecision: 1,
minValue: -1,
maxValue: 99999
}
});
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('KiB/s'),
style: 'margin-left: 10px'
});
/*
* Max Upload Speed
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Upload Speed'),
forId: 'max_upload_speed',
cls: 'x-deluge-options-label'
});
this.fields.max_upload_speed = this.fieldsets.bandwidth.add({
id: 'max_upload_speed',
name: 'max_upload_speed',
width: 70,
value: -1,
strategy: {
xtype: 'number',
decimalPrecision: 1,
minValue: -1,
maxValue: 99999
}
});
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('KiB/s'),
style: 'margin-left: 10px'
});
/*
* Max Connections
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Connections'),
forId: 'max_connections',
cls: 'x-deluge-options-label'
});
this.fields.max_connections = this.fieldsets.bandwidth.add({
id: 'max_connections',
name: 'max_connections',
width: 70,
value: -1,
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
},
colspan: 2
});
/*
* Max Connections
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Connections'),
forId: 'max_connections',
cls: 'x-deluge-options-label'
});
this.fields.max_connections = this.fieldsets.bandwidth.add({
id: 'max_connections',
name: 'max_connections',
width: 70,
value: -1,
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
},
colspan: 2
});
/*
* Max Upload Slots
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Upload Slots'),
forId: 'max_upload_slots',
cls: 'x-deluge-options-label'
});
this.fields.max_upload_slots = this.fieldsets.bandwidth.add({
id: 'max_upload_slots',
name: 'max_upload_slots',
width: 70,
value: -1,
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
},
colspan: 2
});
/*
* Max Upload Slots
*/
this.fieldsets.bandwidth.add({
xtype: 'label',
text: _('Max Upload Slots'),
forId: 'max_upload_slots',
cls: 'x-deluge-options-label'
});
this.fields.max_upload_slots = this.fieldsets.bandwidth.add({
id: 'max_upload_slots',
name: 'max_upload_slots',
width: 70,
value: -1,
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
},
colspan: 2
});
/*
* Queue Options
*/
this.fieldsets.queue = this.add({
xtype: 'fieldset',
title: _('Queue'),
style: 'margin-left: 5px; margin-right: 5px; padding: 5px',
width: 210,
/*
* Queue Options
*/
this.fieldsets.queue = this.add({
xtype: 'fieldset',
title: _('Queue'),
style: 'margin-left: 5px; margin-right: 5px; padding: 5px',
width: 210,
layout: 'table',
layoutConfig: {columns: 2},
labelWidth: 0,
layout: 'table',
layoutConfig: {columns: 2},
labelWidth: 0,
defaults: {
fieldLabel: '',
labelSeparator: ''
}
});
defaults: {
fieldLabel: '',
labelSeparator: ''
}
});
this.fields.auto_managed = this.fieldsets.queue.add({
xtype: 'checkbox',
fieldLabel: '',
labelSeparator: '',
name: 'is_auto_managed',
boxLabel: _('Auto Managed'),
width: 200,
colspan: 2
});
this.fields.auto_managed = this.fieldsets.queue.add({
xtype: 'checkbox',
fieldLabel: '',
labelSeparator: '',
name: 'is_auto_managed',
boxLabel: _('Auto Managed'),
width: 200,
colspan: 2
});
this.fields.stop_at_ratio = this.fieldsets.queue.add({
fieldLabel: '',
labelSeparator: '',
id: 'stop_at_ratio',
width: 120,
boxLabel: _('Stop seed at ratio'),
handler: this.onStopRatioChecked,
scope: this
});
this.fields.stop_at_ratio = this.fieldsets.queue.add({
fieldLabel: '',
labelSeparator: '',
id: 'stop_at_ratio',
width: 120,
boxLabel: _('Stop seed at ratio'),
handler: this.onStopRatioChecked,
scope: this
});
this.fields.stop_ratio = this.fieldsets.queue.add({
xtype: 'spinnerfield',
id: 'stop_ratio',
name: 'stop_ratio',
disabled: true,
width: 50,
value: 2.0,
strategy: {
xtype: 'number',
minValue: -1,
maxValue: 99999,
incrementValue: 0.1,
alternateIncrementValue: 1,
decimalPrecision: 1
}
});
this.fields.stop_ratio = this.fieldsets.queue.add({
xtype: 'spinnerfield',
id: 'stop_ratio',
name: 'stop_ratio',
disabled: true,
width: 50,
value: 2.0,
strategy: {
xtype: 'number',
minValue: -1,
maxValue: 99999,
incrementValue: 0.1,
alternateIncrementValue: 1,
decimalPrecision: 1
}
});
this.fields.remove_at_ratio = this.fieldsets.queue.add({
fieldLabel: '',
labelSeparator: '',
id: 'remove_at_ratio',
ctCls: 'x-deluge-indent-checkbox',
bodyStyle: 'padding-left: 10px',
boxLabel: _('Remove at ratio'),
disabled: true,
colspan: 2
});
this.fields.remove_at_ratio = this.fieldsets.queue.add({
fieldLabel: '',
labelSeparator: '',
id: 'remove_at_ratio',
ctCls: 'x-deluge-indent-checkbox',
bodyStyle: 'padding-left: 10px',
boxLabel: _('Remove at ratio'),
disabled: true,
colspan: 2
});
this.fields.move_completed = this.fieldsets.queue.add({
fieldLabel: '',
labelSeparator: '',
id: 'move_completed',
boxLabel: _('Move Completed'),
colspan: 2,
this.fields.move_completed = this.fieldsets.queue.add({
fieldLabel: '',
labelSeparator: '',
id: 'move_completed',
boxLabel: _('Move Completed'),
colspan: 2,
handler: this.onMoveCompletedChecked,
scope: this
});
});
this.fields.move_completed_path = this.fieldsets.queue.add({
xtype: 'textfield',
fieldLabel: '',
id: 'move_completed_path',
colspan: 3,
bodyStyle: 'margin-left: 20px',
bodyStyle: 'margin-left: 20px',
width: 180,
disabled: true
});
/*
* General Options
*/
this.rightColumn = this.add({
border: false,
autoHeight: true,
style: 'margin-left: 5px',
width: 210
});
/*
* General Options
*/
this.rightColumn = this.add({
border: false,
autoHeight: true,
style: 'margin-left: 5px',
width: 210
});
this.fieldsets.general = this.rightColumn.add({
xtype: 'fieldset',
autoHeight: true,
defaultType: 'checkbox',
title: _('General'),
layout: 'form'
});
this.fieldsets.general = this.rightColumn.add({
xtype: 'fieldset',
autoHeight: true,
defaultType: 'checkbox',
title: _('General'),
layout: 'form'
});
this.fields['private'] = this.fieldsets.general.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Private'),
id: 'private',
disabled: true
});
this.fields['private'] = this.fieldsets.general.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Private'),
id: 'private',
disabled: true
});
this.fields.prioritize_first_last = this.fieldsets.general.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Prioritize First/Last'),
id: 'prioritize_first_last'
});
this.fields.prioritize_first_last = this.fieldsets.general.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Prioritize First/Last'),
id: 'prioritize_first_last'
});
// Bind the fields so the options manager can manage them.
for (var id in this.fields) {
this.optionsManager.bind(id, this.fields[id]);
}
// Bind the fields so the options manager can manage them.
for (var id in this.fields) {
this.optionsManager.bind(id, this.fields[id]);
}
/*
* Buttons
*/
this.buttonPanel = this.rightColumn.add({
layout: 'hbox',
xtype: 'panel',
border: false
});
/*
* Buttons
*/
this.buttonPanel = this.rightColumn.add({
layout: 'hbox',
xtype: 'panel',
border: false
});
/*
* Edit Trackers button
*/
this.buttonPanel.add({
id: 'edit_trackers',
xtype: 'button',
text: _('Edit Trackers'),
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-edit-trackers',
border: false,
width: 100,
handler: this.onEditTrackers,
scope: this
});
/*
* Edit Trackers button
*/
this.buttonPanel.add({
id: 'edit_trackers',
xtype: 'button',
text: _('Edit Trackers'),
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-edit-trackers',
border: false,
width: 100,
handler: this.onEditTrackers,
scope: this
});
/*
* Apply button
*/
this.buttonPanel.add({
id: 'apply',
xtype: 'button',
text: _('Apply'),
style: 'margin-left: 10px;',
border: false,
width: 100,
handler: this.onApply,
scope: this
});
},
/*
* Apply button
*/
this.buttonPanel.add({
id: 'apply',
xtype: 'button',
text: _('Apply'),
style: 'margin-left: 10px;',
border: false,
width: 100,
handler: this.onApply,
scope: this
});
},
onRender: function(ct, position) {
Deluge.details.OptionsTab.superclass.onRender.call(this, ct, position);
onRender: function(ct, position) {
Deluge.details.OptionsTab.superclass.onRender.call(this, ct, position);
// This is another hack I think, so keep an eye out here when upgrading.
this.layout = new Ext.layout.ColumnLayout();
this.layout.setContainer(this);
this.doLayout();
},
// This is another hack I think, so keep an eye out here when upgrading.
this.layout = new Ext.layout.ColumnLayout();
this.layout.setContainer(this);
this.doLayout();
},
clear: function() {
if (this.torrentId == null) return;
this.torrentId = null;
this.optionsManager.changeId(null);
},
clear: function() {
if (this.torrentId == null) return;
this.torrentId = null;
this.optionsManager.changeId(null);
},
reset: function() {
if (this.torrentId) this.optionsManager.reset();
},
reset: function() {
if (this.torrentId) this.optionsManager.reset();
},
update: function(torrentId) {
if (this.torrentId && !torrentId) this.clear(); // we want to clear the pane if we get a null torrent torrentIds
update: function(torrentId) {
if (this.torrentId && !torrentId) this.clear(); // we want to clear the pane if we get a null torrent torrentIds
if (!torrentId) return; // we don't care about null torrentIds
if (!torrentId) return; // we don't care about null torrentIds
if (this.torrentId != torrentId) {
this.torrentId = torrentId;
this.optionsManager.changeId(torrentId);
}
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Options, {
success: this.onRequestComplete,
scope: this
});
},
if (this.torrentId != torrentId) {
this.torrentId = torrentId;
this.optionsManager.changeId(torrentId);
}
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Options, {
success: this.onRequestComplete,
scope: this
});
},
onApply: function() {
var changed = this.optionsManager.getDirty();
if (!Ext.isEmpty(changed['prioritize_first_last'])) {
var value = changed['prioritize_first_last'];
deluge.client.core.set_torrent_prioritize_first_last(this.torrentId, value, {
success: function() {
this.optionsManager.set('prioritize_first_last', value);
},
scope: this
});
}
deluge.client.core.set_torrent_options([this.torrentId], changed, {
success: function() {
this.optionsManager.commit();
},
scope: this
});
},
onApply: function() {
var changed = this.optionsManager.getDirty();
if (!Ext.isEmpty(changed['prioritize_first_last'])) {
var value = changed['prioritize_first_last'];
deluge.client.core.set_torrent_prioritize_first_last(this.torrentId, value, {
success: function() {
this.optionsManager.set('prioritize_first_last', value);
},
scope: this
});
}
deluge.client.core.set_torrent_options([this.torrentId], changed, {
success: function() {
this.optionsManager.commit();
},
scope: this
});
},
onEditTrackers: function() {
deluge.editTrackers.show();
},
onEditTrackers: function() {
deluge.editTrackers.show();
},
onMoveCompletedChecked: function(checkbox, checked) {
this.fields.move_completed_path.setDisabled(!checked);
@ -417,20 +417,20 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
this.fields.move_completed_path.focus();
},
onStopRatioChecked: function(checkbox, checked) {
this.fields.remove_at_ratio.setDisabled(!checked);
this.fields.stop_ratio.setDisabled(!checked);
},
onStopRatioChecked: function(checkbox, checked) {
this.fields.remove_at_ratio.setDisabled(!checked);
this.fields.stop_ratio.setDisabled(!checked);
},
onRequestComplete: function(torrent, options) {
this.fields['private'].setValue(torrent['private']);
this.fields['private'].setDisabled(true);
delete torrent['private'];
torrent['auto_managed'] = torrent['is_auto_managed'];
this.optionsManager.setDefault(torrent);
var stop_at_ratio = this.optionsManager.get('stop_at_ratio');
this.fields.remove_at_ratio.setDisabled(!stop_at_ratio);
this.fields.stop_ratio.setDisabled(!stop_at_ratio);
onRequestComplete: function(torrent, options) {
this.fields['private'].setValue(torrent['private']);
this.fields['private'].setDisabled(true);
delete torrent['private'];
torrent['auto_managed'] = torrent['is_auto_managed'];
this.optionsManager.setDefault(torrent);
var stop_at_ratio = this.optionsManager.get('stop_at_ratio');
this.fields.remove_at_ratio.setDisabled(!stop_at_ratio);
this.fields.stop_ratio.setDisabled(!stop_at_ratio);
this.fields.move_completed_path.setDisabled(!this.optionsManager.get('move_completed'));
}
}
});

View file

@ -31,102 +31,102 @@
*/
(function() {
function flagRenderer(value) {
if (!value.replace(' ', '').replace(' ', '')){
function flagRenderer(value) {
if (!value.replace(' ', '').replace(' ', '')){
return '';
}
return String.format('<img src="flag/{0}" />', value);
}
function peerAddressRenderer(value, p, record) {
var seed = (record.data['seed'] == 1024) ? 'x-deluge-seed' : 'x-deluge-peer'
return String.format('<div class="{0}">{1}</div>', seed, value);
}
function peerProgressRenderer(value) {
var progress = (value * 100).toFixed(0);
return Deluge.progressBar(progress, this.width - 8, progress + '%');
}
return String.format('<img src="flag/{0}" />', value);
}
function peerAddressRenderer(value, p, record) {
var seed = (record.data['seed'] == 1024) ? 'x-deluge-seed' : 'x-deluge-peer'
return String.format('<div class="{0}">{1}</div>', seed, value);
}
function peerProgressRenderer(value) {
var progress = (value * 100).toFixed(0);
return Deluge.progressBar(progress, this.width - 8, progress + '%');
}
Deluge.details.PeersTab = Ext.extend(Ext.grid.GridPanel, {
Deluge.details.PeersTab = Ext.extend(Ext.grid.GridPanel, {
// fast way to figure out if we have a peer already.
peers: {},
// fast way to figure out if we have a peer already.
peers: {},
constructor: function(config) {
config = Ext.apply({
title: _('Peers'),
cls: 'x-deluge-peers',
store: new Ext.data.Store({
reader: new Ext.data.JsonReader({
idProperty: 'ip',
root: 'peers'
}, Deluge.data.Peer)
}),
columns: [{
header: '&nbsp;',
width: 30,
sortable: true,
renderer: flagRenderer,
dataIndex: 'country'
}, {
header: 'Address',
width: 125,
sortable: true,
renderer: peerAddressRenderer,
dataIndex: 'ip'
}, {
header: 'Client',
width: 125,
sortable: true,
renderer: fplain,
dataIndex: 'client'
}, {
header: 'Progress',
width: 150,
sortable: true,
renderer: peerProgressRenderer,
dataIndex: 'progress'
}, {
header: 'Down Speed',
width: 100,
sortable: true,
renderer: fspeed,
dataIndex: 'down_speed'
}, {
header: 'Up Speed',
width: 100,
sortable: true,
renderer: fspeed,
dataIndex: 'up_speed'
}],
stripeRows: true,
deferredRender:false,
autoScroll:true
}, config);
Deluge.details.PeersTab.superclass.constructor.call(this, config);
},
constructor: function(config) {
config = Ext.apply({
title: _('Peers'),
cls: 'x-deluge-peers',
store: new Ext.data.Store({
reader: new Ext.data.JsonReader({
idProperty: 'ip',
root: 'peers'
}, Deluge.data.Peer)
}),
columns: [{
header: '&nbsp;',
width: 30,
sortable: true,
renderer: flagRenderer,
dataIndex: 'country'
}, {
header: 'Address',
width: 125,
sortable: true,
renderer: peerAddressRenderer,
dataIndex: 'ip'
}, {
header: 'Client',
width: 125,
sortable: true,
renderer: fplain,
dataIndex: 'client'
}, {
header: 'Progress',
width: 150,
sortable: true,
renderer: peerProgressRenderer,
dataIndex: 'progress'
}, {
header: 'Down Speed',
width: 100,
sortable: true,
renderer: fspeed,
dataIndex: 'down_speed'
}, {
header: 'Up Speed',
width: 100,
sortable: true,
renderer: fspeed,
dataIndex: 'up_speed'
}],
stripeRows: true,
deferredRender:false,
autoScroll:true
}, config);
Deluge.details.PeersTab.superclass.constructor.call(this, config);
},
clear: function() {
this.getStore().removeAll();
this.peers = {};
},
clear: function() {
this.getStore().removeAll();
this.peers = {};
},
update: function(torrentId) {
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Peers, {
success: this.onRequestComplete,
scope: this
});
},
update: function(torrentId) {
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Peers, {
success: this.onRequestComplete,
scope: this
});
},
onRequestComplete: function(torrent, options) {
if (!torrent) return;
onRequestComplete: function(torrent, options) {
if (!torrent) return;
var store = this.getStore();
var newPeers = [];
var addresses = {};
var store = this.getStore();
var newPeers = [];
var addresses = {};
// Go through the peers updating and creating peer records
Ext.each(torrent.peers, function(peer) {
if (this.peers[peer.ip]) {
// Go through the peers updating and creating peer records
Ext.each(torrent.peers, function(peer) {
if (this.peers[peer.ip]) {
var record = store.getById(peer.ip);
record.beginEdit();
for (var k in peer) {
@ -135,26 +135,26 @@
}
}
record.endEdit();
} else {
this.peers[peer.ip] = 1;
newPeers.push(new Deluge.data.Peer(peer, peer.ip));
}
addresses[peer.ip] = 1;
}, this);
store.add(newPeers);
} else {
this.peers[peer.ip] = 1;
newPeers.push(new Deluge.data.Peer(peer, peer.ip));
}
addresses[peer.ip] = 1;
}, this);
store.add(newPeers);
// Remove any peers that shouldn't be left in the store
store.each(function(record) {
if (!addresses[record.id]) {
store.remove(record);
delete this.peers[record.id];
}
}, this);
store.commitChanges();
// Remove any peers that shouldn't be left in the store
store.each(function(record) {
if (!addresses[record.id]) {
store.remove(record);
delete this.peers[record.id];
}
}, this);
store.commitChanges();
var sortState = store.getSortState();
if (!sortState) return;
store.sort(sortState.field, sortState.direction);
}
});
var sortState = store.getSortState();
if (!sortState) return;
store.sort(sortState.field, sortState.direction);
}
});
})();

View file

@ -36,90 +36,90 @@ Ext.ns('Deluge.details');
* @extends Ext.Panel
*/
Deluge.details.StatusTab = Ext.extend(Ext.Panel, {
title: _('Status'),
autoScroll: true,
onRender: function(ct, position) {
Deluge.details.StatusTab.superclass.onRender.call(this, ct, position);
this.progressBar = this.add({
xtype: 'progress',
cls: 'x-deluge-status-progressbar'
});
this.status = this.add({
cls: 'x-deluge-status',
id: 'deluge-details-status',
border: false,
width: 1000,
listeners: {
'render': {
fn: function(panel) {
panel.load({
url: deluge.config.base + 'render/tab_status.html',
text: _('Loading') + '...'
});
panel.getUpdater().on('update', this.onPanelUpdate, this);
},
scope: this
}
}
});
},
clear: function() {
this.progressBar.updateProgress(0, ' ');
for (var k in this.fields) {
this.fields[k].innerHTML = '';
}
},
update: function(torrentId) {
if (!this.fields) this.getFields();
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Status, {
success: this.onRequestComplete,
scope: this
});
},
onPanelUpdate: function(el, response) {
this.fields = {};
Ext.each(Ext.query('dd', this.status.body.dom), function(field) {
this.fields[field.className] = field;
}, this);
},
onRequestComplete: function(status) {
seeders = status.total_seeds > -1 ? status.num_seeds + ' (' + status.total_seeds + ')' : status.num_seeds
peers = status.total_peers > -1 ? status.num_peers + ' (' + status.total_peers + ')' : status.num_peers
var data = {
downloaded: fsize(status.total_done, true),
uploaded: fsize(status.total_uploaded, true),
share: (status.ratio == -1) ? '&infin;' : status.ratio.toFixed(3),
announce: ftime(status.next_announce),
tracker_status: status.tracker_status,
downspeed: (status.download_payload_rate) ? fspeed(status.download_payload_rate) : '0.0 KiB/s',
upspeed: (status.upload_payload_rate) ? fspeed(status.upload_payload_rate) : '0.0 KiB/s',
eta: ftime(status.eta),
pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')',
seeders: seeders,
peers: peers,
avail: status.distributed_copies.toFixed(3),
active_time: ftime(status.active_time),
seeding_time: ftime(status.seeding_time),
seed_rank: status.seed_rank,
time_added: fdate(status.time_added)
}
data.auto_managed = _((status.is_auto_managed) ? 'True' : 'False');
title: _('Status'),
autoScroll: true,
onRender: function(ct, position) {
Deluge.details.StatusTab.superclass.onRender.call(this, ct, position);
this.progressBar = this.add({
xtype: 'progress',
cls: 'x-deluge-status-progressbar'
});
this.status = this.add({
cls: 'x-deluge-status',
id: 'deluge-details-status',
border: false,
width: 1000,
listeners: {
'render': {
fn: function(panel) {
panel.load({
url: deluge.config.base + 'render/tab_status.html',
text: _('Loading') + '...'
});
panel.getUpdater().on('update', this.onPanelUpdate, this);
},
scope: this
}
}
});
},
clear: function() {
this.progressBar.updateProgress(0, ' ');
for (var k in this.fields) {
this.fields[k].innerHTML = '';
}
},
update: function(torrentId) {
if (!this.fields) this.getFields();
deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Status, {
success: this.onRequestComplete,
scope: this
});
},
onPanelUpdate: function(el, response) {
this.fields = {};
Ext.each(Ext.query('dd', this.status.body.dom), function(field) {
this.fields[field.className] = field;
}, this);
},
onRequestComplete: function(status) {
seeders = status.total_seeds > -1 ? status.num_seeds + ' (' + status.total_seeds + ')' : status.num_seeds
peers = status.total_peers > -1 ? status.num_peers + ' (' + status.total_peers + ')' : status.num_peers
var data = {
downloaded: fsize(status.total_done, true),
uploaded: fsize(status.total_uploaded, true),
share: (status.ratio == -1) ? '&infin;' : status.ratio.toFixed(3),
announce: ftime(status.next_announce),
tracker_status: status.tracker_status,
downspeed: (status.download_payload_rate) ? fspeed(status.download_payload_rate) : '0.0 KiB/s',
upspeed: (status.upload_payload_rate) ? fspeed(status.upload_payload_rate) : '0.0 KiB/s',
eta: ftime(status.eta),
pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')',
seeders: seeders,
peers: peers,
avail: status.distributed_copies.toFixed(3),
active_time: ftime(status.active_time),
seeding_time: ftime(status.seeding_time),
seed_rank: status.seed_rank,
time_added: fdate(status.time_added)
}
data.auto_managed = _((status.is_auto_managed) ? 'True' : 'False');
data.downloaded += ' (' + ((status.total_payload_download) ? fsize(status.total_payload_download) : '0.0 KiB') + ')';
data.uploaded += ' (' + ((status.total_payload_download) ? fsize(status.total_payload_download): '0.0 KiB') + ')';
for (var field in this.fields) {
this.fields[field].innerHTML = data[field];
}
var text = status.state + ' ' + status.progress.toFixed(2) + '%';
this.progressBar.updateProgress(status.progress / 100.0, text);
}
data.downloaded += ' (' + ((status.total_payload_download) ? fsize(status.total_payload_download) : '0.0 KiB') + ')';
data.uploaded += ' (' + ((status.total_payload_download) ? fsize(status.total_payload_download): '0.0 KiB') + ')';
for (var field in this.fields) {
this.fields[field].innerHTML = data[field];
}
var text = status.state + ' ' + status.progress.toFixed(2) + '%';
this.progressBar.updateProgress(status.progress / 100.0, text);
}
});

View file

@ -36,139 +36,139 @@ Ext.namespace('Deluge.preferences');
* @extends Ext.form.FormPanel
*/
Deluge.preferences.Bandwidth = Ext.extend(Ext.form.FormPanel, {
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Bandwidth'),
layout: 'form',
labelWidth: 10
}, config);
Deluge.preferences.Bandwidth.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.preferences.Bandwidth.superclass.initComponent.call(this);
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Global Bandwidth Usage'),
labelWidth: 200,
defaultType: 'spinnerfield',
defaults: {
minValue: -1,
maxValue: 99999
},
style: 'margin-bottom: 0px; padding-bottom: 0px;',
autoHeight: true
});
om.bind('max_connections_global', fieldset.add({
name: 'max_connections_global',
fieldLabel: _('Maximum Connections'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_upload_slots_global', fieldset.add({
name: 'max_upload_slots_global',
fieldLabel: _('Maximum Upload Slots'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_download_speed', fieldset.add({
name: 'max_download_speed',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 80,
value: -1.0,
decimalPrecision: 1
}));
om.bind('max_upload_speed', fieldset.add({
name: 'max_upload_speed',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 80,
value: -1.0,
decimalPrecision: 1
}));
om.bind('max_half_open_connections', fieldset.add({
name: 'max_half_open_connections',
fieldLabel: _('Maximum Half-Open Connections'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_connections_per_second', fieldset.add({
name: 'max_connections_per_second',
fieldLabel: _('Maximum Connection Attempts per Second'),
width: 80,
value: -1,
decimalPrecision: 0
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: '',
defaultType: 'checkbox',
style: 'padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;',
autoHeight: true
});
om.bind('ignore_limits_on_local_network', fieldset.add({
name: 'ignore_limits_on_local_network',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Ignore limits on local network')
}));
om.bind('rate_limit_ip_overhead', fieldset.add({
name: 'rate_limit_ip_overhead',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Rate limit IP overhead')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Per Torrent Bandwidth Usage'),
style: 'margin-bottom: 0px; padding-bottom: 0px;',
defaultType: 'spinnerfield',
labelWidth: 200,
defaults: {
minValue: -1,
maxValue: 99999
},
autoHeight: true
});
om.bind('max_connections_per_torrent', fieldset.add({
name: 'max_connections_per_torrent',
fieldLabel: _('Maximum Connections'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_upload_slots_per_torrent', fieldset.add({
name: 'max_upload_slots_per_torrent',
fieldLabel: _('Maximum Upload Slots'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_download_speed_per_torrent', fieldset.add({
name: 'max_download_speed_per_torrent',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_upload_speed_per_torrent', fieldset.add({
name: 'max_upload_speed_per_torrent',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 80,
value: -1,
decimalPrecision: 0
}));
}
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Bandwidth'),
layout: 'form',
labelWidth: 10
}, config);
Deluge.preferences.Bandwidth.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.preferences.Bandwidth.superclass.initComponent.call(this);
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Global Bandwidth Usage'),
labelWidth: 200,
defaultType: 'spinnerfield',
defaults: {
minValue: -1,
maxValue: 99999
},
style: 'margin-bottom: 0px; padding-bottom: 0px;',
autoHeight: true
});
om.bind('max_connections_global', fieldset.add({
name: 'max_connections_global',
fieldLabel: _('Maximum Connections'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_upload_slots_global', fieldset.add({
name: 'max_upload_slots_global',
fieldLabel: _('Maximum Upload Slots'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_download_speed', fieldset.add({
name: 'max_download_speed',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 80,
value: -1.0,
decimalPrecision: 1
}));
om.bind('max_upload_speed', fieldset.add({
name: 'max_upload_speed',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 80,
value: -1.0,
decimalPrecision: 1
}));
om.bind('max_half_open_connections', fieldset.add({
name: 'max_half_open_connections',
fieldLabel: _('Maximum Half-Open Connections'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_connections_per_second', fieldset.add({
name: 'max_connections_per_second',
fieldLabel: _('Maximum Connection Attempts per Second'),
width: 80,
value: -1,
decimalPrecision: 0
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: '',
defaultType: 'checkbox',
style: 'padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;',
autoHeight: true
});
om.bind('ignore_limits_on_local_network', fieldset.add({
name: 'ignore_limits_on_local_network',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Ignore limits on local network')
}));
om.bind('rate_limit_ip_overhead', fieldset.add({
name: 'rate_limit_ip_overhead',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Rate limit IP overhead')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Per Torrent Bandwidth Usage'),
style: 'margin-bottom: 0px; padding-bottom: 0px;',
defaultType: 'spinnerfield',
labelWidth: 200,
defaults: {
minValue: -1,
maxValue: 99999
},
autoHeight: true
});
om.bind('max_connections_per_torrent', fieldset.add({
name: 'max_connections_per_torrent',
fieldLabel: _('Maximum Connections'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_upload_slots_per_torrent', fieldset.add({
name: 'max_upload_slots_per_torrent',
fieldLabel: _('Maximum Upload Slots'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_download_speed_per_torrent', fieldset.add({
name: 'max_download_speed_per_torrent',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 80,
value: -1,
decimalPrecision: 0
}));
om.bind('max_upload_speed_per_torrent', fieldset.add({
name: 'max_upload_speed_per_torrent',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 80,
value: -1,
decimalPrecision: 0
}));
}
});

View file

@ -37,39 +37,39 @@ Ext.namespace('Deluge.preferences');
*/
Deluge.preferences.Cache = Ext.extend(Ext.form.FormPanel, {
border: false,
title: _('Cache'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Cache.superclass.initComponent.call(this);
border: false,
title: _('Cache'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Cache.superclass.initComponent.call(this);
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Settings'),
autoHeight: true,
labelWidth: 180,
defaultType: 'spinnerfield',
defaults: {
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
});
om.bind('cache_size', fieldset.add({
fieldLabel: _('Cache Size (16 KiB Blocks)'),
name: 'cache_size',
width: 60,
value: 512
}));
om.bind('cache_expiry', fieldset.add({
fieldLabel: _('Cache Expiry (seconds)'),
name: 'cache_expiry',
width: 60,
value: 60
}));
}
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Settings'),
autoHeight: true,
labelWidth: 180,
defaultType: 'spinnerfield',
defaults: {
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
});
om.bind('cache_size', fieldset.add({
fieldLabel: _('Cache Size (16 KiB Blocks)'),
name: 'cache_size',
width: 60,
value: 512
}));
om.bind('cache_expiry', fieldset.add({
fieldLabel: _('Cache Expiry (seconds)'),
name: 'cache_expiry',
width: 60,
value: 60
}));
}
});

View file

@ -37,61 +37,61 @@ Ext.namespace('Deluge.preferences');
*/
Deluge.preferences.Daemon = Ext.extend(Ext.form.FormPanel, {
border: false,
title: _('Daemon'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Daemon.superclass.initComponent.call(this);
border: false,
title: _('Daemon'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Daemon.superclass.initComponent.call(this);
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Port'),
autoHeight: true,
defaultType: 'spinnerfield'
});
om.bind('daemon_port', fieldset.add({
fieldLabel: _('Daemon port'),
name: 'daemon_port',
value: 58846,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Connections'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('allow_remote', fieldset.add({
fieldLabel: '',
height: 22,
labelSeparator: '',
boxLabel: _('Allow Remote Connections'),
name: 'allow_remote'
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Other'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('new_release_check', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 40,
boxLabel: _('Periodically check the website for new releases'),
id: 'new_release_check'
}));
}
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Port'),
autoHeight: true,
defaultType: 'spinnerfield'
});
om.bind('daemon_port', fieldset.add({
fieldLabel: _('Daemon port'),
name: 'daemon_port',
value: 58846,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Connections'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('allow_remote', fieldset.add({
fieldLabel: '',
height: 22,
labelSeparator: '',
boxLabel: _('Allow Remote Connections'),
name: 'allow_remote'
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Other'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('new_release_check', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 40,
boxLabel: _('Periodically check the website for new releases'),
id: 'new_release_check'
}));
}
});

View file

@ -36,114 +36,114 @@ Ext.namespace('Deluge.preferences');
* @extends Ext.form.FormPanel
*/
Deluge.preferences.Downloads = Ext.extend(Ext.FormPanel, {
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Downloads'),
layout: 'form',
autoHeight: true,
width: 320
}, config);
Deluge.preferences.Downloads.superclass.constructor.call(this, config);
},
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Downloads'),
layout: 'form',
autoHeight: true,
width: 320
}, config);
Deluge.preferences.Downloads.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.preferences.Downloads.superclass.initComponent.call(this);
initComponent: function() {
Deluge.preferences.Downloads.superclass.initComponent.call(this);
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Folders'),
labelWidth: 150,
defaultType: 'togglefield',
autoHeight: true,
labelAlign: 'top',
width: 300,
style: 'margin-bottom: 5px; padding-bottom: 5px;'
});
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Folders'),
labelWidth: 150,
defaultType: 'togglefield',
autoHeight: true,
labelAlign: 'top',
width: 300,
style: 'margin-bottom: 5px; padding-bottom: 5px;'
});
optMan.bind('download_location', fieldset.add({
xtype: 'textfield',
name: 'download_location',
fieldLabel: _('Download to'),
width: 280
}));
optMan.bind('download_location', fieldset.add({
xtype: 'textfield',
name: 'download_location',
fieldLabel: _('Download to'),
width: 280
}));
var field = fieldset.add({
name: 'move_completed_path',
fieldLabel: _('Move completed to'),
width: 280
});
optMan.bind('move_completed', field.toggle);
optMan.bind('move_completed_path', field.input);
var field = fieldset.add({
name: 'move_completed_path',
fieldLabel: _('Move completed to'),
width: 280
});
optMan.bind('move_completed', field.toggle);
optMan.bind('move_completed_path', field.input);
field = fieldset.add({
name: 'torrentfiles_location',
fieldLabel: _('Copy of .torrent files to'),
width: 280
});
optMan.bind('copy_torrent_file', field.toggle);
optMan.bind('torrentfiles_location', field.input);
field = fieldset.add({
name: 'torrentfiles_location',
fieldLabel: _('Copy of .torrent files to'),
width: 280
});
optMan.bind('copy_torrent_file', field.toggle);
optMan.bind('torrentfiles_location', field.input);
field = fieldset.add({
name: 'autoadd_location',
fieldLabel: _('Autoadd .torrent files from'),
width: 280
});
optMan.bind('autoadd_enable', field.toggle);
optMan.bind('autoadd_location', field.input);
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Allocation'),
autoHeight: true,
labelWidth: 1,
defaultType: 'radiogroup',
style: 'margin-bottom: 5px; margin-top: 0; padding-bottom: 5px; padding-top: 0;',
width: 240
});
optMan.bind('compact_allocation', fieldset.add({
name: 'compact_allocation',
width: 200,
labelSeparator: '',
//disabled: true,
defaults: {
width: 80,
height: 22,
name: 'compact_allocation'
},
items: [{
boxLabel: _('Use Full'),
inputValue: false
}, {
boxLabel: _('Use Compact'),
inputValue: true
}]
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Options'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
style: 'margin-bottom: 0; padding-bottom: 0;',
width: 280
});
optMan.bind('prioritize_first_last_pieces', fieldset.add({
name: 'prioritize_first_last_pieces',
labelSeparator: '',
height: 22,
boxLabel: _('Prioritize first and last pieces of torrent')
}));
optMan.bind('add_paused', fieldset.add({
name: 'add_paused',
labelSeparator: '',
height: 22,
boxLabel: _('Add torrents in Paused state')
}));
}
field = fieldset.add({
name: 'autoadd_location',
fieldLabel: _('Autoadd .torrent files from'),
width: 280
});
optMan.bind('autoadd_enable', field.toggle);
optMan.bind('autoadd_location', field.input);
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Allocation'),
autoHeight: true,
labelWidth: 1,
defaultType: 'radiogroup',
style: 'margin-bottom: 5px; margin-top: 0; padding-bottom: 5px; padding-top: 0;',
width: 240
});
optMan.bind('compact_allocation', fieldset.add({
name: 'compact_allocation',
width: 200,
labelSeparator: '',
//disabled: true,
defaults: {
width: 80,
height: 22,
name: 'compact_allocation'
},
items: [{
boxLabel: _('Use Full'),
inputValue: false
}, {
boxLabel: _('Use Compact'),
inputValue: true
}]
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Options'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
style: 'margin-bottom: 0; padding-bottom: 0;',
width: 280
});
optMan.bind('prioritize_first_last_pieces', fieldset.add({
name: 'prioritize_first_last_pieces',
labelSeparator: '',
height: 22,
boxLabel: _('Prioritize first and last pieces of torrent')
}));
optMan.bind('add_paused', fieldset.add({
name: 'add_paused',
labelSeparator: '',
height: 22,
boxLabel: _('Add torrents in Paused state')
}));
}
});

View file

@ -37,79 +37,79 @@ Ext.namespace('Deluge.preferences');
*/
Deluge.preferences.Encryption = Ext.extend(Ext.form.FormPanel, {
border: false,
title: _('Encryption'),
initComponent: function() {
Deluge.preferences.Encryption.superclass.initComponent.call(this);
border: false,
title: _('Encryption'),
initComponent: function() {
Deluge.preferences.Encryption.superclass.initComponent.call(this);
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Settings'),
autoHeight: true,
defaultType: 'combo',
width: 300
});
optMan.bind('enc_in_policy', fieldset.add({
fieldLabel: _('Inbound'),
mode: 'local',
width: 150,
store: new Ext.data.ArrayStore({
fields: ['id', 'text'],
data: [
[0, _('Forced')],
[1, _('Enabled')],
[2, _('Disabled')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
}));
optMan.bind('enc_out_policy', fieldset.add({
fieldLabel: _('Outbound'),
mode: 'local',
width: 150,
store: new Ext.data.SimpleStore({
fields: ['id', 'text'],
data: [
[0, _('Forced')],
[1, _('Enabled')],
[2, _('Disabled')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
}));
optMan.bind('enc_level', fieldset.add({
fieldLabel: _('Level'),
mode: 'local',
width: 150,
store: new Ext.data.SimpleStore({
fields: ['id', 'text'],
data: [
[0, _('Handshake')],
[1, _('Full Stream')],
[2, _('Either')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
}));
optMan.bind('enc_prefer_rc4', fieldset.add({
xtype: 'checkbox',
name: 'enc_prefer_rc4',
height: 40,
hideLabel: true,
boxLabel: _('Encrypt entire stream')
}));
}
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Settings'),
autoHeight: true,
defaultType: 'combo',
width: 300
});
optMan.bind('enc_in_policy', fieldset.add({
fieldLabel: _('Inbound'),
mode: 'local',
width: 150,
store: new Ext.data.ArrayStore({
fields: ['id', 'text'],
data: [
[0, _('Forced')],
[1, _('Enabled')],
[2, _('Disabled')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
}));
optMan.bind('enc_out_policy', fieldset.add({
fieldLabel: _('Outbound'),
mode: 'local',
width: 150,
store: new Ext.data.SimpleStore({
fields: ['id', 'text'],
data: [
[0, _('Forced')],
[1, _('Enabled')],
[2, _('Disabled')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
}));
optMan.bind('enc_level', fieldset.add({
fieldLabel: _('Level'),
mode: 'local',
width: 150,
store: new Ext.data.SimpleStore({
fields: ['id', 'text'],
data: [
[0, _('Handshake')],
[1, _('Full Stream')],
[2, _('Either')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
}));
optMan.bind('enc_prefer_rc4', fieldset.add({
xtype: 'checkbox',
name: 'enc_prefer_rc4',
height: 40,
hideLabel: true,
boxLabel: _('Encrypt entire stream')
}));
}
});

View file

@ -37,66 +37,66 @@ Ext.namespace('Deluge.preferences');
*/
Deluge.preferences.InstallPluginWindow = Ext.extend(Ext.Window, {
title: _('Install Plugin'),
layout: 'fit',
height: 115,
width: 350,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'center',
closeAction: 'hide',
iconCls: 'x-deluge-install-plugin',
modal: true,
plain: true,
title: _('Install Plugin'),
layout: 'fit',
height: 115,
width: 350,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'center',
closeAction: 'hide',
iconCls: 'x-deluge-install-plugin',
modal: true,
plain: true,
initComponent: function() {
Deluge.add.FileWindow.superclass.initComponent.call(this);
this.addButton(_('Install'), this.onInstall, this);
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
labelWidth: 70,
autoHeight: true,
fileUpload: true,
items: [{
xtype: 'fileuploadfield',
width: 240,
emptyText: _('Select an egg'),
fieldLabel: _('Plugin Egg'),
name: 'file',
buttonCfg: {
text: _('Browse') + '...'
}
}]
});
},
initComponent: function() {
Deluge.add.FileWindow.superclass.initComponent.call(this);
this.addButton(_('Install'), this.onInstall, this);
this.form = this.add({
xtype: 'form',
baseCls: 'x-plain',
labelWidth: 70,
autoHeight: true,
fileUpload: true,
items: [{
xtype: 'fileuploadfield',
width: 240,
emptyText: _('Select an egg'),
fieldLabel: _('Plugin Egg'),
name: 'file',
buttonCfg: {
text: _('Browse') + '...'
}
}]
});
},
onInstall: function(field, e) {
this.form.getForm().submit({
url: '/upload',
waitMsg: _('Uploading your plugin...'),
success: this.onUploadSuccess,
scope: this
});
},
onInstall: function(field, e) {
this.form.getForm().submit({
url: '/upload',
waitMsg: _('Uploading your plugin...'),
success: this.onUploadSuccess,
scope: this
});
},
onUploadPlugin: function(info, obj, response, request) {
this.fireEvent('pluginadded');
},
onUploadPlugin: function(info, obj, response, request) {
this.fireEvent('pluginadded');
},
onUploadSuccess: function(fp, upload) {
this.hide();
if (upload.result.success) {
var filename = this.form.getForm().getFieldValues().file;
filename = filename.split('\\').slice(-1)[0]
var path = upload.result.files[0];
this.form.getForm().setValues({file: ''});
deluge.client.web.upload_plugin(filename, path, {
success: this.onUploadPlugin,
scope: this,
filename: filename
});
}
}
onUploadSuccess: function(fp, upload) {
this.hide();
if (upload.result.success) {
var filename = this.form.getForm().getFieldValues().file;
filename = filename.split('\\').slice(-1)[0]
var path = upload.result.files[0];
this.form.getForm().setValues({file: ''});
deluge.client.web.upload_plugin(filename, path, {
success: this.onUploadPlugin,
scope: this,
filename: filename
});
}
}
});

View file

@ -37,219 +37,219 @@ Ext.namespace('Deluge.preferences');
*/
Deluge.preferences.Interface = Ext.extend(Ext.form.FormPanel, {
border: false,
title: _('Interface'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Interface.superclass.initComponent.call(this);
var om = this.optionsManager = new Deluge.OptionsManager();
this.on('show', this.onPageShow, this);
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Interface'),
style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('show_session_speed', fieldset.add({
name: 'show_session_speed',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Show session speed in titlebar')
}));
om.bind('sidebar_show_zero', fieldset.add({
name: 'sidebar_show_zero',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Show filters with zero torrents')
}));
om.bind('sidebar_multiple_filters', fieldset.add({
name: 'sidebar_multiple_filters',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Allow the use of multiple filters at once')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Password'),
style: 'margin-bottom: 0px; padding-bottom: 0px; padding-top: 5px',
autoHeight: true,
labelWidth: 110,
defaultType: 'textfield',
defaults: {
width: 180,
inputType: 'password'
}
});
this.oldPassword = fieldset.add({
name: 'old_password',
fieldLabel: _('Old Password')
});
this.newPassword = fieldset.add({
name: 'new_password',
fieldLabel: _('New Password')
});
this.confirmPassword = fieldset.add({
name: 'confirm_password',
fieldLabel: _('Confirm Password')
});
var panel = fieldset.add({
xtype: 'panel',
autoHeight: true,
border: false,
width: 320,
bodyStyle: 'padding-left: 230px'
})
panel.add({
xtype: 'button',
text: _('Change'),
listeners: {
'click': {
fn: this.onPasswordChange,
scope: this
}
}
});
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Server'),
style: 'margin-top: 0px; padding-top: 0px; margin-bottom: 0px; padding-bottom: 0px',
autoHeight: true,
labelWidth: 110,
defaultType: 'spinnerfield',
defaults: {
width: 80
}
});
om.bind('session_timeout', fieldset.add({
name: 'session_timeout',
fieldLabel: _('Session Timeout'),
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('port', fieldset.add({
name: 'port',
fieldLabel: _('Port'),
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
this.httpsField = om.bind('https', fieldset.add({
xtype: 'checkbox',
name: 'https',
hideLabel: true,
width: 280,
height: 22,
boxLabel: _('Use SSL (paths relative to Deluge config folder)')
}));
this.httpsField.on('check', this.onSSLCheck, this);
this.pkeyField = om.bind('pkey', fieldset.add({
xtype: 'textfield',
disabled: true,
name: 'pkey',
width: 180,
fieldLabel: _('Private Key')
}));
this.certField = om.bind('cert', fieldset.add({
xtype: 'textfield',
disabled: true,
name: 'cert',
width: 180,
fieldLabel: _('Certificate')
}));
},
onApply: function() {
var changed = this.optionsManager.getDirty();
if (!Ext.isObjectEmpty(changed)) {
deluge.client.web.set_config(changed, {
success: this.onSetConfig,
scope: this
});
border: false,
title: _('Interface'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Interface.superclass.initComponent.call(this);
var om = this.optionsManager = new Deluge.OptionsManager();
this.on('show', this.onPageShow, this);
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Interface'),
style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('show_session_speed', fieldset.add({
name: 'show_session_speed',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Show session speed in titlebar')
}));
om.bind('sidebar_show_zero', fieldset.add({
name: 'sidebar_show_zero',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Show filters with zero torrents')
}));
om.bind('sidebar_multiple_filters', fieldset.add({
name: 'sidebar_multiple_filters',
height: 22,
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Allow the use of multiple filters at once')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Password'),
style: 'margin-bottom: 0px; padding-bottom: 0px; padding-top: 5px',
autoHeight: true,
labelWidth: 110,
defaultType: 'textfield',
defaults: {
width: 180,
inputType: 'password'
}
});
this.oldPassword = fieldset.add({
name: 'old_password',
fieldLabel: _('Old Password')
});
this.newPassword = fieldset.add({
name: 'new_password',
fieldLabel: _('New Password')
});
this.confirmPassword = fieldset.add({
name: 'confirm_password',
fieldLabel: _('Confirm Password')
});
var panel = fieldset.add({
xtype: 'panel',
autoHeight: true,
border: false,
width: 320,
bodyStyle: 'padding-left: 230px'
})
panel.add({
xtype: 'button',
text: _('Change'),
listeners: {
'click': {
fn: this.onPasswordChange,
scope: this
}
}
});
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Server'),
style: 'margin-top: 0px; padding-top: 0px; margin-bottom: 0px; padding-bottom: 0px',
autoHeight: true,
labelWidth: 110,
defaultType: 'spinnerfield',
defaults: {
width: 80
}
});
om.bind('session_timeout', fieldset.add({
name: 'session_timeout',
fieldLabel: _('Session Timeout'),
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('port', fieldset.add({
name: 'port',
fieldLabel: _('Port'),
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
this.httpsField = om.bind('https', fieldset.add({
xtype: 'checkbox',
name: 'https',
hideLabel: true,
width: 280,
height: 22,
boxLabel: _('Use SSL (paths relative to Deluge config folder)')
}));
this.httpsField.on('check', this.onSSLCheck, this);
this.pkeyField = om.bind('pkey', fieldset.add({
xtype: 'textfield',
disabled: true,
name: 'pkey',
width: 180,
fieldLabel: _('Private Key')
}));
this.certField = om.bind('cert', fieldset.add({
xtype: 'textfield',
disabled: true,
name: 'cert',
width: 180,
fieldLabel: _('Certificate')
}));
},
onApply: function() {
var changed = this.optionsManager.getDirty();
if (!Ext.isObjectEmpty(changed)) {
deluge.client.web.set_config(changed, {
success: this.onSetConfig,
scope: this
});
for (var key in deluge.config) {
deluge.config[key] = this.optionsManager.get(key);
}
}
},
onGotConfig: function(config) {
this.optionsManager.set(config);
},
onPasswordChange: function() {
var newPassword = this.newPassword.getValue();
if (newPassword != this.confirmPassword.getValue()) {
Ext.MessageBox.show({
title: _('Invalid Password'),
msg: _('Your passwords don\'t match!'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
return;
}
var oldPassword = this.oldPassword.getValue();
deluge.client.auth.change_password(oldPassword, newPassword, {
success: function(result) {
if (!result) {
Ext.MessageBox.show({
title: _('Password'),
msg: _('Your old password was incorrect!'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
this.oldPassword.setValue('');
} else {
Ext.MessageBox.show({
title: _('Change Successful'),
msg: _('Your password was successfully changed!'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.INFO,
iconCls: 'x-deluge-icon-info'
});
this.oldPassword.setValue('');
this.newPassword.setValue('');
this.confirmPassword.setValue('');
}
},
scope: this
});
},
onSetConfig: function() {
this.optionsManager.commit();
},
onPageShow: function() {
deluge.client.web.get_config({
success: this.onGotConfig,
scope: this
})
},
onSSLCheck: function(e, checked) {
this.pkeyField.setDisabled(!checked);
this.certField.setDisabled(!checked);
}
for (var key in deluge.config) {
deluge.config[key] = this.optionsManager.get(key);
}
}
},
onGotConfig: function(config) {
this.optionsManager.set(config);
},
onPasswordChange: function() {
var newPassword = this.newPassword.getValue();
if (newPassword != this.confirmPassword.getValue()) {
Ext.MessageBox.show({
title: _('Invalid Password'),
msg: _('Your passwords don\'t match!'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
return;
}
var oldPassword = this.oldPassword.getValue();
deluge.client.auth.change_password(oldPassword, newPassword, {
success: function(result) {
if (!result) {
Ext.MessageBox.show({
title: _('Password'),
msg: _('Your old password was incorrect!'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
this.oldPassword.setValue('');
} else {
Ext.MessageBox.show({
title: _('Change Successful'),
msg: _('Your password was successfully changed!'),
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.INFO,
iconCls: 'x-deluge-icon-info'
});
this.oldPassword.setValue('');
this.newPassword.setValue('');
this.confirmPassword.setValue('');
}
},
scope: this
});
},
onSetConfig: function() {
this.optionsManager.commit();
},
onPageShow: function() {
deluge.client.web.get_config({
success: this.onGotConfig,
scope: this
})
},
onSSLCheck: function(e, checked) {
this.pkeyField.setDisabled(!checked);
this.certField.setDisabled(!checked);
}
});

View file

@ -36,195 +36,195 @@ Ext.namespace('Deluge.preferences');
* @extends Ext.form.FormPanel
*/
Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
border: false,
layout: 'form',
title: _('Network'),
border: false,
layout: 'form',
title: _('Network'),
initComponent: function() {
Deluge.preferences.Network.superclass.initComponent.call(this);
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Incoming Ports'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
optMan.bind('random_port', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Use Random Ports'),
name: 'random_port',
height: 22,
listeners: {
'check': {
fn: function(e, checked) {
this.listenPorts.setDisabled(checked);
},
scope: this
}
}
}));
this.listenPorts = fieldset.add({
xtype: 'spinnergroup',
name: 'listen_ports',
fieldLabel: '',
labelSeparator: '',
colCfg: {
labelWidth: 40,
style: 'margin-right: 10px;'
},
items: [{
fieldLabel: 'From',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}, {
fieldLabel: 'To',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}]
});
optMan.bind('listen_ports', this.listenPorts);
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Outgoing Ports'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
optMan.bind('random_outgoing_ports', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Use Random Ports'),
name: 'random_outgoing_ports',
height: 22,
listeners: {
'check': {
fn: function(e, checked) {
this.outgoingPorts.setDisabled(checked);
},
scope: this
}
}
}));
this.outgoingPorts = fieldset.add({
xtype: 'spinnergroup',
name: 'outgoing_ports',
fieldLabel: '',
labelSeparator: '',
colCfg: {
labelWidth: 40,
style: 'margin-right: 10px;'
},
items: [{
fieldLabel: 'From',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}, {
fieldLabel: 'To',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}]
});
optMan.bind('outgoing_ports', this.outgoingPorts);
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Network Interface'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'textfield'
});
optMan.bind('listen_interface', fieldset.add({
name: 'listen_interface',
fieldLabel: '',
labelSeparator: '',
width: 200
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('TOS'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
bodyStyle: 'margin: 0px; padding: 0px',
autoHeight: true,
defaultType: 'textfield'
});
optMan.bind('peer_tos', fieldset.add({
name: 'peer_tos',
fieldLabel: _('Peer TOS Byte'),
width: 80
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Network Extras'),
autoHeight: true,
layout: 'table',
layoutConfig: {
columns: 3
},
defaultType: 'checkbox'
});
optMan.bind('upnp', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('UPnP'),
name: 'upnp'
}));
optMan.bind('natpmp', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('NAT-PMP'),
ctCls: 'x-deluge-indent-checkbox',
name: 'natpmp'
}));
optMan.bind('utpex', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Peer Exchange'),
ctCls: 'x-deluge-indent-checkbox',
name: 'utpex'
}));
optMan.bind('lsd', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('LSD'),
name: 'lsd'
}));
optMan.bind('dht', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('DHT'),
ctCls: 'x-deluge-indent-checkbox',
name: 'dht'
}));
}
initComponent: function() {
Deluge.preferences.Network.superclass.initComponent.call(this);
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Incoming Ports'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
optMan.bind('random_port', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Use Random Ports'),
name: 'random_port',
height: 22,
listeners: {
'check': {
fn: function(e, checked) {
this.listenPorts.setDisabled(checked);
},
scope: this
}
}
}));
this.listenPorts = fieldset.add({
xtype: 'spinnergroup',
name: 'listen_ports',
fieldLabel: '',
labelSeparator: '',
colCfg: {
labelWidth: 40,
style: 'margin-right: 10px;'
},
items: [{
fieldLabel: 'From',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}, {
fieldLabel: 'To',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}]
});
optMan.bind('listen_ports', this.listenPorts);
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Outgoing Ports'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
optMan.bind('random_outgoing_ports', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Use Random Ports'),
name: 'random_outgoing_ports',
height: 22,
listeners: {
'check': {
fn: function(e, checked) {
this.outgoingPorts.setDisabled(checked);
},
scope: this
}
}
}));
this.outgoingPorts = fieldset.add({
xtype: 'spinnergroup',
name: 'outgoing_ports',
fieldLabel: '',
labelSeparator: '',
colCfg: {
labelWidth: 40,
style: 'margin-right: 10px;'
},
items: [{
fieldLabel: 'From',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}, {
fieldLabel: 'To',
strategy: {
xtype: 'number',
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}
}]
});
optMan.bind('outgoing_ports', this.outgoingPorts);
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Network Interface'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'textfield'
});
optMan.bind('listen_interface', fieldset.add({
name: 'listen_interface',
fieldLabel: '',
labelSeparator: '',
width: 200
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('TOS'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
bodyStyle: 'margin: 0px; padding: 0px',
autoHeight: true,
defaultType: 'textfield'
});
optMan.bind('peer_tos', fieldset.add({
name: 'peer_tos',
fieldLabel: _('Peer TOS Byte'),
width: 80
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Network Extras'),
autoHeight: true,
layout: 'table',
layoutConfig: {
columns: 3
},
defaultType: 'checkbox'
});
optMan.bind('upnp', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('UPnP'),
name: 'upnp'
}));
optMan.bind('natpmp', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('NAT-PMP'),
ctCls: 'x-deluge-indent-checkbox',
name: 'natpmp'
}));
optMan.bind('utpex', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Peer Exchange'),
ctCls: 'x-deluge-indent-checkbox',
name: 'utpex'
}));
optMan.bind('lsd', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('LSD'),
name: 'lsd'
}));
optMan.bind('dht', fieldset.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('DHT'),
ctCls: 'x-deluge-indent-checkbox',
name: 'dht'
}));
}
});

View file

@ -36,73 +36,73 @@ Ext.namespace('Deluge.preferences');
* @extends Ext.form.FormPanel
*/
Deluge.preferences.Other = Ext.extend(Ext.form.FormPanel, {
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Other'),
layout: 'form'
}, config);
Deluge.preferences.Other.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.preferences.Other.superclass.initComponent.call(this);
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Updates'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
optMan.bind('new_release_check', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 22,
name: 'new_release_check',
boxLabel: _('Be alerted about new releases')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('System Information'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
fieldset.add({
xtype: 'panel',
border: false,
bodyCfg: {
html: _('Help us improve Deluge by sending us your '
+ 'Python version, PyGTK version, OS and processor '
+ 'types. Absolutely no other information is sent.')
}
});
optMan.bind('send_info', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 22,
boxLabel: _('Yes, please send anonymous statistics'),
name: 'send_info'
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('GeoIP Database'),
autoHeight: true,
labelWidth: 80,
defaultType: 'textfield'
});
optMan.bind('geoip_db_location', fieldset.add({
name: 'geoip_db_location',
fieldLabel: _('Location'),
width: 200
}));
}
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Other'),
layout: 'form'
}, config);
Deluge.preferences.Other.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.preferences.Other.superclass.initComponent.call(this);
var optMan = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Updates'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
optMan.bind('new_release_check', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 22,
name: 'new_release_check',
boxLabel: _('Be alerted about new releases')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('System Information'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
fieldset.add({
xtype: 'panel',
border: false,
bodyCfg: {
html: _('Help us improve Deluge by sending us your '
+ 'Python version, PyGTK version, OS and processor '
+ 'types. Absolutely no other information is sent.')
}
});
optMan.bind('send_info', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 22,
boxLabel: _('Yes, please send anonymous statistics'),
name: 'send_info'
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('GeoIP Database'),
autoHeight: true,
labelWidth: 80,
defaultType: 'textfield'
});
optMan.bind('geoip_db_location', fieldset.add({
name: 'geoip_db_location',
fieldLabel: _('Location'),
width: 200
}));
}
});

View file

@ -37,234 +37,234 @@ Ext.namespace('Deluge.preferences');
*/
Deluge.preferences.Plugins = Ext.extend(Ext.Panel, {
layout: 'border',
title: _('Plugins'),
border: false,
height: 400,
cls: 'x-deluge-plugins',
layout: 'border',
title: _('Plugins'),
border: false,
height: 400,
cls: 'x-deluge-plugins',
pluginTemplate: new Ext.Template(
'<dl class="singleline">' +
'<dt>Author:</dt><dd>{author}</dd>' +
'<dt>Version:</dt><dd>{version}</dd>' +
'<dt>Author Email:</dt><dd>{email}</dd>' +
'<dt>Homepage:</dt><dd>{homepage}</dd>' +
'<dt>Details:</dt><dd>{details}</dd>' +
'</dl>'
),
pluginTemplate: new Ext.Template(
'<dl class="singleline">' +
'<dt>Author:</dt><dd>{author}</dd>' +
'<dt>Version:</dt><dd>{version}</dd>' +
'<dt>Author Email:</dt><dd>{email}</dd>' +
'<dt>Homepage:</dt><dd>{homepage}</dd>' +
'<dt>Details:</dt><dd>{details}</dd>' +
'</dl>'
),
initComponent: function() {
Deluge.preferences.Plugins.superclass.initComponent.call(this);
this.defaultValues = {
'version': '',
'email': '',
'homepage': '',
'details': ''
};
this.pluginTemplate.compile();
initComponent: function() {
Deluge.preferences.Plugins.superclass.initComponent.call(this);
this.defaultValues = {
'version': '',
'email': '',
'homepage': '',
'details': ''
};
this.pluginTemplate.compile();
var checkboxRenderer = function(v, p, record){
p.css += ' x-grid3-check-col-td';
return '<div class="x-grid3-check-col'+(v?'-on':'')+'"> </div>';
}
var checkboxRenderer = function(v, p, record){
p.css += ' x-grid3-check-col-td';
return '<div class="x-grid3-check-col'+(v?'-on':'')+'"> </div>';
}
this.list = this.add({
xtype: 'listview',
store: new Ext.data.ArrayStore({
fields: [
{name: 'enabled', mapping: 0},
{name: 'plugin', mapping: 1}
]
}),
columns: [{
id: 'enabled',
header: _('Enabled'),
width: .2,
sortable: true,
tpl: new Ext.XTemplate('{enabled:this.getCheckbox}', {
getCheckbox: function(v) {
return '<div class="x-grid3-check-col'+(v?'-on':'')+'" rel="chkbox"> </div>';
}
}),
dataIndex: 'enabled'
}, {
id: 'plugin',
header: _('Plugin'),
width: .8,
sortable: true,
dataIndex: 'plugin'
}],
singleSelect: true,
autoExpandColumn: 'plugin',
listeners: {
selectionchange: {fn: this.onPluginSelect, scope: this}
}
});
this.list = this.add({
xtype: 'listview',
store: new Ext.data.ArrayStore({
fields: [
{name: 'enabled', mapping: 0},
{name: 'plugin', mapping: 1}
]
}),
columns: [{
id: 'enabled',
header: _('Enabled'),
width: .2,
sortable: true,
tpl: new Ext.XTemplate('{enabled:this.getCheckbox}', {
getCheckbox: function(v) {
return '<div class="x-grid3-check-col'+(v?'-on':'')+'" rel="chkbox"> </div>';
}
}),
dataIndex: 'enabled'
}, {
id: 'plugin',
header: _('Plugin'),
width: .8,
sortable: true,
dataIndex: 'plugin'
}],
singleSelect: true,
autoExpandColumn: 'plugin',
listeners: {
selectionchange: {fn: this.onPluginSelect, scope: this}
}
});
this.panel = this.add({
region: 'center',
autoScroll: true,
margins: '5 5 5 5',
items: [this.list],
bbar: new Ext.Toolbar({
items: [{
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-install-plugin',
text: _('Install'),
handler: this.onInstallPluginWindow,
scope: this
}, '->', {
cls: 'x-btn-text-icon',
text: _('Find More'),
iconCls: 'x-deluge-find-more',
handler: this.onFindMorePlugins,
scope: this
}]
})
});
this.panel = this.add({
region: 'center',
autoScroll: true,
margins: '5 5 5 5',
items: [this.list],
bbar: new Ext.Toolbar({
items: [{
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-install-plugin',
text: _('Install'),
handler: this.onInstallPluginWindow,
scope: this
}, '->', {
cls: 'x-btn-text-icon',
text: _('Find More'),
iconCls: 'x-deluge-find-more',
handler: this.onFindMorePlugins,
scope: this
}]
})
});
var pp = this.pluginInfo = this.add({
xtype: 'panel',
border: true,
height: 160,
region: 'south',
margins: '0 5 5 5'
});
var fieldset = pp.add({
xtype: 'fieldset',
title: _('Info'),
border: false,
autoHeight: true,
labelWidth: 1,
style: 'margin-top: 5px;'
});
this.pluginInfo = fieldset.add({
xtype: 'panel',
border: false,
bodyCfg: {
style: 'margin-left: 10px'
}
});
var pp = this.pluginInfo = this.add({
xtype: 'panel',
border: true,
height: 160,
region: 'south',
margins: '0 5 5 5'
});
var fieldset = pp.add({
xtype: 'fieldset',
title: _('Info'),
border: false,
autoHeight: true,
labelWidth: 1,
style: 'margin-top: 5px;'
});
this.pluginInfo = fieldset.add({
xtype: 'panel',
border: false,
bodyCfg: {
style: 'margin-left: 10px'
}
});
this.pluginInfo.on('render', this.onPluginInfoRender, this);
this.list.on('click', this.onNodeClick, this);
deluge.preferences.on('show', this.onPreferencesShow, this);
deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
},
this.pluginInfo.on('render', this.onPluginInfoRender, this);
this.list.on('click', this.onNodeClick, this);
deluge.preferences.on('show', this.onPreferencesShow, this);
deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
},
disablePlugin: function(plugin) {
deluge.client.core.disable_plugin(plugin);
},
disablePlugin: function(plugin) {
deluge.client.core.disable_plugin(plugin);
},
enablePlugin: function(plugin) {
deluge.client.core.enable_plugin(plugin);
},
enablePlugin: function(plugin) {
deluge.client.core.enable_plugin(plugin);
},
setInfo: function(plugin) {
if (!this.pluginInfo.rendered) return;
var values = plugin || this.defaultValues;
this.pluginInfo.body.dom.innerHTML = this.pluginTemplate.apply(values);
},
setInfo: function(plugin) {
if (!this.pluginInfo.rendered) return;
var values = plugin || this.defaultValues;
this.pluginInfo.body.dom.innerHTML = this.pluginTemplate.apply(values);
},
updatePlugins: function() {
deluge.client.web.get_plugins({
success: this.onGotPlugins,
scope: this
});
},
updatePlugins: function() {
deluge.client.web.get_plugins({
success: this.onGotPlugins,
scope: this
});
},
updatePluginsGrid: function() {
var plugins = [];
Ext.each(this.availablePlugins, function(plugin) {
if (this.enabledPlugins.indexOf(plugin) > -1) {
plugins.push([true, plugin]);
} else {
plugins.push([false, plugin]);
}
}, this);
this.list.getStore().loadData(plugins);
},
updatePluginsGrid: function() {
var plugins = [];
Ext.each(this.availablePlugins, function(plugin) {
if (this.enabledPlugins.indexOf(plugin) > -1) {
plugins.push([true, plugin]);
} else {
plugins.push([false, plugin]);
}
}, this);
this.list.getStore().loadData(plugins);
},
onNodeClick: function(dv, index, node, e) {
var el = new Ext.Element(e.target);
if (el.getAttribute('rel') != 'chkbox') return;
onNodeClick: function(dv, index, node, e) {
var el = new Ext.Element(e.target);
if (el.getAttribute('rel') != 'chkbox') return;
var r = dv.getStore().getAt(index);
r.set('enabled', !r.get('enabled'));
r.commit();
if (r.get('enabled')) {
this.enablePlugin(r.get('plugin'));
} else {
this.disablePlugin(r.get('plugin'));
}
},
var r = dv.getStore().getAt(index);
r.set('enabled', !r.get('enabled'));
r.commit();
if (r.get('enabled')) {
this.enablePlugin(r.get('plugin'));
} else {
this.disablePlugin(r.get('plugin'));
}
},
onFindMorePlugins: function() {
window.open('http://dev.deluge-torrent.org/wiki/Plugins');
},
onFindMorePlugins: function() {
window.open('http://dev.deluge-torrent.org/wiki/Plugins');
},
onGotPlugins: function(plugins) {
this.enabledPlugins = plugins.enabled_plugins;
this.availablePlugins = plugins.available_plugins;
this.setInfo();
this.updatePluginsGrid();
},
onGotPlugins: function(plugins) {
this.enabledPlugins = plugins.enabled_plugins;
this.availablePlugins = plugins.available_plugins;
this.setInfo();
this.updatePluginsGrid();
},
onGotPluginInfo: function(info) {
var values = {
author: info['Author'],
version: info['Version'],
email: info['Author-email'],
homepage: info['Home-page'],
details: info['Description']
}
this.setInfo(values);
delete info;
},
onGotPluginInfo: function(info) {
var values = {
author: info['Author'],
version: info['Version'],
email: info['Author-email'],
homepage: info['Home-page'],
details: info['Description']
}
this.setInfo(values);
delete info;
},
onInstallPluginWindow: function() {
if (!this.installWindow) {
this.installWindow = new Deluge.preferences.InstallPluginWindow();
this.installWindow.on('pluginadded', this.onPluginInstall, this);
}
this.installWindow.show();
},
onInstallPluginWindow: function() {
if (!this.installWindow) {
this.installWindow = new Deluge.preferences.InstallPluginWindow();
this.installWindow.on('pluginadded', this.onPluginInstall, this);
}
this.installWindow.show();
},
onPluginEnabled: function(pluginName) {
var index = this.list.getStore().find('plugin', pluginName);
if (index == -1) return;
var plugin = this.list.getStore().getAt(index);
plugin.set('enabled', true);
plugin.commit();
},
onPluginEnabled: function(pluginName) {
var index = this.list.getStore().find('plugin', pluginName);
if (index == -1) return;
var plugin = this.list.getStore().getAt(index);
plugin.set('enabled', true);
plugin.commit();
},
onPluginDisabled: function(pluginName) {
var index = this.list.getStore().find('plugin', pluginName);
if (index == -1) return;
var plugin = this.list.getStore().getAt(index);
plugin.set('enabled', false);
plugin.commit();
},
onPluginDisabled: function(pluginName) {
var index = this.list.getStore().find('plugin', pluginName);
if (index == -1) return;
var plugin = this.list.getStore().getAt(index);
plugin.set('enabled', false);
plugin.commit();
},
onPluginInstall: function() {
this.updatePlugins();
},
onPluginInstall: function() {
this.updatePlugins();
},
onPluginSelect: function(dv, selections) {
onPluginSelect: function(dv, selections) {
if (selections.length == 0) return;
var r = dv.getRecords(selections)[0];
deluge.client.web.get_plugin_info(r.get('plugin'), {
success: this.onGotPluginInfo,
scope: this
});
},
var r = dv.getRecords(selections)[0];
deluge.client.web.get_plugin_info(r.get('plugin'), {
success: this.onGotPluginInfo,
scope: this
});
},
onPreferencesShow: function() {
this.updatePlugins();
},
onPreferencesShow: function() {
this.updatePlugins();
},
onPluginInfoRender: function(ct, position) {
this.setInfo();
}
onPluginInfoRender: function(ct, position) {
this.setInfo();
}
});

View file

@ -39,207 +39,207 @@ PreferencesRecord = Ext.data.Record.create([{name:'name', type:'string'}]);
*/
Deluge.preferences.PreferencesWindow = Ext.extend(Ext.Window, {
/**
* @property {String} currentPage The currently selected page.
*/
currentPage: null,
/**
* @property {String} currentPage The currently selected page.
*/
currentPage: null,
title: _('Preferences'),
layout: 'border',
width: 485,
height: 500,
title: _('Preferences'),
layout: 'border',
width: 485,
height: 500,
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
iconCls: 'x-deluge-preferences',
plain: true,
resizable: false,
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
iconCls: 'x-deluge-preferences',
plain: true,
resizable: false,
pages: {},
pages: {},
initComponent: function() {
Deluge.preferences.PreferencesWindow.superclass.initComponent.call(this);
initComponent: function() {
Deluge.preferences.PreferencesWindow.superclass.initComponent.call(this);
this.list = new Ext.list.ListView({
store: new Ext.data.Store(),
columns: [{
id: 'name',
renderer: fplain,
dataIndex: 'name'
}],
singleSelect: true,
listeners: {
'selectionchange': {
fn: this.onPageSelect, scope: this
}
},
hideHeaders: true,
autoExpandColumn: 'name',
deferredRender: false,
autoScroll: true,
collapsible: true
});
this.add({
region: 'west',
title: _('Categories'),
items: [this.list],
width: 120,
margins: '5 0 5 5',
cmargins: '5 0 5 5'
});
this.list = new Ext.list.ListView({
store: new Ext.data.Store(),
columns: [{
id: 'name',
renderer: fplain,
dataIndex: 'name'
}],
singleSelect: true,
listeners: {
'selectionchange': {
fn: this.onPageSelect, scope: this
}
},
hideHeaders: true,
autoExpandColumn: 'name',
deferredRender: false,
autoScroll: true,
collapsible: true
});
this.add({
region: 'west',
title: _('Categories'),
items: [this.list],
width: 120,
margins: '5 0 5 5',
cmargins: '5 0 5 5'
});
this.configPanel = this.add({
type: 'container',
autoDestroy: false,
region: 'center',
layout: 'card',
layoutConfig: {
deferredRender: true
},
autoScroll: true,
width: 300,
margins: '5 5 5 5',
cmargins: '5 5 5 5'
});
this.configPanel = this.add({
type: 'container',
autoDestroy: false,
region: 'center',
layout: 'card',
layoutConfig: {
deferredRender: true
},
autoScroll: true,
width: 300,
margins: '5 5 5 5',
cmargins: '5 5 5 5'
});
this.addButton(_('Close'), this.onClose, this);
this.addButton(_('Apply'), this.onApply, this);
this.addButton(_('Ok'), this.onOk, this);
this.optionsManager = new Deluge.OptionsManager();
this.on('afterrender', this.onAfterRender, this);
this.on('show', this.onShow, this);
this.addButton(_('Close'), this.onClose, this);
this.addButton(_('Apply'), this.onApply, this);
this.addButton(_('Ok'), this.onOk, this);
this.optionsManager = new Deluge.OptionsManager();
this.on('afterrender', this.onAfterRender, this);
this.on('show', this.onShow, this);
this.initPages();
},
this.initPages();
},
initPages: function() {
deluge.preferences = this;
this.addPage(new Deluge.preferences.Downloads());
this.addPage(new Deluge.preferences.Network());
this.addPage(new Deluge.preferences.Encryption());
this.addPage(new Deluge.preferences.Bandwidth());
this.addPage(new Deluge.preferences.Interface());
this.addPage(new Deluge.preferences.Other());
this.addPage(new Deluge.preferences.Daemon());
this.addPage(new Deluge.preferences.Queue());
this.addPage(new Deluge.preferences.Proxy());
this.addPage(new Deluge.preferences.Cache());
this.addPage(new Deluge.preferences.Plugins());
},
onApply: function(e) {
var changed = this.optionsManager.getDirty();
if (!Ext.isObjectEmpty(changed)) {
deluge.client.core.set_config(changed, {
success: this.onSetConfig,
scope: this
});
}
for (var page in this.pages) {
if (this.pages[page].onApply) this.pages[page].onApply();
}
},
/**
* Return the options manager for the preferences window.
* @returns {Deluge.OptionsManager} the options manager
*/
getOptionsManager: function() {
return this.optionsManager;
},
/**
* Adds a page to the preferences window.
* @param {Mixed} page
*/
addPage: function(page) {
var store = this.list.getStore();
var name = page.title;
store.add([new PreferencesRecord({name: name})]);
page['bodyStyle'] = 'padding: 5px';
page.preferences = this;
this.pages[name] = this.configPanel.add(page);
this.pages[name].index = -1;
return this.pages[name];
},
/**
* Removes a preferences page from the window.
* @param {mixed} name
*/
removePage: function(page) {
var name = page.title;
var store = this.list.getStore();
store.removeAt(store.find('name', name));
this.configPanel.remove(page);
delete this.pages[page.title];
},
initPages: function() {
deluge.preferences = this;
this.addPage(new Deluge.preferences.Downloads());
this.addPage(new Deluge.preferences.Network());
this.addPage(new Deluge.preferences.Encryption());
this.addPage(new Deluge.preferences.Bandwidth());
this.addPage(new Deluge.preferences.Interface());
this.addPage(new Deluge.preferences.Other());
this.addPage(new Deluge.preferences.Daemon());
this.addPage(new Deluge.preferences.Queue());
this.addPage(new Deluge.preferences.Proxy());
this.addPage(new Deluge.preferences.Cache());
this.addPage(new Deluge.preferences.Plugins());
},
onApply: function(e) {
var changed = this.optionsManager.getDirty();
if (!Ext.isObjectEmpty(changed)) {
deluge.client.core.set_config(changed, {
success: this.onSetConfig,
scope: this
});
}
for (var page in this.pages) {
if (this.pages[page].onApply) this.pages[page].onApply();
}
},
/**
* Return the options manager for the preferences window.
* @returns {Deluge.OptionsManager} the options manager
*/
getOptionsManager: function() {
return this.optionsManager;
},
/**
* Adds a page to the preferences window.
* @param {Mixed} page
*/
addPage: function(page) {
var store = this.list.getStore();
var name = page.title;
store.add([new PreferencesRecord({name: name})]);
page['bodyStyle'] = 'padding: 5px';
page.preferences = this;
this.pages[name] = this.configPanel.add(page);
this.pages[name].index = -1;
return this.pages[name];
},
/**
* Removes a preferences page from the window.
* @param {mixed} name
*/
removePage: function(page) {
var name = page.title;
var store = this.list.getStore();
store.removeAt(store.find('name', name));
this.configPanel.remove(page);
delete this.pages[page.title];
},
/**
* Select which preferences page is displayed.
* @param {String} page The page name to change to
*/
selectPage: function(page) {
if (this.pages[page].index < 0) {
this.pages[page].index = this.configPanel.items.indexOf(this.pages[page]);
}
this.list.select(this.pages[page].index);
},
/**
* Select which preferences page is displayed.
* @param {String} page The page name to change to
*/
selectPage: function(page) {
if (this.pages[page].index < 0) {
this.pages[page].index = this.configPanel.items.indexOf(this.pages[page]);
}
this.list.select(this.pages[page].index);
},
// private
doSelectPage: function(page) {
if (this.pages[page].index < 0) {
this.pages[page].index = this.configPanel.items.indexOf(this.pages[page]);
}
this.configPanel.getLayout().setActiveItem(this.pages[page].index);
this.currentPage = page;
},
// private
onGotConfig: function(config) {
this.getOptionsManager().set(config);
},
// private
onPageSelect: function(list, selections) {
var r = list.getRecord(selections[0]);
this.doSelectPage(r.get('name'));
},
// private
onSetConfig: function() {
this.getOptionsManager().commit();
},
// private
doSelectPage: function(page) {
if (this.pages[page].index < 0) {
this.pages[page].index = this.configPanel.items.indexOf(this.pages[page]);
}
this.configPanel.getLayout().setActiveItem(this.pages[page].index);
this.currentPage = page;
},
// private
onGotConfig: function(config) {
this.getOptionsManager().set(config);
},
// private
onPageSelect: function(list, selections) {
var r = list.getRecord(selections[0]);
this.doSelectPage(r.get('name'));
},
// private
onSetConfig: function() {
this.getOptionsManager().commit();
},
// private
onAfterRender: function() {
if (!this.list.getSelectionCount()) {
this.list.select(0);
}
this.configPanel.getLayout().setActiveItem(0);
},
// private
onShow: function() {
if (!deluge.client.core) return;
deluge.client.core.get_config({
success: this.onGotConfig,
scope: this
})
},
// private
onAfterRender: function() {
if (!this.list.getSelectionCount()) {
this.list.select(0);
}
this.configPanel.getLayout().setActiveItem(0);
},
// private
onShow: function() {
if (!deluge.client.core) return;
deluge.client.core.get_config({
success: this.onGotConfig,
scope: this
})
},
// private
onClose: function() {
this.hide();
},
// private
onClose: function() {
this.hide();
},
// private
onOk: function() {
deluge.client.core.set_config(this.optionsManager.getDirty());
this.hide();
}
// private
onOk: function() {
deluge.client.core.set_config(this.optionsManager.getDirty());
this.hide();
}
});

View file

@ -15,9 +15,9 @@
*
* 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.
* 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
@ -37,125 +37,125 @@ Ext.ns('Deluge.preferences');
*/
Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
border: false,
autoHeight: true,
labelWidth: 70,
border: false,
autoHeight: true,
labelWidth: 70,
initComponent: function() {
Deluge.preferences.ProxyField.superclass.initComponent.call(this);
this.proxyType = this.add({
xtype: 'combo',
fieldLabel: _('Type'),
name: 'proxytype',
mode: 'local',
width: 150,
store: new Ext.data.ArrayStore({
fields: ['id', 'text'],
data: [
[0, _('None')],
[1, _('Socksv4')],
[2, _('Socksv5')],
[3, _('Socksv5 with Auth')],
[4, _('HTTP')],
[5, _('HTTP with Auth')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
});
this.hostname = this.add({
xtype: 'textfield',
name: 'hostname',
fieldLabel: _('Host'),
width: 220
});
initComponent: function() {
Deluge.preferences.ProxyField.superclass.initComponent.call(this);
this.proxyType = this.add({
xtype: 'combo',
fieldLabel: _('Type'),
name: 'proxytype',
mode: 'local',
width: 150,
store: new Ext.data.ArrayStore({
fields: ['id', 'text'],
data: [
[0, _('None')],
[1, _('Socksv4')],
[2, _('Socksv5')],
[3, _('Socksv5 with Auth')],
[4, _('HTTP')],
[5, _('HTTP with Auth')]
]
}),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
});
this.hostname = this.add({
xtype: 'textfield',
name: 'hostname',
fieldLabel: _('Host'),
width: 220
});
this.port = this.add({
xtype: 'spinnerfield',
name: 'port',
fieldLabel: _('Port'),
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
});
this.port = this.add({
xtype: 'spinnerfield',
name: 'port',
fieldLabel: _('Port'),
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
});
this.username = this.add({
xtype: 'textfield',
name: 'username',
fieldLabel: _('Username'),
width: 220
});
this.username = this.add({
xtype: 'textfield',
name: 'username',
fieldLabel: _('Username'),
width: 220
});
this.password = this.add({
xtype: 'textfield',
name: 'password',
fieldLabel: _('Password'),
inputType: 'password',
width: 220
});
this.password = this.add({
xtype: 'textfield',
name: 'password',
fieldLabel: _('Password'),
inputType: 'password',
width: 220
});
this.proxyType.on('change', this.onFieldChange, this);
this.proxyType.on('select', this.onTypeSelect, this);
this.setting = false;
},
this.proxyType.on('change', this.onFieldChange, this);
this.proxyType.on('select', this.onTypeSelect, this);
this.setting = false;
},
getName: function() {
return this.initialConfig.name;
},
getName: function() {
return this.initialConfig.name;
},
getValue: function() {
return {
'type': this.proxyType.getValue(),
'hostname': this.hostname.getValue(),
'port': Number(this.port.getValue()),
'username': this.username.getValue(),
'password': this.password.getValue()
}
},
getValue: function() {
return {
'type': this.proxyType.getValue(),
'hostname': this.hostname.getValue(),
'port': Number(this.port.getValue()),
'username': this.username.getValue(),
'password': this.password.getValue()
}
},
// Set the values of the proxies
setValue: function(value) {
this.setting = true;
this.proxyType.setValue(value['type']);
var index = this.proxyType.getStore().find('id', value['type']);
var record = this.proxyType.getStore().getAt(index);
// Set the values of the proxies
setValue: function(value) {
this.setting = true;
this.proxyType.setValue(value['type']);
var index = this.proxyType.getStore().find('id', value['type']);
var record = this.proxyType.getStore().getAt(index);
this.hostname.setValue(value['hostname']);
this.port.setValue(value['port']);
this.username.setValue(value['username']);
this.password.setValue(value['password']);
this.onTypeSelect(this.type, record, index);
this.setting = false;
},
this.hostname.setValue(value['hostname']);
this.port.setValue(value['port']);
this.username.setValue(value['username']);
this.password.setValue(value['password']);
this.onTypeSelect(this.type, record, index);
this.setting = false;
},
onFieldChange: function(field, newValue, oldValue) {
if (this.setting) return;
var newValues = this.getValue();
var oldValues = Ext.apply({}, newValues);
oldValues[field.getName()] = oldValue;
onFieldChange: function(field, newValue, oldValue) {
if (this.setting) return;
var newValues = this.getValue();
var oldValues = Ext.apply({}, newValues);
oldValues[field.getName()] = oldValue;
this.fireEvent('change', this, newValues, oldValues);
},
this.fireEvent('change', this, newValues, oldValues);
},
onTypeSelect: function(combo, record, index) {
var typeId = record.get('id');
if (typeId > 0) {
this.hostname.show();
this.port.show();
} else {
this.hostname.hide();
this.port.hide();
}
onTypeSelect: function(combo, record, index) {
var typeId = record.get('id');
if (typeId > 0) {
this.hostname.show();
this.port.show();
} else {
this.hostname.hide();
this.port.hide();
}
if (typeId == 3 || typeId == 5) {
this.username.show();
this.password.show();
} else {
this.username.hide();
this.password.hide();
}
}
if (typeId == 3 || typeId == 5) {
this.username.show();
this.password.show();
} else {
this.username.hide();
this.password.hide();
}
}
});

View file

@ -36,64 +36,64 @@ Ext.namespace('Deluge.preferences');
* @extends Ext.form.FormPanel
*/
Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Proxy'),
layout: 'form'
}, config);
Deluge.preferences.Proxy.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.preferences.Proxy.superclass.initComponent.call(this);
this.peer = this.add(new Deluge.preferences.ProxyField({
title: _('Peer'),
name: 'peer'
}));
this.peer.on('change', this.onProxyChange, this);
this.web_seed = this.add(new Deluge.preferences.ProxyField({
title: _('Web Seed'),
name: 'web_seed'
}));
this.web_seed.on('change', this.onProxyChange, this);
this.tracker = this.add(new Deluge.preferences.ProxyField({
title: _('Tracker'),
name: 'tracker'
}));
this.tracker.on('change', this.onProxyChange, this);
this.dht = this.add(new Deluge.preferences.ProxyField({
title: _('DHT'),
name: 'dht'
}));
this.dht.on('change', this.onProxyChange, this);
deluge.preferences.getOptionsManager().bind('proxies', this);
},
getValue: function() {
return {
'dht': this.dht.getValue(),
'peer': this.peer.getValue(),
'tracker': this.tracker.getValue(),
'web_seed': this.web_seed.getValue()
}
},
setValue: function(value) {
for (var proxy in value) {
this[proxy].setValue(value[proxy]);
}
},
onProxyChange: function(field, newValue, oldValue) {
var newValues = this.getValue();
var oldValues = Ext.apply({}, newValues);
oldValues[field.getName()] = oldValue;
this.fireEvent('change', this, newValues, oldValues);
}
constructor: function(config) {
config = Ext.apply({
border: false,
title: _('Proxy'),
layout: 'form'
}, config);
Deluge.preferences.Proxy.superclass.constructor.call(this, config);
},
initComponent: function() {
Deluge.preferences.Proxy.superclass.initComponent.call(this);
this.peer = this.add(new Deluge.preferences.ProxyField({
title: _('Peer'),
name: 'peer'
}));
this.peer.on('change', this.onProxyChange, this);
this.web_seed = this.add(new Deluge.preferences.ProxyField({
title: _('Web Seed'),
name: 'web_seed'
}));
this.web_seed.on('change', this.onProxyChange, this);
this.tracker = this.add(new Deluge.preferences.ProxyField({
title: _('Tracker'),
name: 'tracker'
}));
this.tracker.on('change', this.onProxyChange, this);
this.dht = this.add(new Deluge.preferences.ProxyField({
title: _('DHT'),
name: 'dht'
}));
this.dht.on('change', this.onProxyChange, this);
deluge.preferences.getOptionsManager().bind('proxies', this);
},
getValue: function() {
return {
'dht': this.dht.getValue(),
'peer': this.peer.getValue(),
'tracker': this.tracker.getValue(),
'web_seed': this.web_seed.getValue()
}
},
setValue: function(value) {
for (var proxy in value) {
this[proxy].setValue(value[proxy]);
}
},
onProxyChange: function(field, newValue, oldValue) {
var newValues = this.getValue();
var oldValues = Ext.apply({}, newValues);
oldValues[field.getName()] = oldValue;
this.fireEvent('change', this, newValues, oldValues);
}
});

View file

@ -37,166 +37,166 @@ Ext.namespace('Deluge.preferences');
*/
Deluge.preferences.Queue = Ext.extend(Ext.form.FormPanel, {
border: false,
title: _('Queue'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Queue.superclass.initComponent.call(this);
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('General'),
style: 'padding-top: 5px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('queue_new_to_top', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 22,
boxLabel: _('Queue new torrents to top'),
name: 'queue_new_to_top'
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Active Torrents'),
autoHeight: true,
labelWidth: 150,
defaultType: 'spinnerfield',
style: 'margin-bottom: 0px; padding-bottom: 0px;'
});
om.bind('max_active_limit', fieldset.add({
fieldLabel: _('Total Active'),
name: 'max_active_limit',
value: 8,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('max_active_downloading', fieldset.add({
fieldLabel: _('Total Active Downloading'),
name: 'max_active_downloading',
value: 3,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('max_active_seeding', fieldset.add({
fieldLabel: _('Total Active Seeding'),
name: 'max_active_seeding',
value: 5,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('dont_count_slow_torrents', fieldset.add({
xtype: 'checkbox',
name: 'dont_count_slow_torrents',
height: 40,
hideLabel: true,
boxLabel: _('Do not count slow torrents')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Seeding'),
autoHeight: true,
labelWidth: 150,
defaultType: 'spinnerfield',
style: 'margin-bottom: 0px; padding-bottom: 0px; margin-top: 0; padding-top: 0;'
});
om.bind('share_ratio_limit', fieldset.add({
fieldLabel: _('Share Ratio Limit'),
name: 'share_ratio_limit',
value: 8,
width: 80,
incrementValue: 0.1,
minValue: -1,
maxValue: 99999,
alternateIncrementValue: 1,
decimalPrecision: 2
}));
om.bind('seed_time_ratio_limit', fieldset.add({
fieldLabel: _('Share Time Ratio'),
name: 'seed_time_ratio_limit',
value: 3,
width: 80,
incrementValue: 0.1,
minValue: -1,
maxValue: 99999,
alternateIncrementValue: 1,
decimalPrecision: 2
}));
om.bind('seed_time_limit', fieldset.add({
fieldLabel: _('Seed Time (m)'),
name: 'seed_time_limit',
value: 5,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
autoHeight: true,
layout: 'table',
layoutConfig: {columns: 2},
labelWidth: 0,
defaultType: 'checkbox',
defaults: {
fieldLabel: '',
labelSeparator: ''
}
});
this.stopAtRatio = fieldset.add({
name: 'stop_seed_at_ratio',
boxLabel: _('Stop seeding when share ratio reaches:')
});
this.stopAtRatio.on('check', this.onStopRatioCheck, this);
om.bind('stop_seed_at_ratio', this.stopAtRatio);
this.stopRatio = fieldset.add({
xtype: 'spinnerfield',
name: 'stop_seed_ratio',
ctCls: 'x-deluge-indent-checkbox',
disabled: true,
value: '2.0',
width: 60,
incrementValue: 0.1,
minValue: -1,
maxValue: 99999,
alternateIncrementValue: 1,
decimalPrecision: 2
});
om.bind('stop_seed_ratio', this.stopRatio);
this.removeAtRatio = fieldset.add({
name: 'remove_seed_at_ratio',
ctCls: 'x-deluge-indent-checkbox',
boxLabel: _('Remove torrent when share ratio is reached'),
disabled: true,
colspan: 2
});
om.bind('remove_seed_at_ratio', this.removeAtRatio);
},
onStopRatioCheck: function(e, checked) {
this.stopRatio.setDisabled(!checked);
this.removeAtRatio.setDisabled(!checked);
}
border: false,
title: _('Queue'),
layout: 'form',
initComponent: function() {
Deluge.preferences.Queue.superclass.initComponent.call(this);
var om = deluge.preferences.getOptionsManager();
var fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('General'),
style: 'padding-top: 5px;',
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox'
});
om.bind('queue_new_to_top', fieldset.add({
fieldLabel: '',
labelSeparator: '',
height: 22,
boxLabel: _('Queue new torrents to top'),
name: 'queue_new_to_top'
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Active Torrents'),
autoHeight: true,
labelWidth: 150,
defaultType: 'spinnerfield',
style: 'margin-bottom: 0px; padding-bottom: 0px;'
});
om.bind('max_active_limit', fieldset.add({
fieldLabel: _('Total Active'),
name: 'max_active_limit',
value: 8,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('max_active_downloading', fieldset.add({
fieldLabel: _('Total Active Downloading'),
name: 'max_active_downloading',
value: 3,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('max_active_seeding', fieldset.add({
fieldLabel: _('Total Active Seeding'),
name: 'max_active_seeding',
value: 5,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
om.bind('dont_count_slow_torrents', fieldset.add({
xtype: 'checkbox',
name: 'dont_count_slow_torrents',
height: 40,
hideLabel: true,
boxLabel: _('Do not count slow torrents')
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Seeding'),
autoHeight: true,
labelWidth: 150,
defaultType: 'spinnerfield',
style: 'margin-bottom: 0px; padding-bottom: 0px; margin-top: 0; padding-top: 0;'
});
om.bind('share_ratio_limit', fieldset.add({
fieldLabel: _('Share Ratio Limit'),
name: 'share_ratio_limit',
value: 8,
width: 80,
incrementValue: 0.1,
minValue: -1,
maxValue: 99999,
alternateIncrementValue: 1,
decimalPrecision: 2
}));
om.bind('seed_time_ratio_limit', fieldset.add({
fieldLabel: _('Share Time Ratio'),
name: 'seed_time_ratio_limit',
value: 3,
width: 80,
incrementValue: 0.1,
minValue: -1,
maxValue: 99999,
alternateIncrementValue: 1,
decimalPrecision: 2
}));
om.bind('seed_time_limit', fieldset.add({
fieldLabel: _('Seed Time (m)'),
name: 'seed_time_limit',
value: 5,
width: 80,
decimalPrecision: 0,
minValue: -1,
maxValue: 99999
}));
fieldset = this.add({
xtype: 'fieldset',
border: false,
autoHeight: true,
layout: 'table',
layoutConfig: {columns: 2},
labelWidth: 0,
defaultType: 'checkbox',
defaults: {
fieldLabel: '',
labelSeparator: ''
}
});
this.stopAtRatio = fieldset.add({
name: 'stop_seed_at_ratio',
boxLabel: _('Stop seeding when share ratio reaches:')
});
this.stopAtRatio.on('check', this.onStopRatioCheck, this);
om.bind('stop_seed_at_ratio', this.stopAtRatio);
this.stopRatio = fieldset.add({
xtype: 'spinnerfield',
name: 'stop_seed_ratio',
ctCls: 'x-deluge-indent-checkbox',
disabled: true,
value: '2.0',
width: 60,
incrementValue: 0.1,
minValue: -1,
maxValue: 99999,
alternateIncrementValue: 1,
decimalPrecision: 2
});
om.bind('stop_seed_ratio', this.stopRatio);
this.removeAtRatio = fieldset.add({
name: 'remove_seed_at_ratio',
ctCls: 'x-deluge-indent-checkbox',
boxLabel: _('Remove torrent when share ratio is reached'),
disabled: true,
colspan: 2
});
om.bind('remove_seed_at_ratio', this.removeAtRatio);
},
onStopRatioCheck: function(e, checked) {
this.stopRatio.setDisabled(!checked);
this.removeAtRatio.setDisabled(!checked);
}
});

View file

@ -1,38 +1,38 @@
Ext.ux.JSLoader = function(options) {
Ext.ux.JSLoader.scripts[++Ext.ux.JSLoader.index] = {
url: options.url,
success: true,
jsLoadObj: null,
options: options,
onLoad: options.onLoad || Ext.emptyFn,
onError: options.onError || Ext.ux.JSLoader.stdError,
scope: options.scope || this
};
Ext.ux.JSLoader.scripts[++Ext.ux.JSLoader.index] = {
url: options.url,
success: true,
jsLoadObj: null,
options: options,
onLoad: options.onLoad || Ext.emptyFn,
onError: options.onError || Ext.ux.JSLoader.stdError,
scope: options.scope || this
};
Ext.Ajax.request({
url: options.url,
scriptIndex: Ext.ux.JSLoader.index,
success: function(response, options) {
var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
try {
eval(response.responseText);
} catch(e) {
script.success = false;
script.onError(script.options, e);
}
if (script.success) {
script.onLoad.call(script.scope, script.options);
}
},
failure: function(response, options) {
var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
script.success = false;
script.onError(script.options, response.status);
}
});
Ext.Ajax.request({
url: options.url,
scriptIndex: Ext.ux.JSLoader.index,
success: function(response, options) {
var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
try {
eval(response.responseText);
} catch(e) {
script.success = false;
script.onError(script.options, e);
}
if (script.success) {
script.onLoad.call(script.scope, script.options);
}
},
failure: function(response, options) {
var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
script.success = false;
script.onError(script.options, response.status);
}
});
}
Ext.ux.JSLoader.index = 0;
Ext.ux.JSLoader.scripts = [];
Ext.ux.JSLoader.stdError = function(options, e) {
window.alert('Error loading script:\n\n' + options.url + '\n\nstatus: ' + e);
window.alert('Error loading script:\n\n' + options.url + '\n\nstatus: ' + e);
}

View file

@ -10,428 +10,428 @@
* Creates a Spinner control utilized by Ext.ux.form.SpinnerField
*/
Ext.ux.Spinner = Ext.extend(Ext.util.Observable, {
incrementValue: 1,
alternateIncrementValue: 5,
triggerClass: 'x-form-spinner-trigger',
splitterClass: 'x-form-spinner-splitter',
alternateKey: Ext.EventObject.shiftKey,
defaultValue: 0,
accelerate: false,
incrementValue: 1,
alternateIncrementValue: 5,
triggerClass: 'x-form-spinner-trigger',
splitterClass: 'x-form-spinner-splitter',
alternateKey: Ext.EventObject.shiftKey,
defaultValue: 0,
accelerate: false,
constructor: function(config){
Ext.ux.Spinner.superclass.constructor.call(this, config);
Ext.apply(this, config);
this.mimicing = false;
},
constructor: function(config){
Ext.ux.Spinner.superclass.constructor.call(this, config);
Ext.apply(this, config);
this.mimicing = false;
},
init: function(field){
this.field = field;
init: function(field){
this.field = field;
field.afterMethod('onRender', this.doRender, this);
field.afterMethod('onEnable', this.doEnable, this);
field.afterMethod('onDisable', this.doDisable, this);
field.afterMethod('afterRender', this.doAfterRender, this);
field.afterMethod('onResize', this.doResize, this);
field.afterMethod('onFocus', this.doFocus, this);
field.beforeMethod('onDestroy', this.doDestroy, this);
},
field.afterMethod('onRender', this.doRender, this);
field.afterMethod('onEnable', this.doEnable, this);
field.afterMethod('onDisable', this.doDisable, this);
field.afterMethod('afterRender', this.doAfterRender, this);
field.afterMethod('onResize', this.doResize, this);
field.afterMethod('onFocus', this.doFocus, this);
field.beforeMethod('onDestroy', this.doDestroy, this);
},
doRender: function(ct, position){
var el = this.el = this.field.getEl();
var f = this.field;
doRender: function(ct, position){
var el = this.el = this.field.getEl();
var f = this.field;
if (!f.wrap) {
f.wrap = this.wrap = el.wrap({
cls: "x-form-field-wrap"
});
}
else {
this.wrap = f.wrap.addClass('x-form-field-wrap');
}
if (!f.wrap) {
f.wrap = this.wrap = el.wrap({
cls: "x-form-field-wrap"
});
}
else {
this.wrap = f.wrap.addClass('x-form-field-wrap');
}
this.trigger = this.wrap.createChild({
tag: "img",
src: Ext.BLANK_IMAGE_URL,
cls: "x-form-trigger " + this.triggerClass
});
this.trigger = this.wrap.createChild({
tag: "img",
src: Ext.BLANK_IMAGE_URL,
cls: "x-form-trigger " + this.triggerClass
});
if (!f.width) {
this.wrap.setWidth(el.getWidth() + this.trigger.getWidth());
}
if (!f.width) {
this.wrap.setWidth(el.getWidth() + this.trigger.getWidth());
}
this.splitter = this.wrap.createChild({
tag: 'div',
cls: this.splitterClass,
style: 'width:13px; height:2px;'
});
this.splitter.setRight((Ext.isIE) ? 1 : 2).setTop(10).show();
this.splitter = this.wrap.createChild({
tag: 'div',
cls: this.splitterClass,
style: 'width:13px; height:2px;'
});
this.splitter.setRight((Ext.isIE) ? 1 : 2).setTop(10).show();
this.proxy = this.trigger.createProxy('', this.splitter, true);
this.proxy.addClass("x-form-spinner-proxy");
this.proxy.setStyle('left', '0px');
this.proxy.setSize(14, 1);
this.proxy.hide();
this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, "SpinnerDrag", {
dragElId: this.proxy.id
});
this.proxy = this.trigger.createProxy('', this.splitter, true);
this.proxy.addClass("x-form-spinner-proxy");
this.proxy.setStyle('left', '0px');
this.proxy.setSize(14, 1);
this.proxy.hide();
this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, "SpinnerDrag", {
dragElId: this.proxy.id
});
this.initTrigger();
this.initSpinner();
},
this.initTrigger();
this.initSpinner();
},
doAfterRender: function(){
var y;
if (Ext.isIE && this.el.getY() != (y = this.trigger.getY())) {
this.el.position();
this.el.setY(y);
}
},
doAfterRender: function(){
var y;
if (Ext.isIE && this.el.getY() != (y = this.trigger.getY())) {
this.el.position();
this.el.setY(y);
}
},
doEnable: function(){
if (this.wrap) {
this.wrap.removeClass(this.field.disabledClass);
}
},
doEnable: function(){
if (this.wrap) {
this.wrap.removeClass(this.field.disabledClass);
}
},
doDisable: function(){
if (this.wrap) {
this.wrap.addClass(this.field.disabledClass);
this.el.removeClass(this.field.disabledClass);
}
},
doDisable: function(){
if (this.wrap) {
this.wrap.addClass(this.field.disabledClass);
this.el.removeClass(this.field.disabledClass);
}
},
doResize: function(w, h){
if (typeof w == 'number') {
this.el.setWidth(w - this.trigger.getWidth());
}
this.wrap.setWidth(this.el.getWidth() + this.trigger.getWidth());
},
doResize: function(w, h){
if (typeof w == 'number') {
this.el.setWidth(w - this.trigger.getWidth());
}
this.wrap.setWidth(this.el.getWidth() + this.trigger.getWidth());
},
doFocus: function(){
if (!this.mimicing) {
this.wrap.addClass('x-trigger-wrap-focus');
this.mimicing = true;
Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {
delay: 10
});
this.el.on('keydown', this.checkTab, this);
}
},
doFocus: function(){
if (!this.mimicing) {
this.wrap.addClass('x-trigger-wrap-focus');
this.mimicing = true;
Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {
delay: 10
});
this.el.on('keydown', this.checkTab, this);
}
},
// private
checkTab: function(e){
if (e.getKey() == e.TAB) {
this.triggerBlur();
}
},
// private
checkTab: function(e){
if (e.getKey() == e.TAB) {
this.triggerBlur();
}
},
// private
mimicBlur: function(e){
if (!this.wrap.contains(e.target) && this.field.validateBlur(e)) {
this.triggerBlur();
}
},
// private
mimicBlur: function(e){
if (!this.wrap.contains(e.target) && this.field.validateBlur(e)) {
this.triggerBlur();
}
},
// private
triggerBlur: function(){
this.mimicing = false;
Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
this.el.un("keydown", this.checkTab, this);
this.field.beforeBlur();
this.wrap.removeClass('x-trigger-wrap-focus');
this.field.onBlur.call(this.field);
},
// private
triggerBlur: function(){
this.mimicing = false;
Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
this.el.un("keydown", this.checkTab, this);
this.field.beforeBlur();
this.wrap.removeClass('x-trigger-wrap-focus');
this.field.onBlur.call(this.field);
},
initTrigger: function(){
this.trigger.addClassOnOver('x-form-trigger-over');
this.trigger.addClassOnClick('x-form-trigger-click');
},
initTrigger: function(){
this.trigger.addClassOnOver('x-form-trigger-over');
this.trigger.addClassOnClick('x-form-trigger-click');
},
initSpinner: function(){
this.field.addEvents({
'spin': true,
'spinup': true,
'spindown': true
});
initSpinner: function(){
this.field.addEvents({
'spin': true,
'spinup': true,
'spindown': true
});
this.keyNav = new Ext.KeyNav(this.el, {
"up": function(e){
e.preventDefault();
this.onSpinUp();
},
this.keyNav = new Ext.KeyNav(this.el, {
"up": function(e){
e.preventDefault();
this.onSpinUp();
},
"down": function(e){
e.preventDefault();
this.onSpinDown();
},
"down": function(e){
e.preventDefault();
this.onSpinDown();
},
"pageUp": function(e){
e.preventDefault();
this.onSpinUpAlternate();
},
"pageUp": function(e){
e.preventDefault();
this.onSpinUpAlternate();
},
"pageDown": function(e){
e.preventDefault();
this.onSpinDownAlternate();
},
"pageDown": function(e){
e.preventDefault();
this.onSpinDownAlternate();
},
scope: this
});
scope: this
});
this.repeater = new Ext.util.ClickRepeater(this.trigger, {
accelerate: this.accelerate
});
this.field.mon(this.repeater, "click", this.onTriggerClick, this, {
preventDefault: true
});
this.repeater = new Ext.util.ClickRepeater(this.trigger, {
accelerate: this.accelerate
});
this.field.mon(this.repeater, "click", this.onTriggerClick, this, {
preventDefault: true
});
this.field.mon(this.trigger, {
mouseover: this.onMouseOver,
mouseout: this.onMouseOut,
mousemove: this.onMouseMove,
mousedown: this.onMouseDown,
mouseup: this.onMouseUp,
scope: this,
preventDefault: true
});
this.field.mon(this.trigger, {
mouseover: this.onMouseOver,
mouseout: this.onMouseOut,
mousemove: this.onMouseMove,
mousedown: this.onMouseDown,
mouseup: this.onMouseUp,
scope: this,
preventDefault: true
});
this.field.mon(this.wrap, "mousewheel", this.handleMouseWheel, this);
this.field.mon(this.wrap, "mousewheel", this.handleMouseWheel, this);
this.dd.setXConstraint(0, 0, 10)
this.dd.setYConstraint(1500, 1500, 10);
this.dd.endDrag = this.endDrag.createDelegate(this);
this.dd.startDrag = this.startDrag.createDelegate(this);
this.dd.onDrag = this.onDrag.createDelegate(this);
},
this.dd.setXConstraint(0, 0, 10)
this.dd.setYConstraint(1500, 1500, 10);
this.dd.endDrag = this.endDrag.createDelegate(this);
this.dd.startDrag = this.startDrag.createDelegate(this);
this.dd.onDrag = this.onDrag.createDelegate(this);
},
onMouseOver: function(){
if (this.disabled) {
return;
}
var middle = this.getMiddle();
this.tmpHoverClass = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-overup' : 'x-form-spinner-overdown';
this.trigger.addClass(this.tmpHoverClass);
},
onMouseOver: function(){
if (this.disabled) {
return;
}
var middle = this.getMiddle();
this.tmpHoverClass = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-overup' : 'x-form-spinner-overdown';
this.trigger.addClass(this.tmpHoverClass);
},
//private
onMouseOut: function(){
this.trigger.removeClass(this.tmpHoverClass);
},
//private
onMouseOut: function(){
this.trigger.removeClass(this.tmpHoverClass);
},
//private
onMouseMove: function(){
if (this.disabled) {
return;
}
var middle = this.getMiddle();
if (((Ext.EventObject.getPageY() > middle) && this.tmpHoverClass == "x-form-spinner-overup") ||
((Ext.EventObject.getPageY() < middle) && this.tmpHoverClass == "x-form-spinner-overdown")) {
}
},
//private
onMouseMove: function(){
if (this.disabled) {
return;
}
var middle = this.getMiddle();
if (((Ext.EventObject.getPageY() > middle) && this.tmpHoverClass == "x-form-spinner-overup") ||
((Ext.EventObject.getPageY() < middle) && this.tmpHoverClass == "x-form-spinner-overdown")) {
}
},
//private
onMouseDown: function(){
if (this.disabled) {
return;
}
var middle = this.getMiddle();
this.tmpClickClass = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-clickup' : 'x-form-spinner-clickdown';
this.trigger.addClass(this.tmpClickClass);
},
//private
onMouseDown: function(){
if (this.disabled) {
return;
}
var middle = this.getMiddle();
this.tmpClickClass = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-clickup' : 'x-form-spinner-clickdown';
this.trigger.addClass(this.tmpClickClass);
},
//private
onMouseUp: function(){
this.trigger.removeClass(this.tmpClickClass);
},
//private
onMouseUp: function(){
this.trigger.removeClass(this.tmpClickClass);
},
//private
onTriggerClick: function(){
if (this.disabled || this.el.dom.readOnly) {
return;
}
var middle = this.getMiddle();
var ud = (Ext.EventObject.getPageY() < middle) ? 'Up' : 'Down';
this['onSpin' + ud]();
},
//private
onTriggerClick: function(){
if (this.disabled || this.el.dom.readOnly) {
return;
}
var middle = this.getMiddle();
var ud = (Ext.EventObject.getPageY() < middle) ? 'Up' : 'Down';
this['onSpin' + ud]();
},
//private
getMiddle: function(){
var t = this.trigger.getTop();
var h = this.trigger.getHeight();
var middle = t + (h / 2);
return middle;
},
//private
getMiddle: function(){
var t = this.trigger.getTop();
var h = this.trigger.getHeight();
var middle = t + (h / 2);
return middle;
},
//private
//checks if control is allowed to spin
isSpinnable: function(){
if (this.disabled || this.el.dom.readOnly) {
Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly
return false;
}
return true;
},
//private
//checks if control is allowed to spin
isSpinnable: function(){
if (this.disabled || this.el.dom.readOnly) {
Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly
return false;
}
return true;
},
handleMouseWheel: function(e){
//disable scrolling when not focused
if (this.wrap.hasClass('x-trigger-wrap-focus') == false) {
return;
}
handleMouseWheel: function(e){
//disable scrolling when not focused
if (this.wrap.hasClass('x-trigger-wrap-focus') == false) {
return;
}
var delta = e.getWheelDelta();
if (delta > 0) {
this.onSpinUp();
e.stopEvent();
}
else
if (delta < 0) {
this.onSpinDown();
e.stopEvent();
}
},
var delta = e.getWheelDelta();
if (delta > 0) {
this.onSpinUp();
e.stopEvent();
}
else
if (delta < 0) {
this.onSpinDown();
e.stopEvent();
}
},
//private
startDrag: function(){
this.proxy.show();
this._previousY = Ext.fly(this.dd.getDragEl()).getTop();
},
//private
startDrag: function(){
this.proxy.show();
this._previousY = Ext.fly(this.dd.getDragEl()).getTop();
},
//private
endDrag: function(){
this.proxy.hide();
},
//private
endDrag: function(){
this.proxy.hide();
},
//private
onDrag: function(){
if (this.disabled) {
return;
}
var y = Ext.fly(this.dd.getDragEl()).getTop();
var ud = '';
//private
onDrag: function(){
if (this.disabled) {
return;
}
var y = Ext.fly(this.dd.getDragEl()).getTop();
var ud = '';
if (this._previousY > y) {
ud = 'Up';
} //up
if (this._previousY < y) {
ud = 'Down';
} //down
if (ud != '') {
this['onSpin' + ud]();
}
if (this._previousY > y) {
ud = 'Up';
} //up
if (this._previousY < y) {
ud = 'Down';
} //down
if (ud != '') {
this['onSpin' + ud]();
}
this._previousY = y;
},
this._previousY = y;
},
//private
onSpinUp: function(){
if (this.isSpinnable() == false) {
return;
}
if (Ext.EventObject.shiftKey == true) {
this.onSpinUpAlternate();
return;
}
else {
this.spin(false, false);
}
this.field.fireEvent("spin", this);
this.field.fireEvent("spinup", this);
},
//private
onSpinUp: function(){
if (this.isSpinnable() == false) {
return;
}
if (Ext.EventObject.shiftKey == true) {
this.onSpinUpAlternate();
return;
}
else {
this.spin(false, false);
}
this.field.fireEvent("spin", this);
this.field.fireEvent("spinup", this);
},
//private
onSpinDown: function(){
if (this.isSpinnable() == false) {
return;
}
if (Ext.EventObject.shiftKey == true) {
this.onSpinDownAlternate();
return;
}
else {
this.spin(true, false);
}
this.field.fireEvent("spin", this);
this.field.fireEvent("spindown", this);
},
//private
onSpinDown: function(){
if (this.isSpinnable() == false) {
return;
}
if (Ext.EventObject.shiftKey == true) {
this.onSpinDownAlternate();
return;
}
else {
this.spin(true, false);
}
this.field.fireEvent("spin", this);
this.field.fireEvent("spindown", this);
},
//private
onSpinUpAlternate: function(){
if (this.isSpinnable() == false) {
return;
}
this.spin(false, true);
this.field.fireEvent("spin", this);
this.field.fireEvent("spinup", this);
},
//private
onSpinUpAlternate: function(){
if (this.isSpinnable() == false) {
return;
}
this.spin(false, true);
this.field.fireEvent("spin", this);
this.field.fireEvent("spinup", this);
},
//private
onSpinDownAlternate: function(){
if (this.isSpinnable() == false) {
return;
}
this.spin(true, true);
this.field.fireEvent("spin", this);
this.field.fireEvent("spindown", this);
},
//private
onSpinDownAlternate: function(){
if (this.isSpinnable() == false) {
return;
}
this.spin(true, true);
this.field.fireEvent("spin", this);
this.field.fireEvent("spindown", this);
},
spin: function(down, alternate){
var v = parseFloat(this.field.getValue());
var incr = (alternate == true) ? this.alternateIncrementValue : this.incrementValue;
(down == true) ? v -= incr : v += incr;
spin: function(down, alternate){
var v = parseFloat(this.field.getValue());
var incr = (alternate == true) ? this.alternateIncrementValue : this.incrementValue;
(down == true) ? v -= incr : v += incr;
v = (isNaN(v)) ? this.defaultValue : v;
v = this.fixBoundries(v);
this.field.setRawValue(v);
},
v = (isNaN(v)) ? this.defaultValue : v;
v = this.fixBoundries(v);
this.field.setRawValue(v);
},
fixBoundries: function(value){
var v = value;
fixBoundries: function(value){
var v = value;
if (this.field.minValue != undefined && v < this.field.minValue) {
v = this.field.minValue;
}
if (this.field.maxValue != undefined && v > this.field.maxValue) {
v = this.field.maxValue;
}
if (this.field.minValue != undefined && v < this.field.minValue) {
v = this.field.minValue;
}
if (this.field.maxValue != undefined && v > this.field.maxValue) {
v = this.field.maxValue;
}
return this.fixPrecision(v);
},
return this.fixPrecision(v);
},
// private
fixPrecision: function(value){
var nan = isNaN(value);
if (!this.field.allowDecimals || this.field.decimalPrecision == -1 || nan || !value) {
return nan ? '' : value;
}
return parseFloat(parseFloat(value).toFixed(this.field.decimalPrecision));
},
// private
fixPrecision: function(value){
var nan = isNaN(value);
if (!this.field.allowDecimals || this.field.decimalPrecision == -1 || nan || !value) {
return nan ? '' : value;
}
return parseFloat(parseFloat(value).toFixed(this.field.decimalPrecision));
},
doDestroy: function(){
if (this.trigger) {
this.trigger.remove();
}
if (this.wrap) {
this.wrap.remove();
delete this.field.wrap;
}
doDestroy: function(){
if (this.trigger) {
this.trigger.remove();
}
if (this.wrap) {
this.wrap.remove();
delete this.field.wrap;
}
if (this.splitter) {
this.splitter.remove();
}
if (this.splitter) {
this.splitter.remove();
}
if (this.dd) {
this.dd.unreg();
this.dd = null;
}
if (this.dd) {
this.dd.unreg();
this.dd = null;
}
if (this.proxy) {
this.proxy.remove();
}
if (this.proxy) {
this.proxy.remove();
}
if (this.repeater) {
this.repeater.purgeListeners();
}
}
if (this.repeater) {
this.repeater.purgeListeners();
}
}
});
//backwards compat

View file

@ -339,9 +339,9 @@ statusBar.setStatus({
scope: this,
callback: function(){
this.setStatus({
text: text,
iconCls: iconCls
});
text: text,
iconCls: iconCls
});
this.statusEl.el.show();
}
@ -349,10 +349,10 @@ statusBar.setStatus({
}else{
// hide/show the el to avoid jumpy text or icon
this.statusEl.hide();
this.setStatus({
text: text,
iconCls: iconCls
});
this.setStatus({
text: text,
iconCls: iconCls
});
this.statusEl.show();
}
return this;
@ -391,14 +391,14 @@ statusBar.setStatus({
cls = cls || '';
if(this.rendered){
if(this.currIconCls){
this.statusEl.removeClass(this.currIconCls);
this.currIconCls = null;
}
if(cls.length > 0){
this.statusEl.addClass(cls);
this.currIconCls = cls;
}
if(this.currIconCls){
this.statusEl.removeClass(this.currIconCls);
this.currIconCls = null;
}
if(cls.length > 0){
this.statusEl.addClass(cls);
this.currIconCls = cls;
}
}else{
this.currIconCls = cls;
}

View file

@ -34,38 +34,38 @@
Ext.override(Ext.form.RadioGroup, {
afterRender: function() {
this.items.each(function(i) {
this.relayEvents(i, ['check']);
}, this);
if (this.lazyValue) {
this.setValue(this.value);
delete this.value;
delete this.lazyValue;
}
Ext.form.RadioGroup.superclass.afterRender.call(this)
this.items.each(function(i) {
this.relayEvents(i, ['check']);
}, this);
if (this.lazyValue) {
this.setValue(this.value);
delete this.value;
delete this.lazyValue;
}
Ext.form.RadioGroup.superclass.afterRender.call(this)
},
getName: function() {
return this.items.first().getName();
return this.items.first().getName();
},
getValue: function() {
return this.items.first().getGroupValue();
return this.items.first().getGroupValue();
},
setValue: function(v) {
if (!this.items.each) {
this.value = v;
this.lazyValue = true;
return;
}
this.items.each(function(item) {
if (item.rendered) {
var checked = (item.el.getValue() == String(v));
item.el.dom.checked = checked;
item.el.dom.defaultChecked = checked;
item.wrap[checked ? 'addClass' : 'removeClass'](item.checkedCls);
}
});
if (!this.items.each) {
this.value = v;
this.lazyValue = true;
return;
}
this.items.each(function(item) {
if (item.rendered) {
var checked = (item.el.getValue() == String(v));
item.el.dom.checked = checked;
item.el.dom.defaultChecked = checked;
item.wrap[checked ? 'addClass' : 'removeClass'](item.checkedCls);
}
});
}
});

View file

@ -13,46 +13,46 @@ Ext.ns('Ext.ux.form');
* @xtype spinnerfield
*/
Ext.ux.form.SpinnerField = Ext.extend(Ext.form.NumberField, {
actionMode: 'wrap',
deferHeight: true,
autoSize: Ext.emptyFn,
onBlur: Ext.emptyFn,
adjustSize: Ext.BoxComponent.prototype.adjustSize,
actionMode: 'wrap',
deferHeight: true,
autoSize: Ext.emptyFn,
onBlur: Ext.emptyFn,
adjustSize: Ext.BoxComponent.prototype.adjustSize,
constructor: function(config) {
var spinnerConfig = Ext.copyTo({}, config, 'incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass');
constructor: function(config) {
var spinnerConfig = Ext.copyTo({}, config, 'incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass');
var spl = this.spinner = new Ext.ux.Spinner(spinnerConfig);
var spl = this.spinner = new Ext.ux.Spinner(spinnerConfig);
var plugins = config.plugins
? (Ext.isArray(config.plugins)
? config.plugins.push(spl)
: [config.plugins, spl])
: spl;
var plugins = config.plugins
? (Ext.isArray(config.plugins)
? config.plugins.push(spl)
: [config.plugins, spl])
: spl;
Ext.ux.form.SpinnerField.superclass.constructor.call(this, Ext.apply(config, {plugins: plugins}));
},
Ext.ux.form.SpinnerField.superclass.constructor.call(this, Ext.apply(config, {plugins: plugins}));
},
// private
getResizeEl: function(){
return this.wrap;
},
// private
getResizeEl: function(){
return this.wrap;
},
// private
getPositionEl: function(){
return this.wrap;
},
// private
getPositionEl: function(){
return this.wrap;
},
// private
alignErrorIcon: function(){
if (this.wrap) {
this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
}
},
// private
alignErrorIcon: function(){
if (this.wrap) {
this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
}
},
validateBlur: function(){
return true;
}
validateBlur: function(){
return true;
}
});
Ext.reg('spinnerfield', Ext.ux.form.SpinnerField);

View file

@ -31,5 +31,5 @@
*/
Ext.override(Ext.ux.form.SpinnerField, {
onBlur: Ext.form.Field.prototype.onBlur
onBlur: Ext.form.Field.prototype.onBlur
});

View file

@ -99,7 +99,7 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
// Generate the column configs with the correct width setting
for(var i=0; i<numCols; i++){
var cc = Ext.apply({items:[]}, colCfg);
var cc = Ext.apply({items:[]}, colCfg);
cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
if(this.defaults){
cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)
@ -156,17 +156,17 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
field.on('spin', this.onFieldChange, this);
}, this);
if (this.lazyValueSet) {
this.setValue(this.value);
delete this.value;
delete this.lazyValueSet;
}
if (this.lazyValueSet) {
this.setValue(this.value);
delete this.value;
delete this.lazyValueSet;
}
if (this.lazyRawValueSet) {
this.setRawValue(this.rawValue);
delete this.rawValue;
delete this.lazyRawValueSet;
}
if (this.lazyRawValueSet) {
this.setRawValue(this.rawValue);
delete this.rawValue;
delete this.lazyRawValueSet;
}
}
Ext.ux.form.SpinnerGroup.superclass.onRender.call(this, ct, position);
@ -176,7 +176,7 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
this.fireEvent('change', this, this.getValue());
},
initValue : Ext.emptyFn,
initValue : Ext.emptyFn,
getValue: function() {
var value = [this.items.getCount()];
@ -195,25 +195,25 @@ Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
},
setValue: function(value) {
if (!this.rendered) {
this.value = value;
this.lazyValueSet = true;
} else {
this.items.each(function(item, i) {
item.setValue(value[i]);
});
}
if (!this.rendered) {
this.value = value;
this.lazyValueSet = true;
} else {
this.items.each(function(item, i) {
item.setValue(value[i]);
});
}
},
setRawValue: function(value) {
if (!this.rendered) {
this.rawValue = value;
this.lazyRawValueSet = true;
} else {
this.items.each(function(item, i) {
item.setRawValue(value[i]);
});
}
if (!this.rendered) {
this.rawValue = value;
this.lazyRawValueSet = true;
} else {
this.items.each(function(item, i) {
item.setRawValue(value[i]);
});
}
}
});
Ext.reg('spinnergroup', Ext.ux.form.SpinnerGroup);

View file

@ -42,54 +42,54 @@ Ext.namespace("Ext.ux.form");
*/
Ext.ux.form.ToggleField = Ext.extend(Ext.form.Field, {
cls: 'x-toggle-field',
cls: 'x-toggle-field',
initComponent: function() {
Ext.ux.form.ToggleField.superclass.initComponent.call(this);
initComponent: function() {
Ext.ux.form.ToggleField.superclass.initComponent.call(this);
this.toggle = new Ext.form.Checkbox();
this.toggle.on('check', this.onToggleCheck, this);
this.toggle = new Ext.form.Checkbox();
this.toggle.on('check', this.onToggleCheck, this);
this.input = new Ext.form.TextField({
disabled: true
});
},
this.input = new Ext.form.TextField({
disabled: true
});
},
onRender: function(ct, position) {
if (!this.el) {
this.panel = new Ext.Panel({
cls: this.groupCls,
layout: 'table',
layoutConfig: {
columns: 2
},
border: false,
renderTo: ct
});
this.panel.ownerCt = this;
this.el = this.panel.getEl();
onRender: function(ct, position) {
if (!this.el) {
this.panel = new Ext.Panel({
cls: this.groupCls,
layout: 'table',
layoutConfig: {
columns: 2
},
border: false,
renderTo: ct
});
this.panel.ownerCt = this;
this.el = this.panel.getEl();
this.panel.add(this.toggle);
this.panel.add(this.input);
this.panel.doLayout();
this.panel.add(this.toggle);
this.panel.add(this.input);
this.panel.doLayout();
this.toggle.getEl().parent().setStyle('padding-right', '10px');
}
Ext.ux.form.ToggleField.superclass.onRender.call(this, ct, position);
},
this.toggle.getEl().parent().setStyle('padding-right', '10px');
}
Ext.ux.form.ToggleField.superclass.onRender.call(this, ct, position);
},
// private
onResize: function(w, h) {
this.panel.setSize(w, h);
this.panel.doLayout();
// private
onResize: function(w, h) {
this.panel.setSize(w, h);
this.panel.doLayout();
// we substract 10 for the padding :-)
var inputWidth = w - this.toggle.getSize().width - 25;
this.input.setSize(inputWidth, h);
},
// we substract 10 for the padding :-)
var inputWidth = w - this.toggle.getSize().width - 25;
this.input.setSize(inputWidth, h);
},
onToggleCheck: function(toggle, checked) {
this.input.setDisabled(!checked);
}
onToggleCheck: function(toggle, checked) {
this.input.setDisabled(!checked);
}
});
Ext.reg('togglefield', Ext.ux.form.ToggleField);

View file

@ -12,208 +12,208 @@ Ext.ns('Ext.ux.grid');
* A custom GridView which renders rows on an as-needed basis.
*/
Ext.ux.grid.BufferView = Ext.extend(Ext.grid.GridView, {
/**
* @cfg {Number} rowHeight
* The height of a row in the grid.
*/
rowHeight: 19,
/**
* @cfg {Number} rowHeight
* The height of a row in the grid.
*/
rowHeight: 19,
/**
* @cfg {Number} borderHeight
* The combined height of border-top and border-bottom of a row.
*/
borderHeight: 2,
/**
* @cfg {Number} borderHeight
* The combined height of border-top and border-bottom of a row.
*/
borderHeight: 2,
/**
* @cfg {Boolean/Number} scrollDelay
* The number of milliseconds before rendering rows out of the visible
* viewing area. Defaults to 100. Rows will render immediately with a config
* of false.
*/
scrollDelay: 100,
/**
* @cfg {Boolean/Number} scrollDelay
* The number of milliseconds before rendering rows out of the visible
* viewing area. Defaults to 100. Rows will render immediately with a config
* of false.
*/
scrollDelay: 100,
/**
* @cfg {Number} cacheSize
* The number of rows to look forward and backwards from the currently viewable
* area. The cache applies only to rows that have been rendered already.
*/
cacheSize: 20,
/**
* @cfg {Number} cacheSize
* The number of rows to look forward and backwards from the currently viewable
* area. The cache applies only to rows that have been rendered already.
*/
cacheSize: 20,
/**
* @cfg {Number} cleanDelay
* The number of milliseconds to buffer cleaning of extra rows not in the
* cache.
*/
cleanDelay: 500,
/**
* @cfg {Number} cleanDelay
* The number of milliseconds to buffer cleaning of extra rows not in the
* cache.
*/
cleanDelay: 500,
initTemplates : function(){
Ext.ux.grid.BufferView.superclass.initTemplates.call(this);
var ts = this.templates;
// empty div to act as a place holder for a row
ts.rowHolder = new Ext.Template(
'<div class="x-grid3-row {alt}" style="{tstyle}"></div>'
);
ts.rowHolder.disableFormats = true;
ts.rowHolder.compile();
initTemplates : function(){
Ext.ux.grid.BufferView.superclass.initTemplates.call(this);
var ts = this.templates;
// empty div to act as a place holder for a row
ts.rowHolder = new Ext.Template(
'<div class="x-grid3-row {alt}" style="{tstyle}"></div>'
);
ts.rowHolder.disableFormats = true;
ts.rowHolder.compile();
ts.rowBody = new Ext.Template(
'<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
'<tbody><tr>{cells}</tr>',
(this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
'</tbody></table>'
);
ts.rowBody.disableFormats = true;
ts.rowBody.compile();
},
ts.rowBody = new Ext.Template(
'<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
'<tbody><tr>{cells}</tr>',
(this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
'</tbody></table>'
);
ts.rowBody.disableFormats = true;
ts.rowBody.compile();
},
getStyleRowHeight : function(){
return Ext.isBorderBox ? (this.rowHeight + this.borderHeight) : this.rowHeight;
},
getStyleRowHeight : function(){
return Ext.isBorderBox ? (this.rowHeight + this.borderHeight) : this.rowHeight;
},
getCalculatedRowHeight : function(){
return this.rowHeight + this.borderHeight;
},
getCalculatedRowHeight : function(){
return this.rowHeight + this.borderHeight;
},
getVisibleRowCount : function(){
var rh = this.getCalculatedRowHeight();
var visibleHeight = this.scroller.dom.clientHeight;
return (visibleHeight < 1) ? 0 : Math.ceil(visibleHeight / rh);
},
getVisibleRowCount : function(){
var rh = this.getCalculatedRowHeight();
var visibleHeight = this.scroller.dom.clientHeight;
return (visibleHeight < 1) ? 0 : Math.ceil(visibleHeight / rh);
},
getVisibleRows: function(){
var count = this.getVisibleRowCount();
var sc = this.scroller.dom.scrollTop;
var start = (sc == 0 ? 0 : Math.floor(sc/this.getCalculatedRowHeight())-1);
return {
first: Math.max(start, 0),
last: Math.min(start + count + 2, this.ds.getCount()-1)
};
},
getVisibleRows: function(){
var count = this.getVisibleRowCount();
var sc = this.scroller.dom.scrollTop;
var start = (sc == 0 ? 0 : Math.floor(sc/this.getCalculatedRowHeight())-1);
return {
first: Math.max(start, 0),
last: Math.min(start + count + 2, this.ds.getCount()-1)
};
},
doRender : function(cs, rs, ds, startRow, colCount, stripe, onlyBody){
var ts = this.templates, ct = ts.cell, rt = ts.row, rb = ts.rowBody, last = colCount-1;
var rh = this.getStyleRowHeight();
var vr = this.getVisibleRows();
var tstyle = 'width:'+this.getTotalWidth()+';height:'+rh+'px;';
// buffers
var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
for (var j = 0, len = rs.length; j < len; j++) {
r = rs[j]; cb = [];
var rowIndex = (j+startRow);
var visible = rowIndex >= vr.first && rowIndex <= vr.last;
if (visible) {
for (var i = 0; i < colCount; i++) {
c = cs[i];
p.id = c.id;
p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
p.attr = p.cellAttr = "";
p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
p.style = c.style;
if (p.value == undefined || p.value === "") {
p.value = "&#160;";
}
if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
p.css += ' x-grid3-dirty-cell';
}
cb[cb.length] = ct.apply(p);
}
}
var alt = [];
if(stripe && ((rowIndex+1) % 2 == 0)){
alt[0] = "x-grid3-row-alt";
}
if(r.dirty){
alt[1] = " x-grid3-dirty-row";
}
rp.cols = colCount;
if(this.getRowClass){
alt[2] = this.getRowClass(r, rowIndex, rp, ds);
}
rp.alt = alt.join(" ");
rp.cells = cb.join("");
buf[buf.length] = !visible ? ts.rowHolder.apply(rp) : (onlyBody ? rb.apply(rp) : rt.apply(rp));
}
return buf.join("");
},
doRender : function(cs, rs, ds, startRow, colCount, stripe, onlyBody){
var ts = this.templates, ct = ts.cell, rt = ts.row, rb = ts.rowBody, last = colCount-1;
var rh = this.getStyleRowHeight();
var vr = this.getVisibleRows();
var tstyle = 'width:'+this.getTotalWidth()+';height:'+rh+'px;';
// buffers
var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
for (var j = 0, len = rs.length; j < len; j++) {
r = rs[j]; cb = [];
var rowIndex = (j+startRow);
var visible = rowIndex >= vr.first && rowIndex <= vr.last;
if (visible) {
for (var i = 0; i < colCount; i++) {
c = cs[i];
p.id = c.id;
p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
p.attr = p.cellAttr = "";
p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
p.style = c.style;
if (p.value == undefined || p.value === "") {
p.value = "&#160;";
}
if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
p.css += ' x-grid3-dirty-cell';
}
cb[cb.length] = ct.apply(p);
}
}
var alt = [];
if(stripe && ((rowIndex+1) % 2 == 0)){
alt[0] = "x-grid3-row-alt";
}
if(r.dirty){
alt[1] = " x-grid3-dirty-row";
}
rp.cols = colCount;
if(this.getRowClass){
alt[2] = this.getRowClass(r, rowIndex, rp, ds);
}
rp.alt = alt.join(" ");
rp.cells = cb.join("");
buf[buf.length] = !visible ? ts.rowHolder.apply(rp) : (onlyBody ? rb.apply(rp) : rt.apply(rp));
}
return buf.join("");
},
isRowRendered: function(index){
var row = this.getRow(index);
return row && row.childNodes.length > 0;
},
isRowRendered: function(index){
var row = this.getRow(index);
return row && row.childNodes.length > 0;
},
syncScroll: function(){
Ext.ux.grid.BufferView.superclass.syncScroll.apply(this, arguments);
this.update();
},
syncScroll: function(){
Ext.ux.grid.BufferView.superclass.syncScroll.apply(this, arguments);
this.update();
},
// a (optionally) buffered method to update contents of gridview
update: function(){
if (this.scrollDelay) {
if (!this.renderTask) {
this.renderTask = new Ext.util.DelayedTask(this.doUpdate, this);
}
this.renderTask.delay(this.scrollDelay);
}else{
this.doUpdate();
}
},
onRemove : function(ds, record, index, isUpdate){
Ext.ux.grid.BufferView.superclass.onRemove.apply(this, arguments);
if(isUpdate !== true){
this.update();
}
},
// a (optionally) buffered method to update contents of gridview
update: function(){
if (this.scrollDelay) {
if (!this.renderTask) {
this.renderTask = new Ext.util.DelayedTask(this.doUpdate, this);
}
this.renderTask.delay(this.scrollDelay);
}else{
this.doUpdate();
}
},
onRemove : function(ds, record, index, isUpdate){
Ext.ux.grid.BufferView.superclass.onRemove.apply(this, arguments);
if(isUpdate !== true){
this.update();
}
},
doUpdate: function(){
if (this.getVisibleRowCount() > 0) {
var g = this.grid, cm = g.colModel, ds = g.store;
var cs = this.getColumnData();
doUpdate: function(){
if (this.getVisibleRowCount() > 0) {
var g = this.grid, cm = g.colModel, ds = g.store;
var cs = this.getColumnData();
var vr = this.getVisibleRows();
for (var i = vr.first; i <= vr.last; i++) {
// if row is NOT rendered and is visible, render it
if(!this.isRowRendered(i)){
var html = this.doRender(cs, [ds.getAt(i)], ds, i, cm.getColumnCount(), g.stripeRows, true);
this.getRow(i).innerHTML = html;
}
}
this.clean();
}
},
var vr = this.getVisibleRows();
for (var i = vr.first; i <= vr.last; i++) {
// if row is NOT rendered and is visible, render it
if(!this.isRowRendered(i)){
var html = this.doRender(cs, [ds.getAt(i)], ds, i, cm.getColumnCount(), g.stripeRows, true);
this.getRow(i).innerHTML = html;
}
}
this.clean();
}
},
// a buffered method to clean rows
clean : function(){
if(!this.cleanTask){
this.cleanTask = new Ext.util.DelayedTask(this.doClean, this);
}
this.cleanTask.delay(this.cleanDelay);
},
// a buffered method to clean rows
clean : function(){
if(!this.cleanTask){
this.cleanTask = new Ext.util.DelayedTask(this.doClean, this);
}
this.cleanTask.delay(this.cleanDelay);
},
doClean: function(){
if (this.getVisibleRowCount() > 0) {
var vr = this.getVisibleRows();
vr.first -= this.cacheSize;
vr.last += this.cacheSize;
doClean: function(){
if (this.getVisibleRowCount() > 0) {
var vr = this.getVisibleRows();
vr.first -= this.cacheSize;
vr.last += this.cacheSize;
var i = 0, rows = this.getRows();
// if first is less than 0, all rows have been rendered
// so lets clean the end...
if(vr.first <= 0){
i = vr.last + 1;
}
for(var len = this.ds.getCount(); i < len; i++){
// if current row is outside of first and last and
// has content, update the innerHTML to nothing
if ((i < vr.first || i > vr.last) && rows[i].innerHTML) {
rows[i].innerHTML = '';
}
}
}
},
var i = 0, rows = this.getRows();
// if first is less than 0, all rows have been rendered
// so lets clean the end...
if(vr.first <= 0){
i = vr.last + 1;
}
for(var len = this.ds.getCount(); i < len; i++){
// if current row is outside of first and last and
// has content, update the innerHTML to nothing
if ((i < vr.first || i > vr.last) && rows[i].innerHTML) {
rows[i].innerHTML = '';
}
}
}
},
layout: function(){
Ext.ux.grid.BufferView.superclass.layout.call(this);
this.update();
}
layout: function(){
Ext.ux.grid.BufferView.superclass.layout.call(this);
this.update();
}
});

View file

@ -34,23 +34,23 @@
// remove spaces for hidden elements and make show(), hide(), enable() and disable() act on
// the label. don't use hideLabel with this.
Ext.override(Ext.layout.FormLayout, {
renderItem : function(c, position, target){
if(c && !c.rendered && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
var args = this.getTemplateArgs(c);
if(typeof position == 'number'){
position = target.dom.childNodes[position] || null;
}
if(position){
c.formItem = this.fieldTpl.insertBefore(position, args, true);
}else{
c.formItem = this.fieldTpl.append(target, args, true);
}
c.actionMode = 'formItem';
c.render('x-form-el-'+c.id);
c.container = c.formItem;
c.actionMode = 'container';
}else {
Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
}
}
renderItem : function(c, position, target){
if(c && !c.rendered && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
var args = this.getTemplateArgs(c);
if(typeof position == 'number'){
position = target.dom.childNodes[position] || null;
}
if(position){
c.formItem = this.fieldTpl.insertBefore(position, args, true);
}else{
c.formItem = this.fieldTpl.append(target, args, true);
}
c.actionMode = 'formItem';
c.render('x-form-el-'+c.id);
c.container = c.formItem;
c.actionMode = 'container';
}else {
Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
}
}
});

View file

@ -35,58 +35,58 @@
* @author Damien Churchill <damoxc@gmail.com>
*/
Ext.override(Ext.tree.MultiSelectionModel, {
onNodeClick: function (node, e) {
if (e.ctrlKey && this.isSelected(node)) {
this.unselect(node);
} else if (e.shiftKey && !this.isSelected(node)) {
var parentNode = node.parentNode;
// We can only shift select files in the same node
if (this.lastSelNode.parentNode.id != parentNode.id) return;
onNodeClick: function (node, e) {
if (e.ctrlKey && this.isSelected(node)) {
this.unselect(node);
} else if (e.shiftKey && !this.isSelected(node)) {
var parentNode = node.parentNode;
// We can only shift select files in the same node
if (this.lastSelNode.parentNode.id != parentNode.id) return;
// Get the node indexes
var fi = parentNode.indexOf(node),
li = parentNode.indexOf(this.lastSelNode);
// Get the node indexes
var fi = parentNode.indexOf(node),
li = parentNode.indexOf(this.lastSelNode);
// Select the last clicked node and wipe old selections
this.select(this.lastSelNode, e, false, true);
// Select the last clicked node and wipe old selections
this.select(this.lastSelNode, e, false, true);
// Swap the values if required
if (fi > li) {
fi = fi + li, li = fi - li, fi = fi - li;
}
// Swap the values if required
if (fi > li) {
fi = fi + li, li = fi - li, fi = fi - li;
}
// Select all the nodes
parentNode.eachChild(function(n) {
var i = parentNode.indexOf(n);
if (fi < i && i < li) {
this.select(n, e, true, true);
}
}, this);
// Select all the nodes
parentNode.eachChild(function(n) {
var i = parentNode.indexOf(n);
if (fi < i && i < li) {
this.select(n, e, true, true);
}
}, this);
// Select the clicked node
this.select(node, e, true);
} else {
this.select(node, e, e.ctrlKey);
}
},
// Select the clicked node
this.select(node, e, true);
} else {
this.select(node, e, e.ctrlKey);
}
},
select: function(node, e, keepExisting, suppressEvent) {
if(keepExisting !== true){
this.clearSelections(true);
}
if(this.isSelected(node)){
this.lastSelNode = node;
return node;
}
this.selNodes.push(node);
this.selMap[node.id] = node;
this.lastSelNode = node;
node.ui.onSelectedChange(true);
if (suppressEvent !== true) {
this.fireEvent('selectionchange', this, this.selNodes);
}
select: function(node, e, keepExisting, suppressEvent) {
if(keepExisting !== true){
this.clearSelections(true);
}
if(this.isSelected(node)){
this.lastSelNode = node;
return node;
}
this.selNodes.push(node);
this.selMap[node.id] = node;
this.lastSelNode = node;
node.ui.onSelectedChange(true);
if (suppressEvent !== true) {
this.fireEvent('selectionchange', this, this.selNodes);
}
return node;
}
}
})

View file

@ -56,7 +56,7 @@ Ext.tree.ColumnResizer = Ext.extend(Ext.util.Observable, {
}
if(ps) {
this.activeHd = Ext.get(ps);
ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
}
} else if(r.right - x <= hw) {
var ns = hd.dom;
@ -65,7 +65,7 @@ Ext.tree.ColumnResizer = Ext.extend(Ext.util.Observable, {
}
if(ns) {
this.activeHd = Ext.get(ns);
ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
}
} else{
delete this.activeHd;

View file

@ -32,22 +32,22 @@
Ext.override(Ext.ux.tree.TreeGridNodeUI, {
updateColumns: function() {
if (!this.rendered) return;
var a = this.node.attributes,
t = this.node.getOwnerTree(),
cols = t.columns,
c = cols[0];
updateColumns: function() {
if (!this.rendered) return;
var a = this.node.attributes,
t = this.node.getOwnerTree(),
cols = t.columns,
c = cols[0];
// Update the first column
this.anchor.firstChild.innerHTML = (c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text);
// Update the first column
this.anchor.firstChild.innerHTML = (c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text);
// Update the remaining columns
for(i = 1, len = cols.length; i < len; i++) {
c = cols[i];
this.elNode.childNodes[i].firstChild.innerHTML = (c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text);
}
}
// Update the remaining columns
for(i = 1, len = cols.length; i < len; i++) {
c = cols[i];
this.elNode.childNodes[i].firstChild.innerHTML = (c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text);
}
}
});

View file

@ -1,10 +1,10 @@
Ext.tree.RenderColumn = Ext.extend(Ext.tree.Column, {
constructor: function(c) {
c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
c.tpl.format = c.renderer;
c.tpl.col = this;
Ext.tree.RenderColumn.superclass.constructor.call(this, c);
}
constructor: function(c) {
c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
c.tpl.format = c.renderer;
c.tpl.col = this;
Ext.tree.RenderColumn.superclass.constructor.call(this, c);
}
});
Ext.reg('tgrendercolumn', Ext.tree.RenderColumn);

View file

@ -56,14 +56,14 @@ Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, {
return -1;
}
}
var v1 = sortType ? sortType(n1.attributes[p]) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
var v2 = sortType ? sortType(n2.attributes[p]) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
if(v1 < v2){
return dsc ? +1 : -1;
}else if(v1 > v2){
return dsc ? -1 : +1;
var v1 = sortType ? sortType(n1.attributes[p]) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
var v2 = sortType ? sortType(n2.attributes[p]) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
if(v1 < v2){
return dsc ? +1 : -1;
}else if(v1 > v2){
return dsc ? -1 : +1;
}else{
return 0;
return 0;
}
};