summaryrefslogtreecommitdiffstats
path: root/deluge/ui/web/js
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/ui/web/js')
-rw-r--r--deluge/ui/web/js/deluge-all-debug.js9969
-rw-r--r--deluge/ui/web/js/deluge-all.js291
-rw-r--r--deluge/ui/web/js/deluge-all/ConnectionManager.js21
-rw-r--r--deluge/ui/web/js/deluge-all/Sidebar.js18
-rw-r--r--deluge/ui/web/js/deluge-all/UI.js31
-rw-r--r--deluge/ui/web/js/deluge-all/details/FilesTab.js4
-rw-r--r--deluge/ui/web/js/deluge-all/details/OptionsTab.js4
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js2
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/DaemonPage.js2
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/InterfacePage.js2
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions-debug.js2927
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions.js84
-rw-r--r--deluge/ui/web/js/gettext.js326
13 files changed, 60 insertions, 13621 deletions
diff --git a/deluge/ui/web/js/deluge-all-debug.js b/deluge/ui/web/js/deluge-all-debug.js
deleted file mode 100644
index 67bb83a..0000000
--- a/deluge/ui/web/js/deluge-all-debug.js
+++ /dev/null
@@ -1,9969 +0,0 @@
-/**
- * Deluge.add.Window.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge.add');
-
-/**
- * @class Deluge.add.Window
- * @extends Ext.Window
- * Base class for an add Window
- */
-Deluge.add.Window = Ext.extend(Ext.Window, {
- initComponent: function () {
- Deluge.add.Window.superclass.initComponent.call(this);
- this.addEvents('beforeadd', 'add', 'addfailed');
- },
-
- /**
- * Create an id for the torrent before we have any info about it.
- */
- createTorrentId: function () {
- return new Date().getTime().toString();
- },
-});
-/**
- * Deluge.add.AddWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Ext.namespace('Deluge.add');
-
-// This override allows file upload buttons to contain icons
-Ext.override(Ext.ux.form.FileUploadField, {
- onRender: function (ct, position) {
- Ext.ux.form.FileUploadField.superclass.onRender.call(
- this,
- ct,
- position
- );
-
- this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
- this.el.addClass('x-form-file-text');
- this.el.dom.removeAttribute('name');
- this.createFileInput();
-
- var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
- text: this.buttonText,
- });
- this.button = new Ext.Button(
- Ext.apply(btnCfg, {
- renderTo: this.wrap,
- cls:
- 'x-form-file-btn' +
- (btnCfg.iconCls ? ' x-btn-text-icon' : ''),
- })
- );
-
- if (this.buttonOnly) {
- this.el.hide();
- this.wrap.setWidth(this.button.getEl().getWidth());
- }
-
- this.bindListeners();
- this.resizeEl = this.positionEl = this.wrap;
- },
-});
-
-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',
-
- initComponent: function () {
- Deluge.add.AddWindow.superclass.initComponent.call(this);
-
- this.addButton(_('Cancel'), this.onCancelClick, this);
- this.addButton(_('Add'), this.onAddClick, this);
-
- 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,
- dataIndex: 'text',
- tpl: new Ext.XTemplate(
- '<div class="x-deluge-add-torrent-name">{text:htmlEncode}</div>'
- ),
- },
- ],
- stripeRows: true,
- singleSelect: true,
- listeners: {
- selectionchange: {
- fn: this.onSelect,
- scope: this,
- },
- },
- hideHeaders: true,
- autoExpandColumn: 'torrent',
- height: '100%',
- autoScroll: true,
- });
-
- this.add({
- region: 'center',
- items: [this.list],
- border: false,
- bbar: new Ext.Toolbar({
- items: [
- {
- id: 'fileUploadForm',
- xtype: 'form',
- layout: 'fit',
- baseCls: 'x-plain',
- fileUpload: true,
- items: [
- {
- buttonOnly: true,
- xtype: 'fileuploadfield',
- id: 'torrentFile',
- name: 'file',
- multiple: true,
- buttonCfg: {
- iconCls: 'x-deluge-add-file',
- text: _('File'),
- },
- listeners: {
- scope: this,
- fileselected: this.onFileSelected,
- },
- },
- ],
- },
- {
- text: _('Url'),
- iconCls: 'icon-add-url',
- handler: this.onUrl,
- scope: this,
- },
- {
- text: _('Infohash'),
- iconCls: 'icon-magnet-add',
- hidden: true,
- disabled: true,
- },
- '->',
- {
- text: _('Remove'),
- iconCls: 'icon-remove',
- handler: this.onRemove,
- scope: this,
- },
- ],
- }),
- });
-
- this.fileUploadForm = Ext.getCmp('fileUploadForm').getForm();
- 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();
- // Reset upload form so handler fires when a canceled file is reselected
- this.fileUploadForm.reset();
- },
-
- 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();
- },
-
- onCancelClick: function () {
- this.clear();
- this.hide();
- },
-
- 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);
- },
-
- onRemove: function () {
- if (!this.list.getSelectionCount()) return;
- var torrent = this.list.getSelectedRecords()[0];
- if (!torrent) return;
- 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'));
- } 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);
- this.url.on('addfailed', this.onTorrentAddFailed, this);
- }
-
- this.optionsPanel.form.getDefaults();
- },
-
- onFileSelected: function () {
- if (this.fileUploadForm.isValid()) {
- var torrentIds = [];
- var files = this.fileUploadForm.findField('torrentFile').value;
- var randomId = this.createTorrentId();
- Array.prototype.forEach.call(
- files,
- function (file, i) {
- // Append index for batch of unique torrentIds.
- var torrentId = randomId + i.toString();
- torrentIds.push(torrentId);
- this.onTorrentBeforeAdd(torrentId, file.name);
- }.bind(this)
- );
- this.fileUploadForm.submit({
- url: deluge.config.base + 'upload',
- waitMsg: _('Uploading your torrent...'),
- success: this.onUploadSuccess,
- failure: this.onUploadFailure,
- scope: this,
- torrentIds: torrentIds,
- });
- }
- },
-
- onUploadSuccess: function (fp, upload) {
- if (!upload.result.success) {
- this.clear();
- return;
- }
-
- upload.result.files.forEach(
- function (filename, i) {
- deluge.client.web.get_torrent_info(filename, {
- success: this.onGotInfo,
- scope: this,
- filename: filename,
- torrentId: upload.options.torrentIds[i],
- });
- }.bind(this)
- );
- this.fileUploadForm.reset();
- },
-
- onUploadFailure: function (form, action) {
- this.hide();
- Ext.MessageBox.show({
- title: _('Error'),
- msg: _('Failed to upload torrent'),
- buttons: Ext.MessageBox.OK,
- modal: false,
- icon: Ext.MessageBox.ERROR,
- iconCls: 'x-deluge-icon-error',
- });
- this.fireEvent('addfailed', this.torrentId);
- },
-
- onGotInfo: function (info, obj, response, request) {
- info.filename = request.options.filename;
- torrentId = request.options.torrentId;
- this.onTorrentAdd(torrentId, info);
- },
-
- 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);
- this.list.select(r);
- }
- },
-
- onTorrentAddFailed: function (torrentId) {
- var store = this.list.getStore();
- var torrentRecord = store.getById(torrentId);
- if (torrentRecord) {
- store.remove(torrentRecord);
- }
- },
-
- onUrl: function (button, event) {
- this.url.show();
- },
-});
-/**
- * Deluge.add.FilesTab.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge.add');
-
-/**
- * @class Deluge.add.FilesTab
- * @extends Ext.ux.tree.TreeGrid
- */
-Deluge.add.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
- layout: 'fit',
- title: _('Files'),
-
- autoScroll: false,
- animate: false,
- border: false,
- disabled: true,
- rootVisible: false,
-
- columns: [
- {
- header: _('Filename'),
- width: 295,
- dataIndex: 'filename',
- tpl: new Ext.XTemplate('{filename:htmlEncode}'),
- },
- {
- 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);
- },
-
- 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();
-
- 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);
- }
- },
-});
-/**
- * Deluge.add.Infohash.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Ext.deluge.add');
-/**
- * Deluge.add.OptionsPanel.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge.add');
-
-Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
- torrents: {},
-
- // layout options
- region: 'south',
- border: false,
- activeTab: 0,
- height: 265,
-
- 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);
- },
-
- 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);
- },
-
- clear: function () {
- this.files.clearFiles();
- this.form.optionsManager.resetAll();
- },
-
- 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;
- },
-
- 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.form.setDisabled(false);
-
- if (this.torrents[torrentId]['files_tree']) {
- 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.files.setDisabled(false);
- this.files.show();
- } else {
- // Files tab is empty so show options tab
- this.form.show();
- this.files.setDisabled(true);
- }
- },
-
- 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);
- }
- },
-
- onFilesChecked: function (nodes, newValue, oldValue) {
- 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
- );
- },
-});
-/**
- * Deluge.add.OptionsPanel.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge.add');
-
-/**
- * @class Deluge.add.OptionsTab
- * @extends Ext.form.FormPanel
- */
-Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
- title: _('Options'),
- height: 170,
- border: false,
- bodyStyle: 'padding: 5px',
- disabled: true,
- labelWidth: 1,
-
- initComponent: function () {
- Deluge.add.OptionsTab.superclass.initComponent.call(this);
-
- this.optionsManager = new Deluge.MultiOptionsManager();
-
- var fieldset = this.add({
- xtype: 'fieldset',
- title: _('Download Folder'),
- border: false,
- autoHeight: true,
- defaultType: 'textfield',
- labelWidth: 1,
- fieldLabel: '',
- style: 'padding: 5px 0; margin-bottom: 0;',
- });
- this.optionsManager.bind(
- 'download_location',
- fieldset.add({
- fieldLabel: '',
- name: 'download_location',
- anchor: '95%',
- labelSeparator: '',
- })
- );
- var fieldset = this.add({
- xtype: 'fieldset',
- title: _('Move Completed Folder'),
- border: false,
- autoHeight: true,
- defaultType: 'togglefield',
- labelWidth: 1,
- fieldLabel: '',
- style: 'padding: 5px 0; margin-bottom: 0;',
- });
- var field = fieldset.add({
- fieldLabel: '',
- name: 'move_completed_path',
- anchor: '98%',
- });
- this.optionsManager.bind('move_completed', field.toggle);
- this.optionsManager.bind('move_completed_path', field.input);
-
- var panel = this.add({
- border: false,
- layout: 'column',
- defaultType: 'fieldset',
- });
-
- fieldset = panel.add({
- title: _('Bandwidth'),
- border: false,
- autoHeight: true,
- bodyStyle: 'padding: 2px 5px',
- labelWidth: 105,
- width: 200,
- defaultType: 'spinnerfield',
- style: 'padding-right: 10px;',
- });
- this.optionsManager.bind(
- 'max_download_speed',
- fieldset.add({
- fieldLabel: _('Max Down Speed'),
- name: 'max_download_speed',
- width: 60,
- })
- );
- this.optionsManager.bind(
- 'max_upload_speed',
- fieldset.add({
- fieldLabel: _('Max Up Speed'),
- name: 'max_upload_speed',
- width: 60,
- })
- );
- this.optionsManager.bind(
- 'max_connections',
- fieldset.add({
- fieldLabel: _('Max Connections'),
- name: 'max_connections',
- width: 60,
- })
- );
- this.optionsManager.bind(
- 'max_upload_slots',
- fieldset.add({
- fieldLabel: _('Max Upload Slots'),
- 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: '',
- })
- );
- this.optionsManager.bind(
- 'sequential_download',
- fieldset.add({
- name: 'sequential_download',
- boxLabel: _('Sequential Download'),
- fieldLabel: '',
- labelSeparator: '',
- })
- );
- this.optionsManager.bind(
- 'seed_mode',
- fieldset.add({
- name: 'seed_mode',
- boxLabel: _('Skip File Hash Check'),
- fieldLabel: '',
- labelSeparator: '',
- })
- );
- this.optionsManager.bind(
- 'super_seeding',
- fieldset.add({
- name: 'super_seeding',
- boxLabel: _('Super Seed'),
- fieldLabel: '',
- labelSeparator: '',
- })
- );
- this.optionsManager.bind(
- 'pre_allocate_storage',
- fieldset.add({
- name: 'pre_allocate_storage',
- boxLabel: _('Preallocate Disk Space'),
- fieldLabel: '',
- labelSeparator: '',
- })
- );
- },
-
- getDefaults: function () {
- var keys = [
- 'add_paused',
- 'pre_allocate_storage',
- 'download_location',
- 'max_connections_per_torrent',
- 'max_download_speed_per_torrent',
- 'move_completed',
- 'move_completed_path',
- 'max_upload_slots_per_torrent',
- 'max_upload_speed_per_torrent',
- 'prioritize_first_last_pieces',
- 'sequential_download',
- ];
-
- deluge.client.core.get_config_values(keys, {
- success: function (config) {
- var options = {
- file_priorities: [],
- add_paused: config.add_paused,
- sequential_download: config.sequential_download,
- pre_allocate_storage: config.pre_allocate_storage,
- download_location: config.download_location,
- move_completed: config.move_completed,
- move_completed_path: config.move_completed_path,
- 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,
- seed_mode: false,
- super_seeding: false,
- };
- this.optionsManager.options = options;
- this.optionsManager.resetAll();
- },
- scope: this,
- });
- },
-});
-/**
- * Deluge.add.UrlWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Ext.namespace('Deluge.add');
-Deluge.add.UrlWindow = Ext.extend(Deluge.add.Window, {
- title: _('Add from Url'),
- modal: true,
- plain: true,
- layout: 'fit',
- width: 350,
- height: 155,
-
- buttonAlign: 'center',
- closeAction: 'hide',
- bodyStyle: 'padding: 10px 5px;',
- iconCls: 'x-deluge-add-url-window-icon',
-
- initComponent: function () {
- Deluge.add.UrlWindow.superclass.initComponent.call(this);
- this.addButton(_('Add'), this.onAddClick, this);
-
- var form = this.add({
- xtype: 'form',
- defaultType: 'textfield',
- baseCls: 'x-plain',
- labelWidth: 55,
- });
-
- this.urlField = form.add({
- fieldLabel: _('Url'),
- id: 'url',
- name: 'url',
- width: '97%',
- });
- this.urlField.on('specialkey', this.onAdd, this);
-
- this.cookieField = form.add({
- fieldLabel: _('Cookies'),
- id: 'cookies',
- name: 'cookies',
- width: '97%',
- });
- this.cookieField.on('specialkey', this.onAdd, this);
- },
-
- onAddClick: function (field, e) {
- if (
- (field.id == 'url' || field.id == 'cookies') &&
- e.getKey() != e.ENTER
- )
- return;
-
- var field = this.urlField;
- var url = field.getValue();
- var cookies = this.cookieField.getValue();
- var torrentId = this.createTorrentId();
-
- if (url.indexOf('magnet:?') == 0 && url.indexOf('xt=urn:btih') > -1) {
- deluge.client.web.get_magnet_info(url, {
- success: this.onGotInfo,
- scope: this,
- filename: url,
- torrentId: torrentId,
- });
- } else {
- deluge.client.web.download_torrent_from_url(url, cookies, {
- success: this.onDownload,
- failure: this.onDownloadFailed,
- scope: this,
- torrentId: torrentId,
- });
- }
-
- this.hide();
- this.urlField.setValue('');
- this.fireEvent('beforeadd', torrentId, url);
- },
-
- onDownload: function (filename, obj, resp, req) {
- deluge.client.web.get_torrent_info(filename, {
- success: this.onGotInfo,
- failure: this.onDownloadFailed,
- scope: this,
- filename: filename,
- torrentId: req.options.torrentId,
- });
- },
-
- onDownloadFailed: function (obj, resp, req) {
- Ext.MessageBox.show({
- title: _('Error'),
- msg: _('Failed to download torrent'),
- buttons: Ext.MessageBox.OK,
- modal: false,
- icon: Ext.MessageBox.ERROR,
- iconCls: 'x-deluge-icon-error',
- });
- this.fireEvent('addfailed', req.options.torrentId);
- },
-
- onGotInfo: function (info, obj, response, request) {
- info['filename'] = request.options.filename;
- this.fireEvent('add', request.options.torrentId, info);
- },
-});
-/**
- * Deluge.data.SortTypes.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.data');
-
-/**
- * Common sort functions that can be used for data Stores.
- *
- * @author Damien Churchill <damoxc@gmail.com>
- * @version 1.3
- *
- * @class Deluge.data.SortTypes
- * @singleton
- */
-Deluge.data.SortTypes = {
- // prettier-ignore
- 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;
- },
-
- asName: function (value) {
- return String(value).toLowerCase();
- },
-};
-/**
- * Deluge.data.PeerRecord.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.data');
-
-/**
- * Deluge.data.Peer record
- *
- * @author Damien Churchill <damoxc@gmail.com>
- * @version 1.3
- *
- * @class Deluge.data.Peer
- * @extends Ext.data.Record
- * @constructor
- * @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',
- },
-]);
-/**
- * Deluge.data.TorrentRecord.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.data');
-
-/**
- * Deluge.data.Torrent record
- *
- * @author Damien Churchill <damoxc@gmail.com>
- * @version 1.3
- *
- * @class Deluge.data.Torrent
- * @extends Ext.data.Record
- * @constructor
- * @param {Object} data The torrents data
- */
-Deluge.data.Torrent = Ext.data.Record.create([
- {
- name: 'queue',
- type: 'int',
- },
- {
- name: 'name',
- type: 'string',
- sortType: Deluge.data.SortTypes.asName,
- },
- {
- name: 'total_wanted',
- 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: 'save_path',
- type: 'string',
- },
- {
- name: 'total_done',
- type: 'int',
- },
- {
- name: 'total_uploaded',
- type: 'int',
- },
- {
- name: 'total_remaining',
- type: 'int',
- },
- {
- name: 'max_download_speed',
- type: 'int',
- },
- {
- name: 'max_upload_speed',
- type: 'int',
- },
- {
- name: 'seeds_peers_ratio',
- type: 'float',
- },
- {
- name: 'time_since_transfer',
- type: 'int',
- },
-]);
-/**
- * Deluge.details.DetailsPanel.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.details');
-
-/**
- * @class Deluge.details.DetailsPanel
- */
-Deluge.details.DetailsPanel = Ext.extend(Ext.TabPanel, {
- id: 'torrentDetails',
- 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 has not 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();
- },
-});
-/**
- * Deluge.Details.Details.js
- * The details tab displayed in the details panel.
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
- title: _('Details'),
-
- fields: {},
- autoScroll: true,
- queuedItems: {},
-
- oldData: {},
-
- initComponent: function () {
- Deluge.details.DetailsTab.superclass.initComponent.call(this);
- this.addItem('torrent_name', _('Name:'));
- this.addItem('hash', _('Hash:'));
- this.addItem('path', _('Download Folder:'));
- this.addItem('size', _('Total Size:'));
- this.addItem('files', _('Total Files:'));
- this.addItem('comment', _('Comment:'));
- this.addItem('status', _('Status:'));
- this.addItem('tracker', _('Tracker:'));
- this.addItem('creator', _('Created By:'));
- },
-
- 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]);
- }
- },
-
- 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
- );
- },
-
- 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,
- });
- },
-
- onRequestComplete: function (torrent, request, response, options) {
- var data = {
- torrent_name: torrent.name,
- hash: options.options.torrentId,
- path: torrent.download_location,
- size: fsize(torrent.total_size),
- files: torrent.num_files,
- status: torrent.message,
- tracker: torrent.tracker_host,
- comment: torrent.comment,
- creator: torrent.creator,
- };
-
- for (var field in this.fields) {
- if (!Ext.isDefined(data[field])) continue; // This is a field we are not responsible for.
- if (data[field] == this.oldData[field]) continue;
- this.fields[field].dom.innerHTML = Ext.util.Format.htmlEncode(
- data[field]
- );
- }
- this.oldData = data;
- },
-});
-/**
- * Deluge.details.FilesTab.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
- title: _('Files'),
-
- rootVisible: false,
-
- columns: [
- {
- header: _('Filename'),
- width: 330,
- dataIndex: 'filename',
- tpl: new Ext.XTemplate('{filename:htmlEncode}'),
- },
- {
- 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(),
-
- 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);
- });
- },
-
- 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,
- });
- },
-
- 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 = {};
- var walk = function (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()) {
- var setPriorities = function (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_options(
- [this.torrentId],
- { file_priorities: 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.details.OptionsTab.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-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);
- },
-
- 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,
- move_completed_path: '',
- private: false,
- prioritize_first_last: false,
- super_seeding: false,
- },
- });
-
- /*
- * Bandwidth Options
- */
- this.fieldsets.bandwidth = this.add({
- xtype: 'fieldset',
- defaultType: 'spinnerfield',
- bodyStyle: 'padding: 5px',
-
- layout: 'table',
- layoutConfig: { columns: 3 },
- labelWidth: 150,
-
- 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 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 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,
-
- layout: 'table',
- layoutConfig: { columns: 2 },
- labelWidth: 0,
-
- 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.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.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,
- 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',
- width: 180,
- disabled: true,
- });
-
- /*
- * 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.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.super_seeding = this.fieldsets.general.add({
- fieldLabel: '',
- labelSeparator: '',
- boxLabel: _('Super Seeding'),
- id: 'super_seeding',
- });
-
- // 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,
- });
-
- /*
- * 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,
- });
- },
-
- 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();
- },
-
- clear: function () {
- if (this.torrentId == null) return;
- this.torrentId = null;
- this.optionsManager.changeId(null);
- },
-
- 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
-
- if (!torrentId) return; // We do not 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,
- });
- },
-
- onApply: function () {
- var changed = this.optionsManager.getDirty();
- deluge.client.core.set_torrent_options([this.torrentId], changed, {
- success: function () {
- this.optionsManager.commit();
- },
- scope: this,
- });
- },
-
- onEditTrackers: function () {
- deluge.editTrackers.show();
- },
-
- onMoveCompletedChecked: function (checkbox, checked) {
- this.fields.move_completed_path.setDisabled(!checked);
-
- if (!checked) return;
- this.fields.move_completed_path.focus();
- },
-
- 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'];
- torrent['prioritize_first_last_pieces'] =
- torrent['prioritize_first_last'];
- 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')
- );
- },
-});
-/**
- * Deluge.details.PeersTab.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-(function () {
- function flagRenderer(value) {
- if (!value.replace(' ', '').replace(' ', '')) {
- return '';
- }
- return String.format(
- '<img alt="{1}" title="{1}" src="{0}flag/{1}" />',
- deluge.config.base,
- value
- );
- }
- function peerAddressRenderer(value, p, record) {
- var seed =
- record.data['seed'] == 1024 ? 'x-deluge-seed' : 'x-deluge-peer';
- // Modify display of IPv6 to include brackets
- var peer_ip = value.split(':');
- if (peer_ip.length > 2) {
- var port = peer_ip.pop();
- var ip = peer_ip.join(':');
- value = '[' + ip + ']:' + port;
- }
- 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, {
- // 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: 'htmlEncode',
- 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 = {};
- },
-
- 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;
-
- 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]) {
- var record = store.getById(peer.ip);
- record.beginEdit();
- for (var k in peer) {
- if (record.get(k) != peer[k]) {
- record.set(k, peer[k]);
- }
- }
- 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);
-
- // Remove any peers that should not 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);
- },
- });
-})();
-/**
- * Deluge.details.StatusTab.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge.details');
-
-/**
- * @class Deluge.details.StatusTab
- * @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) {
- seeds =
- 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;
- last_seen_complete =
- status.last_seen_complete > 0.0
- ? fdate(status.last_seen_complete)
- : 'Never';
- completed_time =
- status.completed_time > 0.0 ? fdate(status.completed_time) : '';
-
- 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: status.eta < 0 ? '&infin;' : ftime(status.eta),
- pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')',
- seeds: seeds,
- 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),
- last_seen_complete: last_seen_complete,
- completed_time: completed_time,
- time_since_transfer: ftime(status.time_since_transfer),
- };
- data.auto_managed = _(status.is_auto_managed ? 'True' : 'False');
-
- var translate_tracker_status = {
- Error: _('Error'),
- Warning: _('Warning'),
- 'Announce OK': _('Announce OK'),
- 'Announce Sent': _('Announce Sent'),
- };
- for (var key in translate_tracker_status) {
- if (data.tracker_status.indexOf(key) != -1) {
- data.tracker_status = data.tracker_status.replace(
- key,
- translate_tracker_status[key]
- );
- break;
- }
- }
-
- data.downloaded +=
- ' (' +
- (status.total_payload_download
- ? fsize(status.total_payload_download)
- : '0.0 KiB') +
- ')';
- data.uploaded +=
- ' (' +
- (status.total_payload_upload
- ? fsize(status.total_payload_upload)
- : '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);
- },
-});
-/**
- * Deluge.preferences.BandwidthPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Bandwidth
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Bandwidth = Ext.extend(Ext.form.FormPanel, {
- constructor: function (config) {
- config = Ext.apply(
- {
- border: false,
- title: _('Bandwidth'),
- header: false,
- 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:'),
- labelSeparator: '',
- width: 80,
- value: -1,
- decimalPrecision: 0,
- })
- );
- om.bind(
- 'max_upload_slots_global',
- fieldset.add({
- name: 'max_upload_slots_global',
- fieldLabel: _('Maximum Upload Slots'),
- labelSeparator: '',
- width: 80,
- value: -1,
- decimalPrecision: 0,
- })
- );
- om.bind(
- 'max_download_speed',
- fieldset.add({
- name: 'max_download_speed',
- fieldLabel: _('Maximum Download Speed (KiB/s):'),
- labelSeparator: '',
- width: 80,
- value: -1.0,
- decimalPrecision: 1,
- })
- );
- om.bind(
- 'max_upload_speed',
- fieldset.add({
- name: 'max_upload_speed',
- fieldLabel: _('Maximum Upload Speed (KiB/s):'),
- labelSeparator: '',
- 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:'),
- labelSeparator: '',
- 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:'),
- labelSeparator: '',
- 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:'),
- labelSeparator: '',
- 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:'),
- labelSeparator: '',
- 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):'),
- labelSeparator: '',
- 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):'),
- labelSeparator: '',
- width: 80,
- value: -1,
- decimalPrecision: 0,
- })
- );
- },
-});
-/**
- * Deluge.preferences.CachePage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Cache
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Cache = Ext.extend(Ext.form.FormPanel, {
- border: false,
- title: _('Cache'),
- header: false,
- 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: 999999,
- },
- });
- om.bind(
- 'cache_size',
- fieldset.add({
- fieldLabel: _('Cache Size (16 KiB Blocks):'),
- labelSeparator: '',
- name: 'cache_size',
- width: 60,
- value: 512,
- })
- );
- om.bind(
- 'cache_expiry',
- fieldset.add({
- fieldLabel: _('Cache Expiry (seconds):'),
- labelSeparator: '',
- name: 'cache_expiry',
- width: 60,
- value: 60,
- })
- );
- },
-});
-/**
- * Deluge.preferences.DaemonPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Daemon
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Daemon = Ext.extend(Ext.form.FormPanel, {
- border: false,
- title: _('Daemon'),
- header: false,
- 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:'),
- labelSeparator: '',
- 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',
- })
- );
- },
-});
-/**
- * Deluge.preferences.DownloadsPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Downloads
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Downloads = Ext.extend(Ext.FormPanel, {
- constructor: function (config) {
- config = Ext.apply(
- {
- border: false,
- title: _('Downloads'),
- header: false,
- layout: 'form',
- autoHeight: true,
- width: 320,
- },
- config
- );
- Deluge.preferences.Downloads.superclass.constructor.call(this, config);
- },
-
- 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;',
- });
-
- optMan.bind(
- 'download_location',
- fieldset.add({
- xtype: 'textfield',
- name: 'download_location',
- fieldLabel: _('Download to:'),
- labelSeparator: '',
- width: 280,
- })
- );
-
- var field = fieldset.add({
- name: 'move_completed_path',
- fieldLabel: _('Move completed to:'),
- labelSeparator: '',
- 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:'),
- labelSeparator: '',
- width: 280,
- });
- optMan.bind('copy_torrent_file', field.toggle);
- optMan.bind('torrentfiles_location', field.input);
-
- 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(
- 'sequential_download',
- fieldset.add({
- name: 'sequential_download',
- labelSeparator: '',
- height: 22,
- boxLabel: _('Sequential download'),
- })
- );
- optMan.bind(
- 'add_paused',
- fieldset.add({
- name: 'add_paused',
- labelSeparator: '',
- height: 22,
- boxLabel: _('Add torrents in Paused state'),
- })
- );
- optMan.bind(
- 'pre_allocate_storage',
- fieldset.add({
- name: 'pre_allocate_storage',
- labelSeparator: '',
- height: 22,
- boxLabel: _('Pre-allocate disk space'),
- })
- );
- },
-});
-/**
- * Deluge.preferences.EncryptionPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Encryption
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Encryption = Ext.extend(Ext.form.FormPanel, {
- border: false,
- title: _('Encryption'),
- header: false,
-
- initComponent: function () {
- Deluge.preferences.Encryption.superclass.initComponent.call(this);
-
- var optMan = deluge.preferences.getOptionsManager();
-
- var fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Settings'),
- header: false,
- autoHeight: true,
- defaultType: 'combo',
- width: 300,
- });
- optMan.bind(
- 'enc_in_policy',
- fieldset.add({
- fieldLabel: _('Incoming:'),
- labelSeparator: '',
- 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: _('Outgoing:'),
- labelSeparator: '',
- 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:'),
- labelSeparator: '',
- 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',
- })
- );
- },
-});
-/**
- * Deluge.preferences.InstallPluginWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.InstallPluginWindow
- * @extends Ext.Window
- */
-Deluge.preferences.InstallPluginWindow = Ext.extend(Ext.Window, {
- title: _('Install Plugin'),
- layout: 'fit',
- height: 115,
- width: 350,
- constrainHeader: true,
- bodyStyle: 'padding: 10px 5px;',
- buttonAlign: 'center',
- closeAction: 'hide',
- iconCls: 'x-deluge-install-plugin',
- modal: true,
- plain: true,
-
- initComponent: function () {
- Deluge.preferences.InstallPluginWindow.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: deluge.config.base + 'upload',
- waitMsg: _('Uploading your plugin...'),
- success: this.onUploadSuccess,
- scope: this,
- });
- },
-
- 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,
- });
- }
- },
-});
-/**
- * Deluge.preferences.InterfacePage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Interface
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Interface = Ext.extend(Ext.form.FormPanel, {
- border: false,
- title: _('Interface'),
- header: false,
- 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',
- defaults: {
- height: 17,
- fieldLabel: '',
- labelSeparator: '',
- },
- });
- om.bind(
- 'show_session_speed',
- fieldset.add({
- name: 'show_session_speed',
- boxLabel: _('Show session speed in titlebar'),
- })
- );
- om.bind(
- 'sidebar_show_zero',
- fieldset.add({
- name: 'sidebar_show_zero',
- boxLabel: _('Show filters with zero torrents'),
- })
- );
- om.bind(
- 'sidebar_multiple_filters',
- fieldset.add({
- name: 'sidebar_multiple_filters',
- boxLabel: _('Allow the use of multiple filters at once'),
- })
- );
-
- var languagePanel = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Language'),
- style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
- autoHeight: true,
- labelWidth: 1,
- defaultType: 'checkbox',
- });
- this.language = om.bind(
- 'language',
- languagePanel.add({
- xtype: 'combo',
- labelSeparator: '',
- name: 'language',
- mode: 'local',
- width: 200,
- store: new Ext.data.ArrayStore({
- fields: ['id', 'text'],
- }),
- editable: false,
- triggerAction: 'all',
- valueField: 'id',
- displayField: 'text',
- })
- );
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('WebUI Password'),
- style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
- autoHeight: true,
- labelWidth: 100,
- defaultType: 'textfield',
- defaults: {
- width: 100,
- inputType: 'password',
- labelStyle: 'padding-left: 5px',
- height: 20,
- labelSeparator: '',
- },
- });
-
- this.oldPassword = fieldset.add({
- name: 'old_password',
- fieldLabel: _('Old:'),
- });
- this.newPassword = fieldset.add({
- name: 'new_password',
- fieldLabel: _('New:'),
- });
- this.confirmPassword = fieldset.add({
- name: 'confirm_password',
- fieldLabel: _('Confirm:'),
- });
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Server'),
- style: 'padding-top: 5px; margin-bottom: 0px; padding-bottom: 5px',
- autoHeight: true,
- labelWidth: 100,
- defaultType: 'spinnerfield',
- defaults: {
- labelSeparator: '',
- labelStyle: 'padding-left: 5px',
- height: 20,
- 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: 65535,
- })
- );
- this.httpsField = om.bind(
- 'https',
- fieldset.add({
- xtype: 'checkbox',
- name: 'https',
- hideLabel: true,
- width: 300,
- style: 'margin-left: 5px',
- boxLabel: _(
- 'Enable 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);
- }
- if ('language' in changed) {
- Ext.Msg.show({
- title: _('WebUI Language Changed'),
- msg: _(
- 'Do you want to refresh the page now to use the new language?'
- ),
- buttons: {
- yes: _('Refresh'),
- no: _('Close'),
- },
- multiline: false,
- fn: function (btnText) {
- if (btnText === 'yes') location.reload();
- },
- icon: Ext.MessageBox.QUESTION,
- });
- }
- }
- if (this.oldPassword.getValue() || this.newPassword.getValue()) {
- this.onPasswordChange();
- }
- },
-
- onOk: function () {
- this.onApply();
- },
-
- onGotConfig: function (config) {
- this.optionsManager.set(config);
- },
-
- onGotLanguages: function (info, obj, response, request) {
- info.unshift(['', _('System Default')]);
- this.language.store.loadData(info);
- this.language.setValue(this.optionsManager.get('language'));
- },
-
- 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,
- });
- deluge.client.webutils.get_languages({
- success: this.onGotLanguages,
- scope: this,
- });
- },
-
- onSSLCheck: function (e, checked) {
- this.pkeyField.setDisabled(!checked);
- this.certField.setDisabled(!checked);
- },
-});
-/**
- * Deluge.preferences.NetworkPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-// custom Vtype for vtype:'IPAddress'
-Ext.apply(Ext.form.VTypes, {
- IPAddress: function (v) {
- return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(v);
- },
- IPAddressText: 'Must be a numeric IP address',
- IPAddressMask: /[\d\.]/i,
-});
-
-/**
- * @class Deluge.preferences.Network
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
- border: false,
- layout: 'form',
- title: _('Network'),
- header: false,
-
- initComponent: function () {
- Deluge.preferences.Network.superclass.initComponent.call(this);
- var optMan = deluge.preferences.getOptionsManager();
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Incoming Address'),
- 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,
- vtype: 'IPAddress',
- })
- );
-
- var fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Incoming Port'),
- style: 'margin-bottom: 5px; padding-bottom: 0px;',
- autoHeight: true,
- labelWidth: 1,
- defaultType: 'checkbox',
- });
- optMan.bind(
- 'random_port',
- fieldset.add({
- fieldLabel: '',
- labelSeparator: '',
- boxLabel: _('Use Random Port'),
- name: 'random_port',
- height: 22,
- listeners: {
- check: {
- fn: function (e, checked) {
- this.listenPort.setDisabled(checked);
- },
- scope: this,
- },
- },
- })
- );
-
- this.listenPort = fieldset.add({
- xtype: 'spinnerfield',
- name: 'listen_port',
- fieldLabel: '',
- labelSeparator: '',
- width: 75,
- strategy: {
- xtype: 'number',
- decimalPrecision: 0,
- minValue: 0,
- maxValue: 65535,
- },
- });
- optMan.bind('listen_ports', this.listenPort);
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Outgoing Interface'),
- style: 'margin-bottom: 5px; padding-bottom: 0px;',
- autoHeight: true,
- labelWidth: 1,
- defaultType: 'textfield',
- });
- optMan.bind(
- 'outgoing_interface',
- fieldset.add({
- name: 'outgoing_interface',
- fieldLabel: '',
- labelSeparator: '',
- width: 40,
- })
- );
-
- 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:'),
- labelSeparator: '',
- strategy: {
- xtype: 'number',
- decimalPrecision: 0,
- minValue: 0,
- maxValue: 65535,
- },
- },
- {
- fieldLabel: _('To:'),
- labelSeparator: '',
- strategy: {
- xtype: 'number',
- decimalPrecision: 0,
- minValue: 0,
- maxValue: 65535,
- },
- },
- ],
- });
- optMan.bind('outgoing_ports', this.outgoingPorts);
-
- 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',
- })
- );
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Type Of Service'),
- 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:'),
- labelSeparator: '',
- width: 40,
- })
- );
- },
-});
-/**
- * Deluge.preferences.OtherPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Other
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Other = Ext.extend(Ext.form.FormPanel, {
- constructor: function (config) {
- config = Ext.apply(
- {
- border: false,
- title: _('Other'),
- header: false,
- 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: _('Path:'),
- labelSeparator: '',
- width: 200,
- })
- );
- },
-});
-/**
- * Deluge.preferences.PluginsPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Plugins
- * @extends Ext.Panel
- */
-Deluge.preferences.Plugins = Ext.extend(Ext.Panel, {
- layout: 'border',
- title: _('Plugins'),
- header: false,
- border: false,
- 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 style="white-space:normal">{details}</dd>' +
- '</dl>'
- ),
-
- 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>'
- );
- };
-
- this.list = this.add({
- xtype: 'listview',
- store: new Ext.data.ArrayStore({
- fields: [
- { name: 'enabled', mapping: 0 },
- { name: 'plugin', mapping: 1, sortType: 'asUCString' },
- ],
- }),
- columns: [
- {
- id: 'enabled',
- header: _('Enabled'),
- width: 0.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: 0.8,
- sortable: true,
- dataIndex: 'plugin',
- },
- ],
- singleSelect: true,
- autoExpandColumn: 'plugin',
- listeners: {
- selectionchange: { fn: this.onPluginSelect, scope: this },
- },
- });
-
- this.panel = this.add({
- region: 'center',
- autoScroll: true,
- 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: false,
- height: 100,
- region: 'south',
- padding: '5',
- autoScroll: true,
- bodyCfg: {
- style: 'white-space: nowrap',
- },
- }));
-
- 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);
- },
-
- 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);
- },
-
- updatePlugins: function () {
- var onGotAvailablePlugins = function (plugins) {
- this.availablePlugins = plugins.sort(function (a, b) {
- return a.toLowerCase().localeCompare(b.toLowerCase());
- });
-
- deluge.client.core.get_enabled_plugins({
- success: onGotEnabledPlugins,
- scope: this,
- });
- };
-
- var onGotEnabledPlugins = function (plugins) {
- this.enabledPlugins = plugins;
- this.onGotPlugins();
- };
-
- deluge.client.core.get_available_plugins({
- success: onGotAvailablePlugins,
- 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);
- },
-
- 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);
- if (r.get('plugin') == 'WebUi') return;
- 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');
- },
-
- onGotPlugins: function () {
- 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;
- },
-
- 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();
- },
-
- 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();
- },
-
- 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,
- });
- },
-
- onPreferencesShow: function () {
- this.updatePlugins();
- },
-
- onPluginInfoRender: function (ct, position) {
- this.setInfo();
- },
-});
-/**
- * Deluge.preferences.PreferencesWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-PreferencesRecord = Ext.data.Record.create([{ name: 'name', type: 'string' }]);
-
-/**
- * @class Deluge.preferences.PreferencesWindow
- * @extends Ext.Window
- */
-Deluge.preferences.PreferencesWindow = Ext.extend(Ext.Window, {
- /**
- * @property {String} currentPage The currently selected page.
- */
- currentPage: null,
-
- title: _('Preferences'),
- layout: 'border',
- width: 485,
- height: 500,
- border: false,
- constrainHeader: true,
- buttonAlign: 'right',
- closeAction: 'hide',
- closable: true,
- iconCls: 'x-deluge-preferences',
- plain: true,
- resizable: false,
-
- pages: {},
-
- initComponent: function () {
- Deluge.preferences.PreferencesWindow.superclass.initComponent.call(
- this
- );
-
- this.list = new Ext.list.ListView({
- store: new Ext.data.Store(),
- columns: [
- {
- id: 'name',
- 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',
- items: [this.list],
- width: 120,
- margins: '0 5 0 0',
- cmargins: '0 5 0 0',
- });
-
- this.configPanel = this.add({
- type: 'container',
- autoDestroy: false,
- region: 'center',
- layout: 'card',
- layoutConfig: {
- deferredRender: true,
- },
- autoScroll: true,
- width: 300,
- });
-
- 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();
- },
-
- 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)) {
- // Workaround for only displaying single listen port but still pass array to core.
- if ('listen_ports' in changed) {
- changed.listen_ports = [
- changed.listen_ports,
- changed.listen_ports,
- ];
- }
- 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);
- },
-
- // 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
- onClose: function () {
- this.hide();
- },
-
- // private
- onOk: function () {
- 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].onOk) this.pages[page].onOk();
- }
-
- this.hide();
- },
-});
-/**
- * Deluge.preferences.ProxyField.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.ProxyField
- * @extends Ext.form.FieldSet
- */
-Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
- border: false,
- autoHeight: true,
- labelWidth: 70,
-
- initComponent: function () {
- Deluge.preferences.ProxyField.superclass.initComponent.call(this);
- this.proxyType = this.add({
- xtype: 'combo',
- fieldLabel: _('Type:'),
- labelSeparator: '',
- name: 'proxytype',
- mode: 'local',
- width: 150,
- store: new Ext.data.ArrayStore({
- fields: ['id', 'text'],
- data: [
- [0, _('None')],
- [1, _('Socks4')],
- [2, _('Socks5')],
- [3, _('Socks5 Auth')],
- [4, _('HTTP')],
- [5, _('HTTP Auth')],
- [6, _('I2P')],
- ],
- }),
- editable: false,
- triggerAction: 'all',
- valueField: 'id',
- displayField: 'text',
- });
- this.proxyType.on('change', this.onFieldChange, this);
- this.proxyType.on('select', this.onTypeSelect, this);
-
- this.hostname = this.add({
- xtype: 'textfield',
- name: 'hostname',
- fieldLabel: _('Host:'),
- labelSeparator: '',
- width: 220,
- });
- this.hostname.on('change', this.onFieldChange, this);
-
- this.port = this.add({
- xtype: 'spinnerfield',
- name: 'port',
- fieldLabel: _('Port:'),
- labelSeparator: '',
- width: 80,
- decimalPrecision: 0,
- minValue: 0,
- maxValue: 65535,
- });
- this.port.on('change', this.onFieldChange, this);
-
- this.username = this.add({
- xtype: 'textfield',
- name: 'username',
- fieldLabel: _('Username:'),
- labelSeparator: '',
- width: 220,
- });
- this.username.on('change', this.onFieldChange, this);
-
- this.password = this.add({
- xtype: 'textfield',
- name: 'password',
- fieldLabel: _('Password:'),
- labelSeparator: '',
- inputType: 'password',
- width: 220,
- });
- this.password.on('change', this.onFieldChange, this);
-
- this.proxy_host_resolve = this.add({
- xtype: 'checkbox',
- name: 'proxy_host_resolve',
- fieldLabel: '',
- boxLabel: _('Proxy Hostnames'),
- width: 220,
- });
- this.proxy_host_resolve.on('change', this.onFieldChange, this);
-
- this.proxy_peer_conn = this.add({
- xtype: 'checkbox',
- name: 'proxy_peer_conn',
- fieldLabel: '',
- boxLabel: _('Proxy Peers'),
- width: 220,
- });
- this.proxy_peer_conn.on('change', this.onFieldChange, this);
-
- this.proxy_tracker_conn = this.add({
- xtype: 'checkbox',
- name: 'proxy_tracker_conn',
- fieldLabel: '',
- boxLabel: _('Proxy Trackers'),
- width: 220,
- });
- this.proxy_tracker_conn.on('change', this.onFieldChange, this);
-
- var fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Force Proxy'),
- autoHeight: true,
- labelWidth: 1,
- defaultType: 'checkbox',
- style: 'padding-left: 0px; margin-top: 10px',
- });
-
- this.force_proxy = fieldset.add({
- fieldLabel: '',
- labelSeparator: '',
- height: 20,
- name: 'force_proxy',
- boxLabel: _('Force Use of Proxy'),
- });
- this.force_proxy.on('change', this.onFieldChange, this);
-
- this.anonymous_mode = fieldset.add({
- fieldLabel: '',
- labelSeparator: '',
- height: 20,
- name: 'anonymous_mode',
- boxLabel: _('Hide Client Identity'),
- });
- this.anonymous_mode.on('change', this.onFieldChange, this);
-
- this.setting = false;
- },
-
- 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(),
- proxy_hostnames: this.proxy_host_resolve.getValue(),
- proxy_peer_connections: this.proxy_peer_conn.getValue(),
- proxy_tracker_connections: this.proxy_tracker_conn.getValue(),
- force_proxy: this.force_proxy.getValue(),
- anonymous_mode: this.anonymous_mode.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);
-
- this.hostname.setValue(value['hostname']);
- this.port.setValue(value['port']);
- this.username.setValue(value['username']);
- this.password.setValue(value['password']);
- this.proxy_host_resolve.setValue(value['proxy_hostnames']);
- this.proxy_peer_conn.setValue(value['proxy_peer_connections']);
- this.proxy_tracker_conn.setValue(value['proxy_tracker_connections']);
- this.force_proxy.setValue(value['force_proxy']);
- this.anonymous_mode.setValue(value['anonymous_mode']);
-
- 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;
-
- 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();
- this.proxy_peer_conn.show();
- this.proxy_tracker_conn.show();
- if (typeId > 1 && typeId < 6) {
- this.proxy_host_resolve.show();
- } else {
- this.proxy_host_resolve.hide();
- }
- } else {
- this.hostname.hide();
- this.port.hide();
- this.proxy_host_resolve.hide();
- this.proxy_peer_conn.hide();
- this.proxy_tracker_conn.hide();
- }
-
- if (typeId == 3 || typeId == 5) {
- this.username.show();
- this.password.show();
- } else {
- this.username.hide();
- this.password.hide();
- }
- },
-});
-/**
- * Deluge.preferences.ProxyPage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Proxy
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
- constructor: function (config) {
- config = Ext.apply(
- {
- border: false,
- title: _('Proxy'),
- header: false,
- layout: 'form',
- autoScroll: true,
- },
- config
- );
- Deluge.preferences.Proxy.superclass.constructor.call(this, config);
- },
-
- initComponent: function () {
- Deluge.preferences.Proxy.superclass.initComponent.call(this);
- this.proxy = this.add(
- new Deluge.preferences.ProxyField({
- title: _('Proxy'),
- name: 'proxy',
- })
- );
- this.proxy.on('change', this.onProxyChange, this);
- deluge.preferences.getOptionsManager().bind('proxy', this.proxy);
- },
-
- getValue: function () {
- return {
- proxy: this.proxy.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);
- },
-});
-/**
- * Deluge.preferences.QueuePage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge.preferences');
-
-/**
- * @class Deluge.preferences.Queue
- * @extends Ext.form.FormPanel
- */
-Deluge.preferences.Queue = Ext.extend(Ext.form.FormPanel, {
- border: false,
- title: _('Queue'),
- header: false,
- 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: _('New Torrents'),
- style: 'padding-top: 5px; margin-bottom: 0px;',
- autoHeight: true,
- labelWidth: 1,
- defaultType: 'checkbox',
- });
- om.bind(
- 'queue_new_to_top',
- fieldset.add({
- fieldLabel: '',
- labelSeparator: '',
- height: 22,
- boxLabel: _('Queue to top'),
- name: 'queue_new_to_top',
- })
- );
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Active Torrents'),
- autoHeight: true,
- labelWidth: 150,
- defaultType: 'spinnerfield',
- style: 'padding-top: 5px; margin-bottom: 0px',
- });
- om.bind(
- 'max_active_limit',
- fieldset.add({
- fieldLabel: _('Total:'),
- labelSeparator: '',
- name: 'max_active_limit',
- value: 8,
- width: 80,
- decimalPrecision: 0,
- minValue: -1,
- maxValue: 99999,
- })
- );
- om.bind(
- 'max_active_downloading',
- fieldset.add({
- fieldLabel: _('Downloading:'),
- labelSeparator: '',
- name: 'max_active_downloading',
- value: 3,
- width: 80,
- decimalPrecision: 0,
- minValue: -1,
- maxValue: 99999,
- })
- );
- om.bind(
- 'max_active_seeding',
- fieldset.add({
- fieldLabel: _('Seeding:'),
- labelSeparator: '',
- 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: 22,
- hideLabel: true,
- boxLabel: _('Ignore slow torrents'),
- })
- );
- om.bind(
- 'auto_manage_prefer_seeds',
- fieldset.add({
- xtype: 'checkbox',
- name: 'auto_manage_prefer_seeds',
- hideLabel: true,
- boxLabel: _('Prefer seeding torrents'),
- })
- );
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- title: _('Seeding Rotation'),
- autoHeight: true,
- labelWidth: 150,
- defaultType: 'spinnerfield',
- style: 'padding-top: 5px; margin-bottom: 0px',
- });
- om.bind(
- 'share_ratio_limit',
- fieldset.add({
- fieldLabel: _('Share Ratio:'),
- labelSeparator: '',
- 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: _('Time Ratio:'),
- labelSeparator: '',
- 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: _('Time (m):'),
- labelSeparator: '',
- name: 'seed_time_limit',
- value: 5,
- width: 80,
- decimalPrecision: 0,
- minValue: -1,
- maxValue: 99999,
- })
- );
-
- fieldset = this.add({
- xtype: 'fieldset',
- border: false,
- autoHeight: true,
- style: 'padding-top: 5px; margin-bottom: 0px',
- title: _('Share Ratio Reached'),
-
- layout: 'table',
- layoutConfig: { columns: 2 },
- labelWidth: 0,
- defaultType: 'checkbox',
-
- defaults: {
- fieldLabel: '',
- labelSeparator: '',
- },
- });
- this.stopAtRatio = fieldset.add({
- name: 'stop_seed_at_ratio',
- boxLabel: _('Share Ratio:'),
- });
- 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({
- xtype: 'radiogroup',
- columns: 1,
- colspan: 2,
- disabled: true,
- style: 'margin-left: 10px',
- items: [
- {
- boxLabel: _('Pause torrent'),
- name: 'at_ratio',
- inputValue: false,
- checked: true,
- },
- {
- boxLabel: _('Remove torrent'),
- name: 'at_ratio',
- inputValue: true,
- },
- ],
- });
- om.bind('remove_seed_at_ratio', this.removeAtRatio);
- },
-
- onStopRatioCheck: function (e, checked) {
- this.stopRatio.setDisabled(!checked);
- this.removeAtRatio.setDisabled(!checked);
- },
-});
-/**
- * Deluge.StatusbarMenu.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * Menu that handles setting the statusbar limits correctly.
- * @class Deluge.StatusbarMenu
- * @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 || {}
- );
-
- 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;
- // set the new value
- this.value = value = value == 0 ? -1 : value;
-
- var other = null;
- // uncheck all items
- this.items.each(function (item) {
- if (item.setChecked) {
- item.suspendEvents();
- if (item.value == value) {
- item.setChecked(true);
- beenSet = true;
- } else {
- item.setChecked(false);
- }
- item.resumeEvents();
- }
-
- if (item.value == 'other') other = item;
- });
-
- if (beenSet) return;
-
- other.suspendEvents();
- other.setChecked(true);
- other.resumeEvents();
- },
-
- onLimitChanged: function (item, checked) {
- if (!checked || item.value == 'other') return; // We do not care about unchecked 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();
- },
-});
-/**
- * Deluge.OptionsManager.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Deluge');
-
-/**
- * @class Deluge.OptionsManager
- * @extends Ext.util.Observable
- * A class that can be used to manage options throughout the ui.
- * @constructor
- * Creates a new OptionsManager
- * @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;
-
- 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 reset
- * Fires when the options are reset
- */
- reset: true,
- });
- this.on('changed', this.onChange, 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;
-
- 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();
- },
-
- /**
- * 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 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;
- },
-
- /**
- * @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];
- },
-
- /**
- * 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);
- }
- },
-
- /**
- * 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;
-
- 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);
- }
- },
-
- /**
- * 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());
- },
-
- /**
- * Lets the option manager know when a field is focused so if a value changing
- * operation is performed it will not 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 do not want to change it.
- if (bind == this.focused) return;
- // Set the form field to the new value.
- bind.setValue(newValue);
- },
- this
- );
- },
-});
-/**
- * Deluge.AboutWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Ext.namespace('Deluge.about');
-
-/**
- * @class Deluge.about.AboutWindow
- * @extends Ext.Window
- */
-Deluge.about.AboutWindow = Ext.extend(Ext.Window, {
- id: 'AboutWindow',
- title: _('About Deluge'),
- height: 330,
- width: 270,
- iconCls: 'x-deluge-main-panel',
- resizable: false,
- plain: true,
- layout: {
- type: 'vbox',
- align: 'center',
- },
- buttonAlign: 'center',
-
- initComponent: function () {
- Deluge.about.AboutWindow.superclass.initComponent.call(this);
- this.addEvents({
- build_ready: true,
- });
-
- var self = this;
- var libtorrent = function () {
- deluge.client.core.get_libtorrent_version({
- success: function (lt_version) {
- comment += '<br/>' + _('libtorrent:') + ' ' + lt_version;
- Ext.getCmp('about_comment').setText(comment, false);
- self.fireEvent('build_ready');
- },
- });
- };
-
- var client_version = deluge.version;
-
- var comment =
- _(
- 'A peer-to-peer file sharing program\nutilizing the BitTorrent protocol.'
- ).replace('\n', '<br/>') +
- '<br/><br/>' +
- _('Client:') +
- ' ' +
- client_version +
- '<br/>';
- deluge.client.web.connected({
- success: function (connected) {
- if (connected) {
- deluge.client.daemon.get_version({
- success: function (server_version) {
- comment +=
- _('Server:') + ' ' + server_version + '<br/>';
- libtorrent();
- },
- });
- } else {
- this.fireEvent('build_ready');
- }
- },
- failure: function () {
- this.fireEvent('build_ready');
- },
- scope: this,
- });
-
- this.add([
- {
- xtype: 'box',
- style: 'padding-top: 5px',
- height: 80,
- width: 240,
- cls: 'x-deluge-logo',
- hideLabel: true,
- },
- {
- xtype: 'label',
- style: 'padding-top: 10px; font-weight: bold; font-size: 16px;',
- text: _('Deluge') + ' ' + client_version,
- },
- {
- xtype: 'label',
- id: 'about_comment',
- style: 'padding-top: 10px; text-align:center; font-size: 12px;',
- html: comment,
- },
- {
- xtype: 'label',
- style: 'padding-top: 10px; font-size: 10px;',
- text: _('Copyright 2007-2018 Deluge Team'),
- },
- {
- xtype: 'label',
- style: 'padding-top: 5px; font-size: 12px;',
- html: '<a href="https://deluge-torrent.org" target="_blank">deluge-torrent.org</a>',
- },
- ]);
- this.addButton(_('Close'), this.onCloseClick, this);
- },
-
- show: function () {
- this.on('build_ready', function () {
- Deluge.about.AboutWindow.superclass.show.call(this);
- });
- },
-
- onCloseClick: function () {
- this.close();
- },
-});
-
-Ext.namespace('Deluge');
-
-Deluge.About = function () {
- new Deluge.about.AboutWindow().show();
-};
-/**
- * Deluge.AddConnectionWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * @class Deluge.AddConnectionWindow
- * @extends Ext.Window
- */
-Deluge.AddConnectionWindow = Ext.extend(Ext.Window, {
- title: _('Add Connection'),
- iconCls: 'x-deluge-add-window-icon',
-
- layout: 'fit',
- width: 300,
- height: 195,
- constrainHeader: true,
- bodyStyle: 'padding: 10px 5px;',
- closeAction: 'hide',
-
- 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:'),
- labelSeparator: '',
- name: 'host',
- anchor: '75%',
- value: '',
- },
- {
- xtype: 'spinnerfield',
- fieldLabel: _('Port:'),
- labelSeparator: '',
- name: 'port',
- strategy: {
- xtype: 'number',
- decimalPrecision: 0,
- minValue: -1,
- maxValue: 65535,
- },
- value: '58846',
- anchor: '40%',
- },
- {
- fieldLabel: _('Username:'),
- labelSeparator: '',
- name: 'username',
- anchor: '75%',
- value: '',
- },
- {
- fieldLabel: _('Password:'),
- labelSeparator: '',
- anchor: '75%',
- name: 'password',
- inputType: 'password',
- value: '',
- },
- ],
- });
- },
-
- onAddClick: function () {
- var values = this.form.getForm().getValues();
- deluge.client.web.add_host(
- values.host,
- Number(values.port),
- values.username,
- values.password,
- {
- success: function (result) {
- if (!result[0]) {
- Ext.MessageBox.show({
- title: _('Error'),
- msg: String.format(
- _('Unable to add host: {0}'),
- 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();
- },
-});
-/**
- * Deluge.AddTrackerWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-// Custom VType validator for tracker urls
-var trackerUrlTest =
- /(((^https?)|(^udp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
-Ext.apply(Ext.form.VTypes, {
- trackerUrl: function (val, field) {
- return trackerUrlTest.test(val);
- },
- trackerUrlText: 'Not a valid tracker url',
-});
-
-/**
- * @class Deluge.AddTrackerWindow
- * @extends Ext.Window
- */
-Deluge.AddTrackerWindow = Ext.extend(Ext.Window, {
- title: _('Add Tracker'),
- layout: 'fit',
- width: 375,
- height: 150,
- plain: true,
- closable: true,
- resizable: false,
- constrainHeader: true,
- 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:'),
- labelSeparator: '',
- 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.trackerUrl(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();
- },
-});
-/**
- * Deluge.Client.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Ext.ux.util');
-
-/**
- * A class that connects to a json-rpc resource and adds the available
- * methods as functions to the class instance.
- * @class Ext.ux.util.RpcClient
- * @namespace Ext.ux.util
- */
-Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
- _components: [],
-
- _methods: [],
-
- _requests: {},
-
- _url: null,
-
- _optionKeys: ['scope', 'success', 'failure'],
-
- /**
- * @event connected
- * Fires when the client has retrieved the list of methods from the server.
- * @param {Ext.ux.util.RpcClient} this
- */
- constructor: function (config) {
- Ext.ux.util.RpcClient.superclass.constructor.call(this, config);
- this._url = config.url || null;
- this._id = 0;
-
- this.addEvents(
- // raw events
- 'connected',
- 'error'
- );
- this.reloadMethods();
- },
-
- reloadMethods: function () {
- 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;
- },
-
- _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];
- }
- Ext.each(
- this._components,
- function (component) {
- if (!component in components) {
- delete this[component];
- }
- },
- this
- );
- this._components = Ext.keys(components);
- this.fireEvent('connected', this);
- },
-});
-/**
- * Deluge.ConnectionManager.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Deluge.ConnectionManager = Ext.extend(Ext.Window, {
- layout: 'fit',
- width: 300,
- height: 220,
- bodyStyle: 'padding: 10px 5px;',
- buttonAlign: 'right',
- closeAction: 'hide',
- closable: true,
- plain: true,
- constrainHeader: 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);
-
- 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.list = new Ext.list.ListView({
- store: new Ext.data.ArrayStore({
- fields: [
- { name: 'status', mapping: 4 },
- { name: 'host', mapping: 1 },
- { name: 'port', mapping: 2 },
- { name: 'user', mapping: 3 },
- { name: 'version', mapping: 5 },
- ],
- id: 0,
- }),
- columns: [
- {
- header: _('Status'),
- width: 0.24,
- sortable: true,
- tpl: new Ext.XTemplate(
- '<tpl if="status == \'Online\'">',
- _('Online'),
- '</tpl>',
- '<tpl if="status == \'Offline\'">',
- _('Offline'),
- '</tpl>',
- '<tpl if="status == \'Connected\'">',
- _('Connected'),
- '</tpl>'
- ),
- dataIndex: 'status',
- },
- {
- id: 'host',
- header: _('Host'),
- width: 0.51,
- sortable: true,
- tpl: '{user}@{host}:{port}',
- dataIndex: 'host',
- },
- {
- header: _('Version'),
- width: 0.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-edit',
- cls: 'x-btn-text-icon',
- text: _('Edit'),
- iconCls: 'icon-edit',
- handler: this.onEditClick,
- 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,
- });
- },
-
- 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,
- });
- },
-
- 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');
-
- // Update the Connect/Disconnect button
- button.enable();
- if (status.toLowerCase() == 'connected') {
- button.setText(_('Disconnect'));
- } else {
- button.setText(_('Connect'));
- if (status.toLowerCase() != 'online') button.disable();
- }
-
- // Update the Stop/Start Daemon button
- if (
- status.toLowerCase() == 'connected' ||
- status.toLowerCase() == 'online'
- ) {
- this.stopHostButton.enable();
- this.stopHostButton.setText(_('Stop Daemon'));
- } else {
- if (
- record.get('host') == '127.0.0.1' ||
- record.get('host') == 'localhost'
- ) {
- this.stopHostButton.enable();
- this.stopHostButton.setText(_('Start Daemon'));
- } else {
- this.stopHostButton.disable();
- }
- }
- },
-
- // private
- onAddClick: function (button, e) {
- if (!this.addWindow) {
- this.addWindow = new Deluge.AddConnectionWindow();
- this.addWindow.on('hostadded', this.onHostChange, this);
- }
- this.addWindow.show();
- },
-
- // private
- onEditClick: function (button, e) {
- var connection = this.list.getSelectedRecords()[0];
- if (!connection) return;
-
- if (!this.editWindow) {
- this.editWindow = new Deluge.EditConnectionWindow();
- this.editWindow.on('hostedited', this.onHostChange, this);
- }
- this.editWindow.show(connection);
- },
-
- // private
- onHostChange: function () {
- this.loadHosts();
- },
-
- // private
- onClose: function (e) {
- this.hide();
- },
-
- // private
- onConnect: function (e) {
- var selected = this.list.getSelectedRecords()[0];
- if (!selected) return;
-
- var me = this;
- var disconnect = function () {
- deluge.client.web.disconnect({
- success: function (result) {
- this.update(this);
- deluge.events.fire('disconnect');
- },
- scope: me,
- });
- };
-
- if (selected.get('status').toLowerCase() == 'connected') {
- disconnect();
- } else {
- if (
- this.list
- .getStore()
- .find('status', 'Connected', 0, false, false) > -1
- ) {
- disconnect();
- }
-
- 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
- onGetHostStatus: function (host) {
- var record = this.list.getStore().getById(host[0]);
- record.set('status', host[1]);
- record.set('version', host[2]);
- record.commit();
- var selected = this.list.getSelectedRecords()[0];
- if (!selected) return;
- if (selected == record) this.updateButtons(record);
- },
-
- // private
- onHide: function () {
- if (this.running) window.clearInterval(this.running);
- },
-
- // private
- onLogin: function () {
- if (deluge.config.first_login) {
- Ext.MessageBox.confirm(
- _('Change Default Password'),
- _(
- 'We recommend changing the default password.<br><br>Would you like to change it 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
- 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,
- });
- },
-
- // private
- onSelectionChanged: function (list, selections) {
- if (selections[0]) {
- this.editHostButton.enable();
- this.removeHostButton.enable();
- this.stopHostButton.enable();
- this.stopHostButton.setText(_('Stop Daemon'));
- this.updateButtons(this.list.getRecord(selections[0]));
- } else {
- this.editHostButton.disable();
- 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.editHostButton = bbar.items.get('cm-edit');
- 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);
- },
-
- // 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',
- });
- }
- },
- });
- }
- },
-});
-/*
- * Deluge.CopyMagnet.js
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-Deluge.CopyMagnet = Ext.extend(Ext.Window, {
- title: _('Copy Magnet URI'),
- width: 375,
- closeAction: 'hide',
- iconCls: 'icon-magnet-copy',
-
- initComponent: function () {
- Deluge.CopyMagnet.superclass.initComponent.call(this);
- form = this.add({
- xtype: 'form',
- defaultType: 'textfield',
- hideLabels: true,
- });
- this.magnetURI = form.add({
- name: 'URI',
- anchor: '100%',
- });
- this.addButton(_('Close'), this.onClose, this);
- this.addButton(_('Copy'), this.onCopy, this);
- },
- show: function (a) {
- Deluge.CopyMagnet.superclass.show.call(this);
- var torrent = deluge.torrents.getSelected();
- deluge.client.core.get_magnet_uri(torrent.id, {
- success: this.onRequestComplete,
- scope: this,
- });
- },
- onRequestComplete: function (uri) {
- this.magnetURI.setValue(uri);
- },
- onCopy: function () {
- this.magnetURI.focus();
- this.magnetURI.el.dom.select();
- document.execCommand('copy');
- },
- onClose: function () {
- this.hide();
- },
-});
-
-deluge.copyMagnetWindow = new Deluge.CopyMagnet();
-/**
- * Deluge.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-// Setup the state manager
-Ext.state.Manager.setProvider(
- new Ext.state.CookieProvider({
- /**
- * By default, cookies will expire after 7 days. Provide
- * an expiry date 10 years in the future to approximate
- * a cookie that does not expire.
- */
- expires: new Date(
- new Date().getTime() + 1000 * 60 * 60 * 24 * 365 * 10
- ),
- })
-);
-
-// Add some additional functions to ext and setup some of the
-// configurable parameters
-Ext.apply(Ext, {
- 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;
- },
-
- 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';
-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>',
-
- /**
- * 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]();
- },
-
- /**
- * 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;
- },
-});
-
-// Setup a space for plugins to insert themselves
-deluge.plugins = {};
-
-// Hinting for gettext_gen.py
-// _('Skip')
-// _('Low')
-// _('Normal')
-// _('High')
-// _('Mixed')
-FILE_PRIORITY = {
- 0: 'Skip',
- 1: 'Low',
- 2: 'Low',
- 3: 'Low',
- 4: 'Normal',
- 5: 'High',
- 6: 'High',
- 7: 'High',
- 9: 'Mixed',
- Skip: 0,
- Low: 1,
- Normal: 4,
- High: 7,
- Mixed: 9,
-};
-
-FILE_PRIORITY_CSS = {
- 0: 'x-no-download',
- 1: 'x-low-download',
- 2: 'x-low-download',
- 3: 'x-low-download',
- 4: 'x-normal-download',
- 5: 'x-high-download',
- 6: 'x-high-download',
- 7: 'x-high-download',
- 9: 'x-mixed-download',
-};
-/**
- * Deluge.EditConnectionWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * @class Deluge.EditConnectionWindow
- * @extends Ext.Window
- */
-Deluge.EditConnectionWindow = Ext.extend(Ext.Window, {
- title: _('Edit Connection'),
- iconCls: 'x-deluge-add-window-icon',
-
- layout: 'fit',
- width: 300,
- height: 195,
- constrainHeader: true,
- bodyStyle: 'padding: 10px 5px;',
- closeAction: 'hide',
-
- initComponent: function () {
- Deluge.EditConnectionWindow.superclass.initComponent.call(this);
-
- this.addEvents('hostedited');
-
- this.addButton(_('Close'), this.hide, this);
- this.addButton(_('Edit'), this.onEditClick, this);
-
- this.on('hide', this.onHide, this);
-
- this.form = this.add({
- xtype: 'form',
- defaultType: 'textfield',
- baseCls: 'x-plain',
- labelWidth: 60,
- items: [
- {
- fieldLabel: _('Host:'),
- labelSeparator: '',
- name: 'host',
- anchor: '75%',
- value: '',
- },
- {
- xtype: 'spinnerfield',
- fieldLabel: _('Port:'),
- labelSeparator: '',
- name: 'port',
- strategy: {
- xtype: 'number',
- decimalPrecision: 0,
- minValue: 0,
- maxValue: 65535,
- },
- anchor: '40%',
- value: 58846,
- },
- {
- fieldLabel: _('Username:'),
- labelSeparator: '',
- name: 'username',
- anchor: '75%',
- value: '',
- },
- {
- fieldLabel: _('Password:'),
- labelSeparator: '',
- anchor: '75%',
- name: 'password',
- inputType: 'password',
- value: '',
- },
- ],
- });
- },
-
- show: function (connection) {
- Deluge.EditConnectionWindow.superclass.show.call(this);
-
- this.form.getForm().findField('host').setValue(connection.get('host'));
- this.form.getForm().findField('port').setValue(connection.get('port'));
- this.form
- .getForm()
- .findField('username')
- .setValue(connection.get('user'));
- this.host_id = connection.id;
- },
-
- onEditClick: function () {
- var values = this.form.getForm().getValues();
- deluge.client.web.edit_host(
- this.host_id,
- values.host,
- Number(values.port),
- values.username,
- values.password,
- {
- success: function (result) {
- if (!result) {
- console.log(result);
- Ext.MessageBox.show({
- title: _('Error'),
- msg: String.format(_('Unable to edit host')),
- buttons: Ext.MessageBox.OK,
- modal: false,
- icon: Ext.MessageBox.ERROR,
- iconCls: 'x-deluge-icon-error',
- });
- } else {
- this.fireEvent('hostedited');
- }
- this.hide();
- },
- scope: this,
- }
- );
- },
-
- onHide: function () {
- this.form.getForm().reset();
- },
-});
-/**
- * Deluge.EditTrackerWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * @class Deluge.EditTrackerWindow
- * @extends Ext.Window
- */
-Deluge.EditTrackerWindow = Ext.extend(Ext.Window, {
- title: _('Edit Tracker'),
- layout: 'fit',
- width: 375,
- height: 110,
- plain: true,
- closable: true,
- resizable: false,
- constrainHeader: true,
- 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:'),
- labelSeparator: '',
- 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();
- },
-});
-/**
- * Deluge.EditTrackers.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * @class Deluge.EditTrackersWindow
- * @extends Ext.Window
- */
-Deluge.EditTrackersWindow = Ext.extend(Ext.Window, {
- title: _('Edit Trackers'),
- layout: 'fit',
- width: 350,
- height: 220,
- plain: true,
- closable: true,
- resizable: true,
- constrainHeader: true,
-
- bodyStyle: 'padding: 5px',
- buttonAlign: 'right',
- closeAction: 'hide',
- iconCls: 'x-deluge-edit-trackers',
-
- initComponent: function () {
- Deluge.EditTrackersWindow.superclass.initComponent.call(this);
-
- 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.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: 0.1,
- dataIndex: 'tier',
- },
- {
- header: _('Tracker'),
- width: 0.9,
- dataIndex: 'url',
- tpl: new Ext.XTemplate('{url:htmlEncode}'),
- },
- ],
- columnSort: {
- sortClasses: ['', ''],
- },
- stripeRows: true,
- singleSelect: true,
- listeners: {
- dblclick: { fn: this.onListNodeDblClicked, scope: this },
- selectionchange: { fn: this.onSelect, scope: this },
- },
- });
-
- this.panel = this.add({
- 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();
- },
-
- 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();
- },
-
- onEditClick: function () {
- var selected = this.list.getSelectedRecords()[0];
- if (!selected) return;
- this.editWindow.show(selected);
- },
-
- onHide: function () {
- this.list.getStore().removeAll();
- },
-
- 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);
-
- deluge.client.core.set_torrent_trackers(this.torrentId, trackers, {
- failure: this.onSaveFail,
- scope: this,
- });
-
- this.hide();
- },
-
- onRemoveClick: function () {
- // Remove from the grid
- var selected = this.list.getSelectedRecords()[0];
- if (!selected) return;
- this.list.getStore().remove(selected);
- },
-
- onRequestComplete: function (status) {
- this.list.getStore().loadData(status);
- this.list.getStore().sort('tier', 'ASC');
- },
-
- onSaveFail: function () {},
-
- 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,
- });
- },
-
- onDownClick: function () {
- var r = this.list.getSelectedRecords()[0];
- if (!r) return;
-
- 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];
- if (!r) return;
-
- 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));
- },
-});
-/**
- * Deluge.EventsManager.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/**
- * @class Deluge.EventsManager
- * @extends Ext.util.Observable
- * <p>Deluge.EventsManager is instantated as <tt>deluge.events</tt> and can be used by components of the UI to fire global events</p>
- * 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
- );
- },
-
- 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();
- },
-
- /**
- * Stops the EventsManagerManager checking for events.
- */
- stop: function () {
- this.running = false;
- },
-
- // private
- onLogin: function () {
- this.start();
- },
-
- onGetEventsSuccess: function (events) {
- if (!this.running) return;
- if (events) {
- Ext.each(
- events,
- function (event) {
- var name = event[0],
- args = event[1];
- args.splice(0, 0, name);
- this.fireEvent.apply(this, args);
- },
- this
- );
- }
- 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();
- },
-});
-
-/**
- * Appends an event handler to this object (shorthand for {@link #addListener})
- * @method
- */
-Deluge.EventsManager.prototype.on = Deluge.EventsManager.prototype.addListener;
-
-/**
- * Fires the specified event with the passed parameters (minus the
- * event name).
- * @method
- */
-Deluge.EventsManager.prototype.fire = Deluge.EventsManager.prototype.fireEvent;
-deluge.events = new Deluge.EventsManager();
-/**
- * Deluge.FileBrowser.js
- *
- * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Ext.namespace('Deluge');
-Deluge.FileBrowser = Ext.extend(Ext.Window, {
- title: _('File Browser'),
-
- width: 500,
- height: 400,
-
- 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',
- },
- ],
- });
- },
-});
-/**
- * Deluge.FilterPanel.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * @class Deluge.FilterPanel
- * @extends Ext.list.ListView
- */
-Deluge.FilterPanel = Ext.extend(Ext.Panel, {
- autoScroll: true,
-
- border: false,
-
- show_zero: null,
-
- initComponent: function () {
- Deluge.FilterPanel.superclass.initComponent.call(this);
- this.filterType = this.initialConfig.filter;
- var title = '';
- if (this.filterType == 'state') {
- title = _('States');
- } else if (this.filterType == 'tracker_host') {
- title = _('Trackers');
- } else if (this.filterType == 'owner') {
- title = _('Owner');
- } else if (this.filterType == 'label') {
- title = _('Labels');
- } else {
- (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>';
- }
-
- 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;
-
- var state = this.list.getSelectedRecords()[0];
- if (!state) return;
- if (state.id == 'All') return;
- return state.id;
- },
-
- /**
- * 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();
- },
-
- /**
- * 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 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;
- store.remove(record);
- var selected = this.list.getSelectedRecords()[0];
- if (!selected) return;
- if (selected.id == record.id) {
- this.list.select(0);
- }
- }, this);
-
- store.commitChanges();
-
- 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:htmlEncode} ({count})</div>',
-};
-/**
- * Deluge.Formatters.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/**
- * A collection of functions for string formatting values.
- * @class Deluge.Formatters
- * @author Damien Churchill <damoxc@gmail.com>
- * @version 1.3
- * @singleton
- */
-Deluge.Formatters = (function () {
- var charToEntity = {
- '&': '&amp;',
- '>': '&gt;',
- '<': '&lt;',
- '"': '&quot;',
- "'": '&#39;',
- };
-
- var charToEntityRegex = new RegExp(
- '(' + Object.keys(charToEntity).join('|') + ')',
- 'g'
- );
- var htmlEncodeReplaceFn = function (match, capture) {
- return charToEntity[capture];
- };
-
- /**
- * Formats a date string in the date representation of the current locale,
- * based on the systems timezone.
- *
- * @param {Number} timestamp time in seconds since the Epoch.
- * @return {String} a string in the date representation of the current locale
- * or "" if seconds < 0.
- */
- return (Formatters = {
- 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 the bytes value into a string with K, M or G units.
- *
- * @param {Number} bytes the filesize in bytes
- * @param {Boolean} showZero pass in true to displays 0 values
- * @return {String} formatted string with K, M or G units.
- */
- sizeShort: function (bytes, showZero) {
- if (!bytes && !showZero) return '';
- bytes = bytes / 1024.0;
-
- if (bytes < 1024) {
- return bytes.toFixed(1) + ' K';
- } else {
- bytes = bytes / 1024;
- }
-
- if (bytes < 1024) {
- return bytes.toFixed(1) + ' M';
- } else {
- bytes = bytes / 1024;
- }
-
- return bytes.toFixed(1) + ' G';
- },
-
- /**
- * 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;
- },
-
- cssClassEscape: function (value) {
- return value.toLowerCase().replace('.', '_');
- },
-
- htmlEncode: function (value) {
- return !value
- ? value
- : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
- },
- });
-})();
-var fsize = Deluge.Formatters.size;
-var fsize_short = Deluge.Formatters.sizeShort;
-var fspeed = Deluge.Formatters.speed;
-var ftime = Deluge.Formatters.timeRemaining;
-var fdate = Deluge.Formatters.date;
-var fplain = Deluge.Formatters.plain;
-Ext.util.Format.cssClassEscape = Deluge.Formatters.cssClassEscape;
-Ext.util.Format.htmlEncode = Deluge.Formatters.htmlEncode;
-/**
- * Deluge.Keys.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/**
- * @description The torrent status keys that are commonly used around the UI.
- * @class Deluge.Keys
- * @singleton
- */
-Deluge.Keys = {
- /**
- * Keys that are used within the torrent grid.
- * <pre>['queue', 'name', 'total_wanted', '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', 'download_location', 'last_seen_complete',
- * 'total_done', 'total_uploaded', 'max_download_speed', 'max_upload_speed',
- * 'seeds_peers_ratio', 'total_remaining', 'completed_time', 'time_since_transfer']</pre>
- */
- Grid: [
- 'queue',
- 'name',
- 'total_wanted',
- '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',
- 'download_location',
- 'last_seen_complete',
- 'total_done',
- 'total_uploaded',
- 'max_download_speed',
- 'max_upload_speed',
- 'seeds_peers_ratio',
- 'total_remaining',
- 'completed_time',
- 'time_since_transfer',
- ],
-
- /**
- * 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', 'time_since_transfer',
- * 'seed_rank', 'last_seen_complete', 'completed_time', 'owner', 'public', 'shared']</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',
- 'time_since_transfer',
- 'seed_rank',
- 'last_seen_complete',
- 'completed_time',
- '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'],
-
- /**
- * 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',
- 'download_location',
- 'total_size',
- 'num_files',
- 'message',
- 'tracker_host',
- 'comment',
- 'creator',
- ],
-
- /**
- * 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',
- 'remove_at_ratio',
- 'private',
- 'prioritize_first_last',
- 'move_completed',
- 'move_completed_path',
- 'super_seeding',
- ],
-};
-
-// Merge the grid and status keys together as the status keys contain all the
-// grid ones.
-Ext.each(Deluge.Keys.Grid, function (key) {
- Deluge.Keys.Status.push(key);
-});
-/**
- * Deluge.LoginWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-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: 120,
- labelAlign: 'right',
- defaults: { width: 110 },
- defaultType: 'textfield',
- });
-
- this.passwordField = this.form.add({
- xtype: 'textfield',
- fieldLabel: _('Password:'),
- labelSeparator: '',
- grow: true,
- growMin: '110',
- growMax: '145',
- 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, 300);
- },
-});
-/**
- * Deluge.Menus.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-deluge.menus = {
- onTorrentActionSetOpt: function (item, e) {
- var ids = deluge.torrents.getSelectedIds();
- var action = item.initialConfig.torrentAction;
- var opts = {};
- opts[action[0]] = action[1];
- deluge.client.core.set_torrent_options(ids, opts);
- },
-
- onTorrentActionMethod: function (item, e) {
- var ids = deluge.torrents.getSelectedIds();
- var action = item.initialConfig.torrentAction;
- deluge.client.core[action](ids, {
- success: function () {
- deluge.ui.update();
- },
- });
- },
-
- onTorrentActionShow: function (item, e) {
- var ids = deluge.torrents.getSelectedIds();
- var action = item.initialConfig.torrentAction;
- switch (action) {
- case 'copy_magnet':
- deluge.copyMagnetWindow.show();
- break;
- case 'edit_trackers':
- deluge.editTrackers.show();
- break;
- case 'remove':
- deluge.removeWindow.show(ids);
- break;
- case 'move':
- deluge.moveStorage.show(ids);
- break;
- }
- },
-};
-
-deluge.menus.torrent = new Ext.menu.Menu({
- id: 'torrentMenu',
- items: [
- {
- torrentAction: 'pause_torrent',
- text: _('Pause'),
- iconCls: 'icon-pause',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- {
- torrentAction: 'resume_torrent',
- text: _('Resume'),
- iconCls: 'icon-resume',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- '-',
- {
- text: _('Options'),
- iconCls: 'icon-options',
- hideOnClick: false,
- menu: new Ext.menu.Menu({
- items: [
- {
- text: _('D/L Speed Limit'),
- iconCls: 'x-deluge-downloading',
- hideOnClick: false,
- menu: new Ext.menu.Menu({
- items: [
- {
- torrentAction: ['max_download_speed', 5],
- text: _('5 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_download_speed', 10],
- text: _('10 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_download_speed', 30],
- text: _('30 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_download_speed', 80],
- text: _('80 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_download_speed', 300],
- text: _('300 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_download_speed', -1],
- text: _('Unlimited'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- ],
- }),
- },
- {
- text: _('U/L Speed Limit'),
- iconCls: 'x-deluge-seeding',
- hideOnClick: false,
- menu: new Ext.menu.Menu({
- items: [
- {
- torrentAction: ['max_upload_speed', 5],
- text: _('5 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_speed', 10],
- text: _('10 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_speed', 30],
- text: _('30 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_speed', 80],
- text: _('80 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_speed', 300],
- text: _('300 KiB/s'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_speed', -1],
- text: _('Unlimited'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- ],
- }),
- },
- {
- text: _('Connection Limit'),
- iconCls: 'x-deluge-connections',
- hideOnClick: false,
- menu: new Ext.menu.Menu({
- items: [
- {
- torrentAction: ['max_connections', 50],
- text: '50',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_connections', 100],
- text: '100',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_connections', 200],
- text: '200',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_connections', 300],
- text: '300',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_connections', 500],
- text: '500',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_connections', -1],
- text: _('Unlimited'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- ],
- }),
- },
- {
- text: _('Upload Slot Limit'),
- iconCls: 'icon-upload-slots',
- hideOnClick: false,
- menu: new Ext.menu.Menu({
- items: [
- {
- torrentAction: ['max_upload_slots', 0],
- text: '0',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_slots', 1],
- text: '1',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_slots', 2],
- text: '2',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_slots', 3],
- text: '3',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_slots', 5],
- text: '5',
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['max_upload_slots', -1],
- text: _('Unlimited'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- ],
- }),
- },
- {
- id: 'auto_managed',
- text: _('Auto Managed'),
- hideOnClick: false,
- menu: new Ext.menu.Menu({
- items: [
- {
- torrentAction: ['auto_managed', true],
- text: _('On'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- {
- torrentAction: ['auto_managed', false],
- text: _('Off'),
- handler: deluge.menus.onTorrentActionSetOpt,
- scope: deluge.menus,
- },
- ],
- }),
- },
- ],
- }),
- },
- '-',
- {
- text: _('Queue'),
- iconCls: 'icon-queue',
- hideOnClick: false,
- menu: new Ext.menu.Menu({
- items: [
- {
- torrentAction: 'queue_top',
- text: _('Top'),
- iconCls: 'icon-top',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- {
- torrentAction: 'queue_up',
- text: _('Up'),
- iconCls: 'icon-up',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- {
- torrentAction: 'queue_down',
- text: _('Down'),
- iconCls: 'icon-down',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- {
- torrentAction: 'queue_bottom',
- text: _('Bottom'),
- iconCls: 'icon-bottom',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- ],
- }),
- },
- '-',
- {
- torrentAction: 'copy_magnet',
- text: _('Copy Magnet URI'),
- iconCls: 'icon-magnet-copy',
- handler: deluge.menus.onTorrentActionShow,
- scope: deluge.menus,
- },
- {
- torrentAction: 'force_reannounce',
- text: _('Update Tracker'),
- iconCls: 'icon-update-tracker',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- {
- torrentAction: 'edit_trackers',
- text: _('Edit Trackers'),
- iconCls: 'icon-edit-trackers',
- handler: deluge.menus.onTorrentActionShow,
- scope: deluge.menus,
- },
- '-',
- {
- torrentAction: 'remove',
- text: _('Remove Torrent'),
- iconCls: 'icon-remove',
- handler: deluge.menus.onTorrentActionShow,
- scope: deluge.menus,
- },
- '-',
- {
- torrentAction: 'force_recheck',
- text: _('Force Recheck'),
- iconCls: 'icon-recheck',
- handler: deluge.menus.onTorrentActionMethod,
- scope: deluge.menus,
- },
- {
- torrentAction: 'move',
- text: _('Move Download Folder'),
- iconCls: 'icon-move',
- handler: deluge.menus.onTorrentActionShow,
- scope: deluge.menus,
- },
- ],
-});
-
-deluge.menus.filePriorities = new Ext.menu.Menu({
- id: 'filePrioritiesMenu',
- items: [
- {
- id: 'expandAll',
- text: _('Expand All'),
- iconCls: 'icon-expand-all',
- },
- '-',
- {
- id: 'skip',
- text: _('Skip'),
- iconCls: 'icon-do-not-download',
- filePriority: FILE_PRIORITY['Skip'],
- },
- {
- id: 'low',
- text: _('Low'),
- iconCls: 'icon-low',
- filePriority: FILE_PRIORITY['Low'],
- },
- {
- id: 'normal',
- text: _('Normal'),
- iconCls: 'icon-normal',
- filePriority: FILE_PRIORITY['Normal'],
- },
- {
- id: 'high',
- text: _('High'),
- iconCls: 'icon-high',
- filePriority: FILE_PRIORITY['High'],
- },
- ],
-});
-/**
- * Deluge.MoveStorage.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Ext.namespace('Deluge');
-Deluge.MoveStorage = Ext.extend(Ext.Window, {
- constructor: function (config) {
- config = Ext.apply(
- {
- title: _('Move Download Folder'),
- width: 375,
- height: 110,
- layout: 'fit',
- buttonAlign: 'right',
- closeAction: 'hide',
- closable: true,
- iconCls: 'x-deluge-move-storage',
- plain: true,
- constrainHeader: true,
- resizable: false,
- },
- config
- );
- Deluge.MoveStorage.superclass.constructor.call(this, config);
- },
-
- initComponent: function () {
- Deluge.MoveStorage.superclass.initComponent.call(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.moveLocation = this.form.add({
- fieldLabel: _('Download Folder'),
- 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;
- },
-
- show: function (torrentIds) {
- Deluge.MoveStorage.superclass.show.call(this);
- this.torrentIds = torrentIds;
- },
-
- onCancel: function () {
- this.hide();
- },
-
- onMove: function () {
- var dest = this.moveLocation.getValue();
- deluge.client.core.move_storage(this.torrentIds, dest);
- this.hide();
- },
-});
-deluge.moveStorage = new Deluge.MoveStorage();
-/**
- * Deluge.MultiOptionsManager.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/**
- * @description A class that can be used to manage options throughout the ui.
- * @namespace Deluge
- * @class Deluge.MultiOptionsManager
- * @extends Deluge.OptionsManager
- */
-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;
- },
-
- /**
- * 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];
- },
-
- /**
- * 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 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 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);
- }
- }
- },
-
- /**
- * 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;
-
- 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);
- }
- }
- },
-});
-/**
- * Deluge.OtherLimitWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * @class Deluge.OtherLimitWindow
- * @extends Ext.Window
- */
-Deluge.OtherLimitWindow = Ext.extend(Ext.Window, {
- layout: 'fit',
- width: 210,
- height: 100,
- constrainHeader: true,
- 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);
- }
-
- 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 });
- },
-
- 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();
- },
-
- doFocusField: function () {
- this.form.getForm().findField('limit').focus(true, 10);
- },
-});
-/**
- * Deluge.Plugin.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Deluge');
-
-/**
- * @class Deluge.Plugin
- * @extends Ext.util.Observable
- */
-Deluge.Plugin = Ext.extend(Ext.util.Observable, {
- /**
- * 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,
-
- /**
- * @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 () {
- deluge.client.reloadMethods();
- 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);
-
- 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);
- },
-
- 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 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');
-/**
- * Deluge.RemoveWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/**
- * @class Deluge.RemoveWindow
- * @extends Ext.Window
- */
-Deluge.RemoveWindow = Ext.extend(Ext.Window, {
- title: _('Remove Torrent'),
- layout: 'fit',
- width: 350,
- height: 100,
- constrainHeader: true,
- buttonAlign: 'right',
- closeAction: 'hide',
- closable: true,
- iconCls: 'x-deluge-remove-window-icon',
- plain: true,
-
- 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) {
- deluge.client.core.remove_torrents(this.torrentIds, removeData, {
- success: function (result) {
- if (result == true) {
- console.log(
- 'Error(s) occured when trying to delete torrent(s).'
- );
- }
- this.onRemoved(this.torrentIds);
- },
- scope: this,
- torrentIds: this.torrentIds,
- });
- },
-
- 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 (torrentIds) {
- deluge.events.fire('torrentsRemoved', torrentIds);
- this.hide();
- deluge.ui.update();
- },
-});
-
-deluge.removeWindow = new Deluge.RemoveWindow();
-/**
- * Deluge.Sidebar.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-// These are just so gen_gettext.py will pick up the strings
-// _('State')
-// _('Tracker Host')
-
-/**
- * @class Deluge.Sidebar
- * @author Damien Churchill <damoxc@gmail.com>
- * @version 1.3
- */
-Deluge.Sidebar = Ext.extend(Ext.Panel, {
- // private
- panels: {},
-
- // 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: 100,
- collapsible: true,
- },
- config
- );
- Deluge.Sidebar.superclass.constructor.call(this, config);
- },
-
- // 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;
-
- 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);
- },
-
- getFilter: function (filter) {
- return this.panels[filter];
- },
-
- 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;
- }
- }
-
- return states;
- },
-
- 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;
- },
-
- 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);
- }
- }
-
- // Perform a cleanup of fitlers that are not 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
- );
- },
-});
-/**
- * Deluge.Statusbar.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-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-externalip',
- text: ' ',
- cls: 'x-btn-text',
- tooltip: _('External IP Address'),
- },
- '-',
- {
- 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 folder'),
- 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);
-
- 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('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}',
- });
-
- this.items.get('statusbar-dht').setText(stats.dht_nodes);
- this.items
- .get('statusbar-freespace')
- .setText(
- stats.free_space >= 0 ? fsize(stats.free_space) : _('Error')
- );
- this.items
- .get('statusbar-externalip')
- .setText(
- String.format(
- _('<b>IP</b> {0}'),
- stats.external_ip ? stats.external_ip : _('n/a')
- )
- );
- },
-});
-/**
- * Deluge.Toolbar.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/**
- * An extension of the <tt>Ext.Toolbar</tt> class that provides an extensible toolbar for Deluge.
- * @class Deluge.Toolbar
- * @extends Ext.Toolbar
- */
-Deluge.Toolbar = Ext.extend(Ext.Toolbar, {
- constructor: function (config) {
- config = Ext.apply(
- {
- items: [
- {
- id: 'tbar-deluge-text',
- text: _('Deluge'),
- iconCls: 'x-deluge-main-panel',
- handler: this.onAboutClick,
- },
- new Ext.Toolbar.Separator(),
- {
- id: 'create',
- disabled: true,
- hidden: 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,
- },
- new Ext.Toolbar.Separator(),
- {
- id: 'pause',
- disabled: true,
- text: _('Pause'),
- iconCls: 'icon-pause',
- handler: this.onTorrentAction,
- },
- {
- id: 'resume',
- disabled: true,
- text: _('Resume'),
- iconCls: 'icon-resume',
- handler: this.onTorrentAction,
- },
- new Ext.Toolbar.Separator(),
- {
- 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,
- },
- new Ext.Toolbar.Separator(),
- {
- 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');
- },
-
- onAboutClick: function () {
- var about = new Deluge.about.AboutWindow();
- about.show();
- },
-
- 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();
- },
-});
-/**
- * Deluge.TorrentGrid.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-(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(),
- Ext.util.Format.htmlEncode(value)
- );
- }
- function torrentSpeedRenderer(value) {
- if (!value) return;
- return fspeed(value);
- }
- function torrentLimitRenderer(value) {
- if (value == -1) return '';
- return fspeed(value * 1024.0);
- }
- function torrentProgressRenderer(value, p, r) {
- value = new Number(value);
- var progress = value;
- var text = _(r.data['state']) + ' ' + value.toFixed(2) + '%';
- if (this.style) {
- var style = this.style;
- } else {
- var style = p.style;
- }
- var width = new Number(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;' : parseFloat(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>',
- Ext.util.Format.htmlEncode(value)
- );
- }
-
- function etaSorter(eta) {
- if (eta === 0) return Number.MAX_VALUE;
- if (eta <= -1) return Number.MAX_SAFE_INTEGER;
- return eta;
- }
-
- function dateOrNever(date) {
- return date > 0.0 ? fdate(date) : _('Never');
- }
-
- function timeOrInf(time) {
- if (time === 0) return '';
- if (time <= -1) return '&infin;';
- return ftime(time);
- }
-
- /**
- * 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, {
- // object to store contained torrent ids
- torrents: {},
-
- 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_wanted',
- },
- {
- header: _('Progress'),
- width: 150,
- sortable: true,
- renderer: torrentProgressRenderer,
- dataIndex: 'progress',
- },
- {
- header: _('Seeds'),
- hidden: true,
- width: 60,
- sortable: true,
- renderer: seedsRenderer,
- dataIndex: 'num_seeds',
- },
- {
- header: _('Peers'),
- hidden: true,
- 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: timeOrInf,
- dataIndex: 'eta',
- },
- {
- header: _('Ratio'),
- hidden: true,
- width: 60,
- sortable: true,
- renderer: availRenderer,
- dataIndex: 'ratio',
- },
- {
- header: _('Avail'),
- hidden: true,
- width: 60,
- sortable: true,
- renderer: availRenderer,
- dataIndex: 'distributed_copies',
- },
- {
- header: _('Added'),
- hidden: true,
- width: 80,
- sortable: true,
- renderer: fdate,
- dataIndex: 'time_added',
- },
- {
- header: _('Complete Seen'),
- hidden: true,
- width: 80,
- sortable: true,
- renderer: dateOrNever,
- dataIndex: 'last_seen_complete',
- },
- {
- header: _('Completed'),
- hidden: true,
- width: 80,
- sortable: true,
- renderer: dateOrNever,
- dataIndex: 'completed_time',
- },
- {
- header: _('Tracker'),
- hidden: true,
- width: 120,
- sortable: true,
- renderer: trackerRenderer,
- dataIndex: 'tracker_host',
- },
- {
- header: _('Download Folder'),
- hidden: true,
- width: 120,
- sortable: true,
- renderer: fplain,
- dataIndex: 'download_location',
- },
- {
- header: _('Owner'),
- width: 80,
- sortable: true,
- renderer: fplain,
- dataIndex: 'owner',
- },
- {
- header: _('Public'),
- hidden: true,
- width: 80,
- sortable: true,
- renderer: fplain,
- dataIndex: 'public',
- },
- {
- header: _('Shared'),
- hidden: true,
- width: 80,
- sortable: true,
- renderer: fplain,
- dataIndex: 'shared',
- },
- {
- header: _('Downloaded'),
- hidden: true,
- width: 75,
- sortable: true,
- renderer: fsize,
- dataIndex: 'total_done',
- },
- {
- header: _('Uploaded'),
- hidden: true,
- width: 75,
- sortable: true,
- renderer: fsize,
- dataIndex: 'total_uploaded',
- },
- {
- header: _('Remaining'),
- hidden: true,
- width: 75,
- sortable: true,
- renderer: fsize,
- dataIndex: 'total_remaining',
- },
- {
- header: _('Down Limit'),
- hidden: true,
- width: 75,
- sortable: true,
- renderer: torrentLimitRenderer,
- dataIndex: 'max_download_speed',
- },
- {
- header: _('Up Limit'),
- hidden: true,
- width: 75,
- sortable: true,
- renderer: torrentLimitRenderer,
- dataIndex: 'max_upload_speed',
- },
- {
- header: _('Seeds:Peers'),
- hidden: true,
- width: 75,
- sortable: true,
- renderer: availRenderer,
- dataIndex: 'seeds_peers_ratio',
- },
- {
- header: _('Last Transfer'),
- hidden: true,
- width: 75,
- sortable: true,
- renderer: ftime,
- dataIndex: 'time_since_transfer',
- },
- ],
-
- meta: {
- root: 'torrents',
- idProperty: 'id',
- fields: [
- {
- name: 'queue',
- sortType: Deluge.data.SortTypes.asQueuePosition,
- },
- { name: 'name', sortType: Deluge.data.SortTypes.asName },
- { name: 'total_wanted', 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_rate', type: 'int' },
- { name: 'eta', type: 'int', sortType: etaSorter },
- { name: 'ratio', type: 'float' },
- { name: 'distributed_copies', type: 'float' },
- { name: 'time_added', type: 'int' },
- { name: 'last_seen_complete', type: 'int' },
- { name: 'completed_time', type: 'int' },
- { name: 'tracker_host' },
- { name: 'download_location' },
- { name: 'total_done', type: 'int' },
- { name: 'total_uploaded', type: 'int' },
- { name: 'total_remaining', type: 'int' },
- { name: 'max_download_speed', type: 'int' },
- { name: 'max_upload_speed', type: 'int' },
- { name: 'seeds_peers_ratio', type: 'float' },
- { name: 'time_since_transfer', type: 'int' },
- ],
- },
-
- keys: [
- {
- key: 'a',
- ctrl: true,
- stopEvent: true,
- handler: function () {
- deluge.torrents.getSelectionModel().selectAll();
- },
- },
- {
- key: [46],
- stopEvent: true,
- handler: function () {
- ids = deluge.torrents.getSelectedIds();
- deluge.removeWindow.show(ids);
- },
- },
- ],
-
- constructor: function (config) {
- config = Ext.apply(
- {
- id: 'torrentGrid',
- store: new Ext.data.JsonStore(this.meta),
- columns: this.columns,
- keys: this.keys,
- region: 'center',
- cls: 'deluge-torrents',
- stripeRows: true,
- autoExpandColumn: 'name',
- autoExpandMin: 150,
- deferredRender: false,
- autoScroll: true,
- stateful: true,
- view: new Ext.ux.grid.BufferView({
- rowHeight: 26,
- scrollDelay: false,
- }),
- },
- config
- );
- Deluge.TorrentGrid.superclass.constructor.call(this, config);
- },
-
- initComponent: function () {
- Deluge.TorrentGrid.superclass.initComponent.call(this);
- deluge.events.on('torrentsRemoved', this.onTorrentsRemoved, this);
- deluge.events.on('disconnect', this.onDisconnect, this);
-
- this.on('rowcontextmenu', function (grid, rowIndex, e) {
- e.stopEvent();
- var selection = grid.getSelectionModel();
- if (!selection.isSelected(rowIndex)) {
- selection.selectRow(rowIndex);
- }
- deluge.menus.torrent.showAt(e.getPoint());
- });
- },
-
- /**
- * 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 record.
- * @ return {Array/Ext.data.Record} The record(s) representing the rows
- */
- getSelected: function () {
- return this.getSelectionModel().getSelected();
- },
-
- /**
- * Returns the currently selected records.
- */
- getSelections: function () {
- return this.getSelectionModel().getSelections();
- },
-
- /**
- * Return the currently selected torrent id.
- * @return {String} The currently selected id.
- */
- getSelectedId: function () {
- return this.getSelectionModel().getSelected().id;
- },
-
- /**
- * 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;
- },
-
- update: function (torrents, wipe) {
- var store = this.getStore();
-
- // Need to perform a complete reload of the torrent grid.
- if (wipe) {
- store.removeAll();
- this.torrents = {};
- }
-
- var newTorrents = [];
-
- // Update and add any new torrents.
- for (var t in torrents) {
- var torrent = torrents[t];
-
- 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);
-
- // 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();
-
- var sortState = store.getSortState();
- if (!sortState) return;
- store.sort(sortState.field, sortState.direction);
- },
-
- // private
- onDisconnect: function () {
- this.getStore().removeAll();
- this.torrents = {};
- },
-
- // private
- onTorrentsRemoved: 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();
-})();
-/**
- * Deluge.UI.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/** Dummy translation arrays so Torrent states are available for gettext.js and Translators.
- *
- * All entries in deluge.common.TORRENT_STATE should be added here.
- *
- * No need to import these, just simply use the `_()` function around a status variable.
- */
-var TORRENT_STATE_TRANSLATION = [
- _('All'),
- _('Active'),
- _('Allocating'),
- _('Checking'),
- _('Downloading'),
- _('Seeding'),
- _('Paused'),
- _('Checking'),
- _('Queued'),
- _('Error'),
-];
-
-/**
- * @static
- * @class Deluge.UI
- * The controller for the whole interface, that ties all the components
- * together and handles the 2 second poll.
- */
-deluge.ui = {
- errorCount: 0,
-
- 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();
-
- this.detailsPanel = new Ext.Panel({
- id: 'detailsPanel',
- cls: 'detailsPanel',
- region: 'south',
- split: true,
- height: 215,
- minSize: 100,
- collapsible: true,
- layout: 'fit',
- items: [deluge.details],
- });
-
- this.MainPanel = new Ext.Panel({
- id: 'mainPanel',
- iconCls: 'x-deluge-main-panel',
- layout: 'border',
- border: false,
- tbar: deluge.toolbar,
- items: [deluge.sidebar, this.detailsPanel, deluge.torrents],
- bbar: deluge.statusbar,
- });
-
- 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',
- });
-
- // 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();
-
- 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.originalTitle = document.title;
- },
-
- 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;
-
- deluge.client.web.update_ui(Deluge.Keys.Grid, filters, {
- success: this.onUpdate,
- failure: this.onUpdateError,
- scope: this,
- });
- deluge.details.update();
- },
-
- 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();
- }
- },
-
- 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;
- }
-
- if (deluge.config.show_session_speed) {
- document.title =
- 'D: ' +
- fsize_short(data['stats'].download_rate, true) +
- ' U: ' +
- fsize_short(data['stats'].upload_rate, true) +
- ' - ' +
- this.originalTitle;
- }
- 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
- */
- 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
- );
- },
-
- 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
- );
- },
-
- onPluginDisabled: function (pluginName) {
- if (deluge.plugins[pluginName]) deluge.plugins[pluginName].disable();
- },
-
- 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;
- },
-
- /**
- * @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();
-});
diff --git a/deluge/ui/web/js/deluge-all.js b/deluge/ui/web/js/deluge-all.js
deleted file mode 100644
index f9fd796..0000000
--- a/deluge/ui/web/js/deluge-all.js
+++ /dev/null
@@ -1,291 +0,0 @@
-Ext.ns("Deluge.add");Deluge.add.Window=Ext.extend(Ext.Window,{initComponent:function(){Deluge.add.Window.superclass.initComponent.call(this);this.addEvents("beforeadd","add","addfailed")},createTorrentId:function(){return(new Date).getTime().toString()}});Ext.namespace("Deluge.add");
-Ext.override(Ext.ux.form.FileUploadField,{onRender:function(a,b){Ext.ux.form.FileUploadField.superclass.onRender.call(this,a,b);this.wrap=this.el.wrap({cls:"x-form-field-wrap x-form-file-wrap"});this.el.addClass("x-form-file-text");this.el.dom.removeAttribute("name");this.createFileInput();var c=Ext.applyIf(this.buttonCfg||{},{text:this.buttonText});this.button=new Ext.Button(Ext.apply(c,{renderTo:this.wrap,cls:"x-form-file-btn"+(c.iconCls?" x-btn-text-icon":"")}));this.buttonOnly&&(this.el.hide(),
-this.wrap.setWidth(this.button.getEl().getWidth()));this.bindListeners();this.resizeEl=this.positionEl=this.wrap}});
-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:!0,plain:!0,iconCls:"x-deluge-add-window-icon",initComponent:function(){Deluge.add.AddWindow.superclass.initComponent.call(this);this.addButton(_("Cancel"),this.onCancelClick,this);this.addButton(_("Add"),this.onAddClick,this);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:!0,dataIndex:"text",tpl:new Ext.XTemplate('<div class="x-deluge-add-torrent-name">{text:htmlEncode}</div>')}],stripeRows:!0,singleSelect:!0,listeners:{selectionchange:{fn:this.onSelect,scope:this}},hideHeaders:!0,autoExpandColumn:"torrent",height:"100%",autoScroll:!0});this.add({region:"center",items:[this.list],border:!1,bbar:new Ext.Toolbar({items:[{id:"fileUploadForm",xtype:"form",layout:"fit",baseCls:"x-plain",
-fileUpload:!0,items:[{buttonOnly:!0,xtype:"fileuploadfield",id:"torrentFile",name:"file",multiple:!0,buttonCfg:{iconCls:"x-deluge-add-file",text:_("File")},listeners:{scope:this,fileselected:this.onFileSelected}}]},{text:_("Url"),iconCls:"icon-add-url",handler:this.onUrl,scope:this},{text:_("Infohash"),iconCls:"icon-magnet-add",hidden:!0,disabled:!0},"->",{text:_("Remove"),iconCls:"icon-remove",handler:this.onRemove,scope:this}]})});this.fileUploadForm=Ext.getCmp("fileUploadForm").getForm();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();this.fileUploadForm.reset()},onAddClick:function(){var a=[];this.list&&(this.list.getStore().each(function(b){b=b.get("info_hash");a.push({path:this.optionsPanel.getFilename(b),options:this.optionsPanel.getOptions(b)})},this),deluge.client.web.add_torrents(a,{success:function(a){}}),this.clear(),this.hide())},onCancelClick:function(){this.clear();
-this.hide()},onFile:function(){this.file||(this.file=new Deluge.add.FileWindow);this.file.show()},onHide:function(){this.optionsPanel.setActiveTab(0);this.optionsPanel.files.setDisabled(!0);this.optionsPanel.form.setDisabled(!0)},onRemove:function(){if(this.list.getSelectionCount()){var a=this.list.getSelectedRecords()[0];a&&(this.list.getStore().remove(a),this.optionsPanel.clear(),this.torrents&&this.torrents[a.id]&&delete this.torrents[a.id])}},onSelect:function(a,b){if(b.length){var c=this.list.getRecord(b[0]);
-this.optionsPanel.setTorrent(c.get("info_hash"))}else this.optionsPanel.files.setDisabled(!0),this.optionsPanel.form.setDisabled(!0)},onShow:function(){this.url||(this.url=new Deluge.add.UrlWindow,this.url.on("beforeadd",this.onTorrentBeforeAdd,this),this.url.on("add",this.onTorrentAdd,this),this.url.on("addfailed",this.onTorrentAddFailed,this));this.optionsPanel.form.getDefaults()},onFileSelected:function(){if(this.fileUploadForm.isValid()){var a=[],b=this.fileUploadForm.findField("torrentFile").value,
-c=this.createTorrentId();Array.prototype.forEach.call(b,function(b,f){var g=c+f.toString();a.push(g);this.onTorrentBeforeAdd(g,b.name)}.bind(this));this.fileUploadForm.submit({url:deluge.config.base+"upload",waitMsg:_("Uploading your torrent..."),success:this.onUploadSuccess,failure:this.onUploadFailure,scope:this,torrentIds:a})}},onUploadSuccess:function(a,b){b.result.success?(b.result.files.forEach(function(a,d){deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,scope:this,filename:a,
-torrentId:b.options.torrentIds[d]})}.bind(this)),this.fileUploadForm.reset()):this.clear()},onUploadFailure:function(a,b){this.hide();Ext.MessageBox.show({title:_("Error"),msg:_("Failed to upload torrent"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.fireEvent("addfailed",this.torrentId)},onGotInfo:function(a,b,c,d){a.filename=d.options.filename;torrentId=d.options.torrentId;this.onTorrentAdd(torrentId,a)},onTorrentBeforeAdd:function(a,b){this.list.getStore().loadData([[a,
-null,b]],!0)},onTorrentAdd:function(a,b){var c=this.list.getStore().getById(a);b?(c.set("info_hash",b.info_hash),c.set("text",b.name),this.list.getStore().commitChanges(),this.optionsPanel.addTorrent(b),this.list.select(c)):(Ext.MessageBox.show({title:_("Error"),msg:_("Not a valid torrent"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"}),this.list.getStore().remove(c))},onTorrentAddFailed:function(a){var b=this.list.getStore();(a=b.getById(a))&&b.remove(a)},
-onUrl:function(a,b){this.url.show()}});Ext.ns("Deluge.add");
-Deluge.add.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{layout:"fit",title:_("Files"),autoScroll:!1,animate:!1,border:!1,disabled:!0,rootVisible:!1,columns:[{header:_("Filename"),width:295,dataIndex:"filename",tpl:new Ext.XTemplate("{filename:htmlEncode}")},{header:_("Size"),width:60,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{header:_("Download"),width:65,dataIndex:"download",tpl:new Ext.XTemplate("{download:this.format}",{format:function(a){return'<div rel="chkbox" class="x-grid3-check-col'+
-(a?"-on":"")+'"> </div>'}})}],initComponent:function(){Deluge.add.FilesTab.superclass.initComponent.call(this);this.on("click",this.onNodeClick,this)},clearFiles:function(){var a=this.getRootNode();a.hasChildNodes()&&a.cascade(function(a){a.parentNode&&a.getOwnerTree()&&a.remove()})},setDownload:function(a,b,c){a.attributes.download=b;a.ui.updateColumns();if(a.isLeaf()){if(!c)return this.fireEvent("fileschecked",[a],b,!b)}else{var d=[a];a.cascade(function(a){a.attributes.download=b;a.ui.updateColumns();
-d.push(a)},this);if(!c)return this.fireEvent("fileschecked",d,b,!b)}},onNodeClick:function(a,b){"chkbox"==(new Ext.Element(b.target)).getAttribute("rel")&&this.setDownload(a,!a.attributes.download)}});Ext.namespace("Ext.deluge.add");Ext.ns("Deluge.add");
-Deluge.add.OptionsPanel=Ext.extend(Ext.TabPanel,{torrents:{},region:"south",border:!1,activeTab:0,height:265,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)},addTorrent:function(a){this.torrents[a.info_hash]=a;var b={};this.walkFileTree(a.files_tree,function(a,c,g,e){"file"==c&&(b[g.index]=g.download)},this);var c=[];
-Ext.each(Ext.keys(b),function(a){c[a]=b[a]});a=this.form.optionsManager.changeId(a.info_hash,!0);this.form.optionsManager.setDefault("file_priorities",c);this.form.optionsManager.changeId(a,!0)},clear:function(){this.files.clearFiles();this.form.optionsManager.resetAll()},getFilename:function(a){return this.torrents[a].filename},getOptions:function(a){a=this.form.optionsManager.changeId(a,!0);var b=this.form.optionsManager.get();this.form.optionsManager.changeId(a,!0);Ext.each(b.file_priorities,function(a,
-d){b.file_priorities[d]=a?1:0});return b},setTorrent:function(a){if(a){this.torrentId=a;this.form.optionsManager.changeId(a);this.files.clearFiles();var b=this.files.getRootNode(),c=this.form.optionsManager.get("file_priorities");this.form.setDisabled(!1);this.torrents[a].files_tree?(this.walkFileTree(this.torrents[a].files_tree,function(a,b,g,e){a=new Ext.tree.TreeNode({download:g.index?c[g.index]:!0,filename:a,fileindex:g.index,leaf:"dir"!=b,size:g.length});e.appendChild(a);if("dir"==b)return a},
-this,b),b.firstChild.expand(),this.files.setDisabled(!1),this.files.show()):(this.form.show(),this.files.setDisabled(!0))}},walkFileTree:function(a,b,c,d){for(var f in a.contents){var g=a.contents[f],e=g.type,l=c?b.apply(c,[f,e,g,d]):b(f,e,g,d);"dir"==e&&this.walkFileTree(g,b,c,l)}},onFilesChecked:function(a,b,c){Ext.each(a,function(a){if(!(0>a.attributes.fileindex)){var c=this.form.optionsManager.get("file_priorities");c[a.attributes.fileindex]=b;this.form.optionsManager.update("file_priorities",
-c)}},this)}});Ext.ns("Deluge.add");
-Deluge.add.OptionsTab=Ext.extend(Ext.form.FormPanel,{title:_("Options"),height:170,border:!1,bodyStyle:"padding: 5px",disabled:!0,labelWidth:1,initComponent:function(){Deluge.add.OptionsTab.superclass.initComponent.call(this);this.optionsManager=new Deluge.MultiOptionsManager;var a=this.add({xtype:"fieldset",title:_("Download Folder"),border:!1,autoHeight:!0,defaultType:"textfield",labelWidth:1,fieldLabel:"",style:"padding: 5px 0; margin-bottom: 0;"});this.optionsManager.bind("download_location",a.add({fieldLabel:"",
-name:"download_location",anchor:"95%",labelSeparator:""}));a=this.add({xtype:"fieldset",title:_("Move Completed Folder"),border:!1,autoHeight:!0,defaultType:"togglefield",labelWidth:1,fieldLabel:"",style:"padding: 5px 0; margin-bottom: 0;"});a=a.add({fieldLabel:"",name:"move_completed_path",anchor:"98%"});this.optionsManager.bind("move_completed",a.toggle);this.optionsManager.bind("move_completed_path",a.input);var b=this.add({border:!1,layout:"column",defaultType:"fieldset"}),a=b.add({title:_("Bandwidth"),
-border:!1,autoHeight:!0,bodyStyle:"padding: 2px 5px",labelWidth:105,width:200,defaultType:"spinnerfield",style:"padding-right: 10px;"});this.optionsManager.bind("max_download_speed",a.add({fieldLabel:_("Max Down Speed"),name:"max_download_speed",width:60}));this.optionsManager.bind("max_upload_speed",a.add({fieldLabel:_("Max Up Speed"),name:"max_upload_speed",width:60}));this.optionsManager.bind("max_connections",a.add({fieldLabel:_("Max Connections"),name:"max_connections",width:60}));this.optionsManager.bind("max_upload_slots",
-a.add({fieldLabel:_("Max Upload Slots"),name:"max_upload_slots",width:60}));a=b.add({border:!1,autoHeight:!0,defaultType:"checkbox"});this.optionsManager.bind("add_paused",a.add({name:"add_paused",boxLabel:_("Add In Paused State"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("prioritize_first_last_pieces",a.add({name:"prioritize_first_last_pieces",boxLabel:_("Prioritize First/Last Pieces"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("sequential_download",a.add({name:"sequential_download",
-boxLabel:_("Sequential Download"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("seed_mode",a.add({name:"seed_mode",boxLabel:_("Skip File Hash Check"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("super_seeding",a.add({name:"super_seeding",boxLabel:_("Super Seed"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("pre_allocate_storage",a.add({name:"pre_allocate_storage",boxLabel:_("Preallocate Disk Space"),fieldLabel:"",labelSeparator:""}))},getDefaults:function(){deluge.client.core.get_config_values("add_paused pre_allocate_storage download_location max_connections_per_torrent max_download_speed_per_torrent move_completed move_completed_path max_upload_slots_per_torrent max_upload_speed_per_torrent prioritize_first_last_pieces sequential_download".split(" "),
-{success:function(a){this.optionsManager.options={file_priorities:[],add_paused:a.add_paused,sequential_download:a.sequential_download,pre_allocate_storage:a.pre_allocate_storage,download_location:a.download_location,move_completed:a.move_completed,move_completed_path:a.move_completed_path,max_connections:a.max_connections_per_torrent,max_download_speed:a.max_download_speed_per_torrent,max_upload_slots:a.max_upload_slots_per_torrent,max_upload_speed:a.max_upload_speed_per_torrent,prioritize_first_last_pieces:a.prioritize_first_last_pieces,
-seed_mode:!1,super_seeding:!1};this.optionsManager.resetAll()},scope:this})}});Ext.namespace("Deluge.add");
-Deluge.add.UrlWindow=Ext.extend(Deluge.add.Window,{title:_("Add from Url"),modal:!0,plain:!0,layout:"fit",width:350,height:155,buttonAlign:"center",closeAction:"hide",bodyStyle:"padding: 10px 5px;",iconCls:"x-deluge-add-url-window-icon",initComponent:function(){Deluge.add.UrlWindow.superclass.initComponent.call(this);this.addButton(_("Add"),this.onAddClick,this);var a=this.add({xtype:"form",defaultType:"textfield",baseCls:"x-plain",labelWidth:55});this.urlField=a.add({fieldLabel:_("Url"),id:"url",
-name:"url",width:"97%"});this.urlField.on("specialkey",this.onAdd,this);this.cookieField=a.add({fieldLabel:_("Cookies"),id:"cookies",name:"cookies",width:"97%"});this.cookieField.on("specialkey",this.onAdd,this)},onAddClick:function(a,b){if(!(("url"==a.id||"cookies"==a.id)&&b.getKey()!=b.ENTER)){a=this.urlField;var c=a.getValue(),d=this.cookieField.getValue(),f=this.createTorrentId();0==c.indexOf("magnet:?")&&-1<c.indexOf("xt=urn:btih")?deluge.client.web.get_magnet_info(c,{success:this.onGotInfo,
-scope:this,filename:c,torrentId:f}):deluge.client.web.download_torrent_from_url(c,d,{success:this.onDownload,failure:this.onDownloadFailed,scope:this,torrentId:f});this.hide();this.urlField.setValue("");this.fireEvent("beforeadd",f,c)}},onDownload:function(a,b,c,d){deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,failure:this.onDownloadFailed,scope:this,filename:a,torrentId:d.options.torrentId})},onDownloadFailed:function(a,b,c){Ext.MessageBox.show({title:_("Error"),msg:_("Failed to download torrent"),
-buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.fireEvent("addfailed",c.options.torrentId)},onGotInfo:function(a,b,c,d){a.filename=d.options.filename;this.fireEvent("add",d.options.torrentId,a)}});Ext.namespace("Deluge.data");Deluge.data.SortTypes={asIPAddress:function(a){a=a.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);return 256*(256*(256*+a[1]+ +a[2])+ +a[3])+ +a[4]},asQueuePosition:function(a){return-1<a?a:Number.MAX_VALUE},asName:function(a){return String(a).toLowerCase()}};
-Ext.namespace("Deluge.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"}]);Ext.namespace("Deluge.data");
-Deluge.data.Torrent=Ext.data.Record.create([{name:"queue",type:"int"},{name:"name",type:"string",sortType:Deluge.data.SortTypes.asName},{name:"total_wanted",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:"save_path",type:"string"},{name:"total_done",type:"int"},{name:"total_uploaded",type:"int"},{name:"total_remaining",type:"int"},{name:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"},{name:"time_since_transfer",type:"int"}]);Ext.namespace("Deluge.details");
-Deluge.details.DetailsPanel=Ext.extend(Ext.TabPanel,{id:"torrentDetails",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(a){a.clear&&(a.clear.defer(100,a),a.disable())})},update:function(a){var b=deluge.torrents.getSelected();
-b?(this.items.each(function(a){a.disabled&&a.enable()}),a=a||this.getActiveTab(),a.update&&a.update(b.id)):this.clear()},onRender:function(a,b){Deluge.details.DetailsPanel.superclass.onRender.call(this,a,b);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(a){a.hasSelection()||this.clear()},this)},onTabChange:function(a,b){this.update(b)},
-onTorrentsClick:function(a,b,c){this.update()}});
-Deluge.details.DetailsTab=Ext.extend(Ext.Panel,{title:_("Details"),fields:{},autoScroll:!0,queuedItems:{},oldData:{},initComponent:function(){Deluge.details.DetailsTab.superclass.initComponent.call(this);this.addItem("torrent_name",_("Name:"));this.addItem("hash",_("Hash:"));this.addItem("path",_("Download Folder:"));this.addItem("size",_("Total Size:"));this.addItem("files",_("Total Files:"));this.addItem("comment",_("Comment:"));this.addItem("status",_("Status:"));this.addItem("tracker",_("Tracker:"));
-this.addItem("creator",_("Created By:"))},onRender:function(a,b){Deluge.details.DetailsTab.superclass.onRender.call(this,a,b);this.body.setStyle("padding","10px");this.dl=Ext.DomHelper.append(this.body,{tag:"dl"},!0);for(var c in this.queuedItems)this.doAddItem(c,this.queuedItems[c])},addItem:function(a,b){this.rendered?this.doAddItem(a,b):this.queuedItems[a]=b},doAddItem:function(a,b){Ext.DomHelper.append(this.dl,{tag:"dt",cls:a,html:b});this.fields[a]=Ext.DomHelper.append(this.dl,{tag:"dd",cls:a,
-html:""},!0)},clear:function(){if(this.fields){for(var a in this.fields)this.fields[a].dom.innerHTML="";this.oldData={}}},update:function(a){deluge.client.web.get_torrent_status(a,Deluge.Keys.Details,{success:this.onRequestComplete,scope:this,torrentId:a})},onRequestComplete:function(a,b,c,d){a={torrent_name:a.name,hash:d.options.torrentId,path:a.download_location,size:fsize(a.total_size),files:a.num_files,status:a.message,tracker:a.tracker_host,comment:a.comment,creator:a.creator};for(var f in this.fields)Ext.isDefined(a[f])&&
-a[f]!=this.oldData[f]&&(this.fields[f].dom.innerHTML=Ext.util.Format.htmlEncode(a[f]));this.oldData=a}});
-Deluge.details.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{title:_("Files"),rootVisible:!1,columns:[{header:_("Filename"),width:330,dataIndex:"filename",tpl:new Ext.XTemplate("{filename:htmlEncode}")},{header:_("Size"),width:150,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{xtype:"tgrendercolumn",header:_("Progress"),width:150,dataIndex:"progress",renderer:function(a){a*=100;return Deluge.progressBar(a,this.col.width,a.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(a){return FILE_PRIORITY_CSS[a]},getName:function(a){return _(FILE_PRIORITY[a])}})}],selModel:new Ext.tree.MultiSelectionModel,initComponent:function(){Deluge.details.FilesTab.superclass.initComponent.call(this);this.setRootNode(new Ext.tree.TreeNode({text:_("Files")}))},clear:function(){var a=this.getRootNode();a.hasChildNodes()&&
-a.cascade(function(a){var c=a.parentNode;c&&c.ownerTree&&c.removeChild(a)})},createFileTree:function(a){function b(a,c){for(var g in a.contents){var e=a.contents[g];"dir"==e.type?b(e,c.appendChild(new Ext.tree.TreeNode({text:g,filename:g,size:e.size,progress:e.progress,priority:e.priority}))):c.appendChild(new Ext.tree.TreeNode({text:g,filename:g,fileIndex:e.index,size:e.size,progress:e.progress,priority:e.priority,leaf:!0,iconCls:"x-deluge-file",uiProvider:Ext.ux.tree.TreeGridNodeUI}))}}var c=this.getRootNode();
-b(a,c);c.firstChild.expand()},update:function(a){this.torrentId!=a&&(this.clear(),this.torrentId=a);deluge.client.web.get_torrent_files(a,{success:this.onRequestComplete,scope:this,torrentId:a})},updateFileTree:function(a){function b(a,d){for(var f in a.contents){var g=a.contents[f],e=d.findChild("filename",f);e.attributes.size=g.size;e.attributes.progress=g.progress;e.attributes.priority=g.priority;e.ui.updateColumns();"dir"==g.type&&b(g,e)}}b(a,this.getRootNode())},onRender:function(a,b){Deluge.details.FilesTab.superclass.onRender.call(this,
-a,b);deluge.menus.filePriorities.on("itemclick",this.onItemClick,this);this.on("contextmenu",this.onContextMenu,this);this.sorter=new Ext.tree.TreeSorter(this,{folderSort:!0})},onContextMenu:function(a,b){b.stopEvent();var c=this.getSelectionModel();2>c.getSelectedNodes().length&&(c.clearSelections(),a.select());deluge.menus.filePriorities.showAt(b.getPoint())},onItemClick:function(a,b){switch(a.id){case "expandAll":this.expandAll();break;default:var c={};this.getRootNode().cascade(function(a){Ext.isEmpty(a.attributes.fileIndex)||
-(c[a.attributes.fileIndex]=a.attributes.priority)});var d=this.getSelectionModel().getSelectedNodes();Ext.each(d,function(b){b.isLeaf()?Ext.isEmpty(b.attributes.fileIndex)||(c[b.attributes.fileIndex]=a.filePriority):b.cascade(function(b){Ext.isEmpty(b.attributes.fileIndex)||(c[b.attributes.fileIndex]=a.filePriority)})});var f=Array(Ext.keys(c).length),g;for(g in c)f[g]=c[g];deluge.client.core.set_torrent_options([this.torrentId],{file_priorities:f},{success:function(){Ext.each(d,function(b){b.setColumnValue(3,
-a.filePriority)})},scope:this})}},onRequestComplete:function(a,b){this.getRootNode().hasChildNodes()?this.updateFileTree(a):this.createFileTree(a)}});
-Deluge.details.OptionsTab=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({autoScroll:!0,bodyStyle:"padding: 5px;",border:!1,cls:"x-deluge-options",defaults:{autoHeight:!0,labelWidth:1,defaultType:"checkbox"},deferredRender:!1,layout:"column",title:_("Options")},a);Deluge.details.OptionsTab.superclass.constructor.call(this,a)},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:!1,stop_at_ratio:!1,stop_ratio:2,remove_at_ratio:!1,move_completed:!1,move_completed_path:"","private":!1,prioritize_first_last:!1,super_seeding:!1}});this.fieldsets.bandwidth=this.add({xtype:"fieldset",defaultType:"spinnerfield",bodyStyle:"padding: 5px",layout:"table",layoutConfig:{columns:3},labelWidth:150,style:"margin-left: 10px; margin-right: 5px; padding: 5px",title:_("Bandwidth"),width:250});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"});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"});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});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});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,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.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:!0,width:50,value:2,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:!0,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",width:180,disabled:!0});this.rightColumn=this.add({border:!1,autoHeight:!0,style:"margin-left: 5px",width:210});this.fieldsets.general=this.rightColumn.add({xtype:"fieldset",autoHeight:!0,defaultType:"checkbox",title:_("General"),layout:"form"});this.fields["private"]=
-this.fieldsets.general.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Private"),id:"private",disabled:!0});this.fields.prioritize_first_last=this.fieldsets.general.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Prioritize First/Last"),id:"prioritize_first_last"});this.fields.super_seeding=this.fieldsets.general.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Super Seeding"),id:"super_seeding"});for(var a in this.fields)this.optionsManager.bind(a,this.fields[a]);this.buttonPanel=this.rightColumn.add({layout:"hbox",
-xtype:"panel",border:!1});this.buttonPanel.add({id:"edit_trackers",xtype:"button",text:_("Edit Trackers"),cls:"x-btn-text-icon",iconCls:"x-deluge-edit-trackers",border:!1,width:100,handler:this.onEditTrackers,scope:this});this.buttonPanel.add({id:"apply",xtype:"button",text:_("Apply"),style:"margin-left: 10px;",border:!1,width:100,handler:this.onApply,scope:this})},onRender:function(a,b){Deluge.details.OptionsTab.superclass.onRender.call(this,a,b);this.layout=new Ext.layout.ColumnLayout;this.layout.setContainer(this);
-this.doLayout()},clear:function(){null!=this.torrentId&&(this.torrentId=null,this.optionsManager.changeId(null))},reset:function(){this.torrentId&&this.optionsManager.reset()},update:function(a){this.torrentId&&!a&&this.clear();a&&(this.torrentId!=a&&(this.torrentId=a,this.optionsManager.changeId(a)),deluge.client.web.get_torrent_status(a,Deluge.Keys.Options,{success:this.onRequestComplete,scope:this}))},onApply:function(){var a=this.optionsManager.getDirty();deluge.client.core.set_torrent_options([this.torrentId],
-a,{success:function(){this.optionsManager.commit()},scope:this})},onEditTrackers:function(){deluge.editTrackers.show()},onMoveCompletedChecked:function(a,b){this.fields.move_completed_path.setDisabled(!b);b&&this.fields.move_completed_path.focus()},onStopRatioChecked:function(a,b){this.fields.remove_at_ratio.setDisabled(!b);this.fields.stop_ratio.setDisabled(!b)},onRequestComplete:function(a,b){this.fields["private"].setValue(a["private"]);this.fields["private"].setDisabled(!0);delete a["private"];
-a.auto_managed=a.is_auto_managed;a.prioritize_first_last_pieces=a.prioritize_first_last;this.optionsManager.setDefault(a);var c=this.optionsManager.get("stop_at_ratio");this.fields.remove_at_ratio.setDisabled(!c);this.fields.stop_ratio.setDisabled(!c);this.fields.move_completed_path.setDisabled(!this.optionsManager.get("move_completed"))}});
-(function(){function a(a){return!a.replace(" ","").replace(" ","")?"":String.format('<img alt="{1}" title="{1}" src="{0}flag/{1}" />',deluge.config.base,a)}function b(a,b,c){b=1024==c.data.seed?"x-deluge-seed":"x-deluge-peer";c=a.split(":");2<c.length&&(a=c.pop(),a="["+c.join(":")+"]:"+a);return String.format('<div class="{0}">{1}</div>',b,a)}function c(a){a=(100*a).toFixed(0);return Deluge.progressBar(a,this.width-8,a+"%")}Deluge.details.PeersTab=Ext.extend(Ext.grid.GridPanel,{peers:{},constructor:function(d){d=
-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:!0,renderer:a,dataIndex:"country"},{header:_("Address"),width:125,sortable:!0,renderer:b,dataIndex:"ip"},{header:_("Client"),width:125,sortable:!0,renderer:"htmlEncode",dataIndex:"client"},{header:_("Progress"),width:150,sortable:!0,renderer:c,dataIndex:"progress"},{header:_("Down Speed"),width:100,
-sortable:!0,renderer:fspeed,dataIndex:"down_speed"},{header:_("Up Speed"),width:100,sortable:!0,renderer:fspeed,dataIndex:"up_speed"}],stripeRows:!0,deferredRender:!1,autoScroll:!0},d);Deluge.details.PeersTab.superclass.constructor.call(this,d)},clear:function(){this.getStore().removeAll();this.peers={}},update:function(a){deluge.client.web.get_torrent_status(a,Deluge.Keys.Peers,{success:this.onRequestComplete,scope:this})},onRequestComplete:function(a,b){if(a){var c=this.getStore(),e=[],l={};Ext.each(a.peers,
-function(a){if(this.peers[a.ip]){var b=c.getById(a.ip);b.beginEdit();for(var d in a)b.get(d)!=a[d]&&b.set(d,a[d]);b.endEdit()}else this.peers[a.ip]=1,e.push(new Deluge.data.Peer(a,a.ip));l[a.ip]=1},this);c.add(e);c.each(function(a){l[a.id]||(c.remove(a),delete this.peers[a.id])},this);c.commitChanges();var h=c.getSortState();h&&c.sort(h.field,h.direction)}}})})();Ext.ns("Deluge.details");
-Deluge.details.StatusTab=Ext.extend(Ext.Panel,{title:_("Status"),autoScroll:!0,onRender:function(a,b){Deluge.details.StatusTab.superclass.onRender.call(this,a,b);this.progressBar=this.add({xtype:"progress",cls:"x-deluge-status-progressbar"});this.status=this.add({cls:"x-deluge-status",id:"deluge-details-status",border:!1,width:1E3,listeners:{render:{fn:function(a){a.load({url:deluge.config.base+"render/tab_status.html",text:_("Loading")+"..."});a.getUpdater().on("update",this.onPanelUpdate,this)},
-scope:this}}})},clear:function(){this.progressBar.updateProgress(0," ");for(var a in this.fields)this.fields[a].innerHTML=""},update:function(a){this.fields||this.getFields();deluge.client.web.get_torrent_status(a,Deluge.Keys.Status,{success:this.onRequestComplete,scope:this})},onPanelUpdate:function(a,b){this.fields={};Ext.each(Ext.query("dd",this.status.body.dom),function(a){this.fields[a.className]=a},this)},onRequestComplete:function(a){seeds=-1<a.total_seeds?a.num_seeds+" ("+a.total_seeds+")":
-a.num_seeds;peers=-1<a.total_peers?a.num_peers+" ("+a.total_peers+")":a.num_peers;last_seen_complete=0<a.last_seen_complete?fdate(a.last_seen_complete):"Never";completed_time=0<a.completed_time?fdate(a.completed_time):"";var b={downloaded:fsize(a.total_done,!0),uploaded:fsize(a.total_uploaded,!0),share:-1==a.ratio?"&infin;":a.ratio.toFixed(3),announce:ftime(a.next_announce),tracker_status:a.tracker_status,downspeed:a.download_payload_rate?fspeed(a.download_payload_rate):"0.0 KiB/s",upspeed:a.upload_payload_rate?
-fspeed(a.upload_payload_rate):"0.0 KiB/s",eta:0>a.eta?"&infin;":ftime(a.eta),pieces:a.num_pieces+" ("+fsize(a.piece_length)+")",seeds:seeds,peers:peers,avail:a.distributed_copies.toFixed(3),active_time:ftime(a.active_time),seeding_time:ftime(a.seeding_time),seed_rank:a.seed_rank,time_added:fdate(a.time_added),last_seen_complete:last_seen_complete,completed_time:completed_time,time_since_transfer:ftime(a.time_since_transfer)};b.auto_managed=_(a.is_auto_managed?"True":"False");var c={Error:_("Error"),
-Warning:_("Warning"),"Announce OK":_("Announce OK"),"Announce Sent":_("Announce Sent")},d;for(d in c)if(-1!=b.tracker_status.indexOf(d)){b.tracker_status=b.tracker_status.replace(d,c[d]);break}b.downloaded+=" ("+(a.total_payload_download?fsize(a.total_payload_download):"0.0 KiB")+")";b.uploaded+=" ("+(a.total_payload_upload?fsize(a.total_payload_upload):"0.0 KiB")+")";for(var f in this.fields)this.fields[f].innerHTML=b[f];b=a.state+" "+a.progress.toFixed(2)+"%";this.progressBar.updateProgress(a.progress/
-100,b)}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Bandwidth=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Bandwidth"),header:!1,layout:"form",labelWidth:10},a);Deluge.preferences.Bandwidth.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Bandwidth.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Global Bandwidth Usage"),labelWidth:200,defaultType:"spinnerfield",defaults:{minValue:-1,
-maxValue:99999},style:"margin-bottom: 0px; padding-bottom: 0px;",autoHeight:!0});a.bind("max_connections_global",b.add({name:"max_connections_global",fieldLabel:_("Maximum Connections:"),labelSeparator:"",width:80,value:-1,decimalPrecision:0}));a.bind("max_upload_slots_global",b.add({name:"max_upload_slots_global",fieldLabel:_("Maximum Upload Slots"),labelSeparator:"",width:80,value:-1,decimalPrecision:0}));a.bind("max_download_speed",b.add({name:"max_download_speed",fieldLabel:_("Maximum Download Speed (KiB/s):"),
-labelSeparator:"",width:80,value:-1,decimalPrecision:1}));a.bind("max_upload_speed",b.add({name:"max_upload_speed",fieldLabel:_("Maximum Upload Speed (KiB/s):"),labelSeparator:"",width:80,value:-1,decimalPrecision:1}));a.bind("max_half_open_connections",b.add({name:"max_half_open_connections",fieldLabel:_("Maximum Half-Open Connections:"),labelSeparator:"",width:80,value:-1,decimalPrecision:0}));a.bind("max_connections_per_second",b.add({name:"max_connections_per_second",fieldLabel:_("Maximum Connection Attempts per Second:"),
-labelSeparator:"",width:80,value:-1,decimalPrecision:0}));b=this.add({xtype:"fieldset",border:!1,title:"",defaultType:"checkbox",style:"padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;",autoHeight:!0});a.bind("ignore_limits_on_local_network",b.add({name:"ignore_limits_on_local_network",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Ignore limits on local network")}));a.bind("rate_limit_ip_overhead",b.add({name:"rate_limit_ip_overhead",height:22,fieldLabel:"",labelSeparator:"",
-boxLabel:_("Rate limit IP overhead")}));b=this.add({xtype:"fieldset",border:!1,title:_("Per Torrent Bandwidth Usage"),style:"margin-bottom: 0px; padding-bottom: 0px;",defaultType:"spinnerfield",labelWidth:200,defaults:{minValue:-1,maxValue:99999},autoHeight:!0});a.bind("max_connections_per_torrent",b.add({name:"max_connections_per_torrent",fieldLabel:_("Maximum Connections:"),labelSeparator:"",width:80,value:-1,decimalPrecision:0}));a.bind("max_upload_slots_per_torrent",b.add({name:"max_upload_slots_per_torrent",
-fieldLabel:_("Maximum Upload Slots:"),labelSeparator:"",width:80,value:-1,decimalPrecision:0}));a.bind("max_download_speed_per_torrent",b.add({name:"max_download_speed_per_torrent",fieldLabel:_("Maximum Download Speed (KiB/s):"),labelSeparator:"",width:80,value:-1,decimalPrecision:0}));a.bind("max_upload_speed_per_torrent",b.add({name:"max_upload_speed_per_torrent",fieldLabel:_("Maximum Upload Speed (KiB/s):"),labelSeparator:"",width:80,value:-1,decimalPrecision:0}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Cache=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Cache"),header:!1,layout:"form",initComponent:function(){Deluge.preferences.Cache.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Settings"),autoHeight:!0,labelWidth:180,defaultType:"spinnerfield",defaults:{decimalPrecision:0,minValue:-1,maxValue:999999}});a.bind("cache_size",b.add({fieldLabel:_("Cache Size (16 KiB Blocks):"),labelSeparator:"",
-name:"cache_size",width:60,value:512}));a.bind("cache_expiry",b.add({fieldLabel:_("Cache Expiry (seconds):"),labelSeparator:"",name:"cache_expiry",width:60,value:60}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Daemon=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Daemon"),header:!1,layout:"form",initComponent:function(){Deluge.preferences.Daemon.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Port"),autoHeight:!0,defaultType:"spinnerfield"});a.bind("daemon_port",b.add({fieldLabel:_("Daemon port:"),labelSeparator:"",name:"daemon_port",value:58846,decimalPrecision:0,minValue:-1,maxValue:99999}));b=this.add({xtype:"fieldset",
-border:!1,title:_("Connections"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("allow_remote",b.add({fieldLabel:"",height:22,labelSeparator:"",boxLabel:_("Allow Remote Connections"),name:"allow_remote"}));b=this.add({xtype:"fieldset",border:!1,title:_("Other"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("new_release_check",b.add({fieldLabel:"",labelSeparator:"",height:40,boxLabel:_("Periodically check the website for new releases"),id:"new_release_check"}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Downloads=Ext.extend(Ext.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Downloads"),header:!1,layout:"form",autoHeight:!0,width:320},a);Deluge.preferences.Downloads.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Downloads.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Folders"),labelWidth:150,defaultType:"togglefield",autoHeight:!0,labelAlign:"top",
-width:300,style:"margin-bottom: 5px; padding-bottom: 5px;"});a.bind("download_location",b.add({xtype:"textfield",name:"download_location",fieldLabel:_("Download to:"),labelSeparator:"",width:280}));var c=b.add({name:"move_completed_path",fieldLabel:_("Move completed to:"),labelSeparator:"",width:280});a.bind("move_completed",c.toggle);a.bind("move_completed_path",c.input);c=b.add({name:"torrentfiles_location",fieldLabel:_("Copy of .torrent files to:"),labelSeparator:"",width:280});a.bind("copy_torrent_file",
-c.toggle);a.bind("torrentfiles_location",c.input);b=this.add({xtype:"fieldset",border:!1,title:_("Options"),autoHeight:!0,labelWidth:1,defaultType:"checkbox",style:"margin-bottom: 0; padding-bottom: 0;",width:280});a.bind("prioritize_first_last_pieces",b.add({name:"prioritize_first_last_pieces",labelSeparator:"",height:22,boxLabel:_("Prioritize first and last pieces of torrent")}));a.bind("sequential_download",b.add({name:"sequential_download",labelSeparator:"",height:22,boxLabel:_("Sequential download")}));
-a.bind("add_paused",b.add({name:"add_paused",labelSeparator:"",height:22,boxLabel:_("Add torrents in Paused state")}));a.bind("pre_allocate_storage",b.add({name:"pre_allocate_storage",labelSeparator:"",height:22,boxLabel:_("Pre-allocate disk space")}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Encryption=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Encryption"),header:!1,initComponent:function(){Deluge.preferences.Encryption.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Settings"),header:!1,autoHeight:!0,defaultType:"combo",width:300});a.bind("enc_in_policy",b.add({fieldLabel:_("Incoming:"),labelSeparator:"",mode:"local",width:150,store:new Ext.data.ArrayStore({fields:["id","text"],
-data:[[0,_("Forced")],[1,_("Enabled")],[2,_("Disabled")]]}),editable:!1,triggerAction:"all",valueField:"id",displayField:"text"}));a.bind("enc_out_policy",b.add({fieldLabel:_("Outgoing:"),labelSeparator:"",mode:"local",width:150,store:new Ext.data.SimpleStore({fields:["id","text"],data:[[0,_("Forced")],[1,_("Enabled")],[2,_("Disabled")]]}),editable:!1,triggerAction:"all",valueField:"id",displayField:"text"}));a.bind("enc_level",b.add({fieldLabel:_("Level:"),labelSeparator:"",mode:"local",width:150,
-store:new Ext.data.SimpleStore({fields:["id","text"],data:[[0,_("Handshake")],[1,_("Full Stream")],[2,_("Either")]]}),editable:!1,triggerAction:"all",valueField:"id",displayField:"text"}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.InstallPluginWindow=Ext.extend(Ext.Window,{title:_("Install Plugin"),layout:"fit",height:115,width:350,constrainHeader:!0,bodyStyle:"padding: 10px 5px;",buttonAlign:"center",closeAction:"hide",iconCls:"x-deluge-install-plugin",modal:!0,plain:!0,initComponent:function(){Deluge.preferences.InstallPluginWindow.superclass.initComponent.call(this);this.addButton(_("Install"),this.onInstall,this);this.form=this.add({xtype:"form",baseCls:"x-plain",labelWidth:70,autoHeight:!0,fileUpload:!0,
-items:[{xtype:"fileuploadfield",width:240,emptyText:_("Select an egg"),fieldLabel:_("Plugin Egg"),name:"file",buttonCfg:{text:_("Browse...")}}]})},onInstall:function(a,b){this.form.getForm().submit({url:deluge.config.base+"upload",waitMsg:_("Uploading your plugin..."),success:this.onUploadSuccess,scope:this})},onUploadPlugin:function(a,b,c,d){this.fireEvent("pluginadded")},onUploadSuccess:function(a,b){this.hide();if(b.result.success){var c=this.form.getForm().getFieldValues().file,c=c.split("\\").slice(-1)[0],
-d=b.result.files[0];this.form.getForm().setValues({file:""});deluge.client.web.upload_plugin(c,d,{success:this.onUploadPlugin,scope:this,filename:c})}}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Interface=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Interface"),header:!1,layout:"form",initComponent:function(){Deluge.preferences.Interface.superclass.initComponent.call(this);var a=this.optionsManager=new Deluge.OptionsManager;this.on("show",this.onPageShow,this);var b=this.add({xtype:"fieldset",border:!1,title:_("Interface"),style:"margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px",autoHeight:!0,labelWidth:1,defaultType:"checkbox",defaults:{height:17,fieldLabel:"",
-labelSeparator:""}});a.bind("show_session_speed",b.add({name:"show_session_speed",boxLabel:_("Show session speed in titlebar")}));a.bind("sidebar_show_zero",b.add({name:"sidebar_show_zero",boxLabel:_("Show filters with zero torrents")}));a.bind("sidebar_multiple_filters",b.add({name:"sidebar_multiple_filters",boxLabel:_("Allow the use of multiple filters at once")}));b=this.add({xtype:"fieldset",border:!1,title:_("Language"),style:"margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px",autoHeight:!0,
-labelWidth:1,defaultType:"checkbox"});this.language=a.bind("language",b.add({xtype:"combo",labelSeparator:"",name:"language",mode:"local",width:200,store:new Ext.data.ArrayStore({fields:["id","text"]}),editable:!1,triggerAction:"all",valueField:"id",displayField:"text"}));b=this.add({xtype:"fieldset",border:!1,title:_("WebUI Password"),style:"margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px",autoHeight:!0,labelWidth:100,defaultType:"textfield",defaults:{width:100,inputType:"password",labelStyle:"padding-left: 5px",
-height:20,labelSeparator:""}});this.oldPassword=b.add({name:"old_password",fieldLabel:_("Old:")});this.newPassword=b.add({name:"new_password",fieldLabel:_("New:")});this.confirmPassword=b.add({name:"confirm_password",fieldLabel:_("Confirm:")});b=this.add({xtype:"fieldset",border:!1,title:_("Server"),style:"padding-top: 5px; margin-bottom: 0px; padding-bottom: 5px",autoHeight:!0,labelWidth:100,defaultType:"spinnerfield",defaults:{labelSeparator:"",labelStyle:"padding-left: 5px",height:20,width:80}});
-a.bind("session_timeout",b.add({name:"session_timeout",fieldLabel:_("Session Timeout:"),decimalPrecision:0,minValue:-1,maxValue:99999}));a.bind("port",b.add({name:"port",fieldLabel:_("Port:"),decimalPrecision:0,minValue:1,maxValue:65535}));this.httpsField=a.bind("https",b.add({xtype:"checkbox",name:"https",hideLabel:!0,width:300,style:"margin-left: 5px",boxLabel:_("Enable SSL (paths relative to Deluge config folder)")}));this.httpsField.on("check",this.onSSLCheck,this);this.pkeyField=a.bind("pkey",
-b.add({xtype:"textfield",disabled:!0,name:"pkey",width:180,fieldLabel:_("Private Key:")}));this.certField=a.bind("cert",b.add({xtype:"textfield",disabled:!0,name:"cert",width:180,fieldLabel:_("Certificate:")}))},onApply:function(){var a=this.optionsManager.getDirty();if(!Ext.isObjectEmpty(a)){deluge.client.web.set_config(a,{success:this.onSetConfig,scope:this});for(var b in deluge.config)deluge.config[b]=this.optionsManager.get(b);"language"in a&&Ext.Msg.show({title:_("WebUI Language Changed"),msg:_("Do you want to refresh the page now to use the new language?"),
-buttons:{yes:_("Refresh"),no:_("Close")},multiline:!1,fn:function(a){"yes"===a&&location.reload()},icon:Ext.MessageBox.QUESTION})}if(this.oldPassword.getValue()||this.newPassword.getValue())this.onPasswordChange()},onOk:function(){this.onApply()},onGotConfig:function(a){this.optionsManager.set(a)},onGotLanguages:function(a,b,c,d){a.unshift(["",_("System Default")]);this.language.store.loadData(a);this.language.setValue(this.optionsManager.get("language"))},onPasswordChange:function(){var a=this.newPassword.getValue();
-if(a!=this.confirmPassword.getValue())Ext.MessageBox.show({title:_("Invalid Password"),msg:_("Your passwords don't match!"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});else{var b=this.oldPassword.getValue();deluge.client.auth.change_password(b,a,{success:function(a){a?(Ext.MessageBox.show({title:_("Change Successful"),msg:_("Your password was successfully changed!"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.INFO,iconCls:"x-deluge-icon-info"}),
-this.oldPassword.setValue(""),this.newPassword.setValue(""),this.confirmPassword.setValue("")):(Ext.MessageBox.show({title:_("Password"),msg:_("Your old password was incorrect!"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"}),this.oldPassword.setValue(""))},scope:this})}},onSetConfig:function(){this.optionsManager.commit()},onPageShow:function(){deluge.client.web.get_config({success:this.onGotConfig,scope:this});deluge.client.webutils.get_languages({success:this.onGotLanguages,
-scope:this})},onSSLCheck:function(a,b){this.pkeyField.setDisabled(!b);this.certField.setDisabled(!b)}});Ext.namespace("Deluge.preferences");Ext.apply(Ext.form.VTypes,{IPAddress:function(a){return/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(a)},IPAddressText:"Must be a numeric IP address",IPAddressMask:/[\d\.]/i});
-Deluge.preferences.Network=Ext.extend(Ext.form.FormPanel,{border:!1,layout:"form",title:_("Network"),header:!1,initComponent:function(){Deluge.preferences.Network.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Incoming Address"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:!0,labelWidth:1,defaultType:"textfield"});a.bind("listen_interface",b.add({name:"listen_interface",fieldLabel:"",labelSeparator:"",
-width:200,vtype:"IPAddress"}));var b=this.add({xtype:"fieldset",border:!1,title:_("Incoming Port"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("random_port",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Use Random Port"),name:"random_port",height:22,listeners:{check:{fn:function(a,b){this.listenPort.setDisabled(b)},scope:this}}}));this.listenPort=b.add({xtype:"spinnerfield",name:"listen_port",fieldLabel:"",labelSeparator:"",width:75,
-strategy:{xtype:"number",decimalPrecision:0,minValue:0,maxValue:65535}});a.bind("listen_ports",this.listenPort);b=this.add({xtype:"fieldset",border:!1,title:_("Outgoing Interface"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:!0,labelWidth:1,defaultType:"textfield"});a.bind("outgoing_interface",b.add({name:"outgoing_interface",fieldLabel:"",labelSeparator:"",width:40}));b=this.add({xtype:"fieldset",border:!1,title:_("Outgoing Ports"),style:"margin-bottom: 5px; padding-bottom: 0px;",
-autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("random_outgoing_ports",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Use Random Ports"),name:"random_outgoing_ports",height:22,listeners:{check:{fn:function(a,b){this.outgoingPorts.setDisabled(b)},scope:this}}}));this.outgoingPorts=b.add({xtype:"spinnergroup",name:"outgoing_ports",fieldLabel:"",labelSeparator:"",colCfg:{labelWidth:40,style:"margin-right: 10px;"},items:[{fieldLabel:_("From:"),labelSeparator:"",strategy:{xtype:"number",
-decimalPrecision:0,minValue:0,maxValue:65535}},{fieldLabel:_("To:"),labelSeparator:"",strategy:{xtype:"number",decimalPrecision:0,minValue:0,maxValue:65535}}]});a.bind("outgoing_ports",this.outgoingPorts);b=this.add({xtype:"fieldset",border:!1,title:_("Network Extras"),autoHeight:!0,layout:"table",layoutConfig:{columns:3},defaultType:"checkbox"});a.bind("upnp",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("UPnP"),name:"upnp"}));a.bind("natpmp",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("NAT-PMP"),
-ctCls:"x-deluge-indent-checkbox",name:"natpmp"}));a.bind("utpex",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Peer Exchange"),ctCls:"x-deluge-indent-checkbox",name:"utpex"}));a.bind("lsd",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("LSD"),name:"lsd"}));a.bind("dht",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("DHT"),ctCls:"x-deluge-indent-checkbox",name:"dht"}));b=this.add({xtype:"fieldset",border:!1,title:_("Type Of Service"),style:"margin-bottom: 5px; padding-bottom: 0px;",bodyStyle:"margin: 0px; padding: 0px",
-autoHeight:!0,defaultType:"textfield"});a.bind("peer_tos",b.add({name:"peer_tos",fieldLabel:_("Peer TOS Byte:"),labelSeparator:"",width:40}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Other=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Other"),header:!1,layout:"form"},a);Deluge.preferences.Other.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Other.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Updates"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("new_release_check",b.add({fieldLabel:"",labelSeparator:"",
-height:22,name:"new_release_check",boxLabel:_("Be alerted about new releases")}));b=this.add({xtype:"fieldset",border:!1,title:_("System Information"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});b.add({xtype:"panel",border:!1,bodyCfg:{html:_("Help us improve Deluge by sending us your Python version, PyGTK version, OS and processor types. Absolutely no other information is sent.")}});a.bind("send_info",b.add({fieldLabel:"",labelSeparator:"",height:22,boxLabel:_("Yes, please send anonymous statistics"),
-name:"send_info"}));b=this.add({xtype:"fieldset",border:!1,title:_("GeoIP Database"),autoHeight:!0,labelWidth:80,defaultType:"textfield"});a.bind("geoip_db_location",b.add({name:"geoip_db_location",fieldLabel:_("Path:"),labelSeparator:"",width:200}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Plugins=Ext.extend(Ext.Panel,{layout:"border",title:_("Plugins"),header:!1,border:!1,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 style="white-space:normal">{details}</dd></dl>'),initComponent:function(){Deluge.preferences.Plugins.superclass.initComponent.call(this);
-this.defaultValues={version:"",email:"",homepage:"",details:""};this.pluginTemplate.compile();this.list=this.add({xtype:"listview",store:new Ext.data.ArrayStore({fields:[{name:"enabled",mapping:0},{name:"plugin",mapping:1,sortType:"asUCString"}]}),columns:[{id:"enabled",header:_("Enabled"),width:0.2,sortable:!0,tpl:new Ext.XTemplate("{enabled:this.getCheckbox}",{getCheckbox:function(a){return'<div class="x-grid3-check-col'+(a?"-on":"")+'" rel="chkbox"> </div>'}}),dataIndex:"enabled"},{id:"plugin",
-header:_("Plugin"),width:0.8,sortable:!0,dataIndex:"plugin"}],singleSelect:!0,autoExpandColumn:"plugin",listeners:{selectionchange:{fn:this.onPluginSelect,scope:this}}});this.panel=this.add({region:"center",autoScroll:!0,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.pluginInfo=this.add({xtype:"panel",border:!1,height:100,region:"south",padding:"5",autoScroll:!0,bodyCfg:{style:"white-space: nowrap"}});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(a){deluge.client.core.disable_plugin(a)},enablePlugin:function(a){deluge.client.core.enable_plugin(a)},
-setInfo:function(a){this.pluginInfo.rendered&&(this.pluginInfo.body.dom.innerHTML=this.pluginTemplate.apply(a||this.defaultValues))},updatePlugins:function(){var a=function(a){this.enabledPlugins=a;this.onGotPlugins()};deluge.client.core.get_available_plugins({success:function(b){this.availablePlugins=b.sort(function(a,b){return a.toLowerCase().localeCompare(b.toLowerCase())});deluge.client.core.get_enabled_plugins({success:a,scope:this})},scope:this})},updatePluginsGrid:function(){var a=[];Ext.each(this.availablePlugins,
-function(b){-1<this.enabledPlugins.indexOf(b)?a.push([!0,b]):a.push([!1,b])},this);this.list.getStore().loadData(a)},onNodeClick:function(a,b,c,d){"chkbox"==(new Ext.Element(d.target)).getAttribute("rel")&&(a=a.getStore().getAt(b),"WebUi"!=a.get("plugin")&&(a.set("enabled",!a.get("enabled")),a.commit(),a.get("enabled")?this.enablePlugin(a.get("plugin")):this.disablePlugin(a.get("plugin"))))},onFindMorePlugins:function(){window.open("http://dev.deluge-torrent.org/wiki/Plugins")},onGotPlugins:function(){this.setInfo();
-this.updatePluginsGrid()},onGotPluginInfo:function(a){this.setInfo({author:a.Author,version:a.Version,email:a["Author-email"],homepage:a["Home-page"],details:a.Description});delete a},onInstallPluginWindow:function(){this.installWindow||(this.installWindow=new Deluge.preferences.InstallPluginWindow,this.installWindow.on("pluginadded",this.onPluginInstall,this));this.installWindow.show()},onPluginEnabled:function(a){a=this.list.getStore().find("plugin",a);-1!=a&&(a=this.list.getStore().getAt(a),a.set("enabled",
-!0),a.commit())},onPluginDisabled:function(a){a=this.list.getStore().find("plugin",a);-1!=a&&(a=this.list.getStore().getAt(a),a.set("enabled",!1),a.commit())},onPluginInstall:function(){this.updatePlugins()},onPluginSelect:function(a,b){if(0!=b.length){var c=a.getRecords(b)[0];deluge.client.web.get_plugin_info(c.get("plugin"),{success:this.onGotPluginInfo,scope:this})}},onPreferencesShow:function(){this.updatePlugins()},onPluginInfoRender:function(a,b){this.setInfo()}});Ext.namespace("Deluge.preferences");
-PreferencesRecord=Ext.data.Record.create([{name:"name",type:"string"}]);
-Deluge.preferences.PreferencesWindow=Ext.extend(Ext.Window,{currentPage:null,title:_("Preferences"),layout:"border",width:485,height:500,border:!1,constrainHeader:!0,buttonAlign:"right",closeAction:"hide",closable:!0,iconCls:"x-deluge-preferences",plain:!0,resizable:!1,pages:{},initComponent:function(){Deluge.preferences.PreferencesWindow.superclass.initComponent.call(this);this.list=new Ext.list.ListView({store:new Ext.data.Store,columns:[{id:"name",dataIndex:"name"}],singleSelect:!0,listeners:{selectionchange:{fn:this.onPageSelect,
-scope:this}},hideHeaders:!0,autoExpandColumn:"name",deferredRender:!1,autoScroll:!0,collapsible:!0});this.add({region:"west",items:[this.list],width:120,margins:"0 5 0 0",cmargins:"0 5 0 0"});this.configPanel=this.add({type:"container",autoDestroy:!1,region:"center",layout:"card",layoutConfig:{deferredRender:!0},autoScroll:!0,width:300});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()},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(a){a=this.optionsManager.getDirty();Ext.isObjectEmpty(a)||("listen_ports"in a&&(a.listen_ports=[a.listen_ports,a.listen_ports]),deluge.client.core.set_config(a,{success:this.onSetConfig,scope:this}));for(var b in this.pages)if(this.pages[b].onApply)this.pages[b].onApply()},getOptionsManager:function(){return this.optionsManager},addPage:function(a){var b=
-this.list.getStore(),c=a.title;b.add([new PreferencesRecord({name:c})]);a.bodyStyle="padding: 5px";a.preferences=this;this.pages[c]=this.configPanel.add(a);this.pages[c].index=-1;return this.pages[c]},removePage:function(a){var b=a.title,c=this.list.getStore();c.removeAt(c.find("name",b));this.configPanel.remove(a);delete this.pages[a.title]},selectPage:function(a){0>this.pages[a].index&&(this.pages[a].index=this.configPanel.items.indexOf(this.pages[a]));this.list.select(this.pages[a].index)},doSelectPage:function(a){0>
-this.pages[a].index&&(this.pages[a].index=this.configPanel.items.indexOf(this.pages[a]));this.configPanel.getLayout().setActiveItem(this.pages[a].index);this.currentPage=a},onGotConfig:function(a){this.getOptionsManager().set(a)},onPageSelect:function(a,b){var c=a.getRecord(b[0]);this.doSelectPage(c.get("name"))},onSetConfig:function(){this.getOptionsManager().commit()},onAfterRender:function(){this.list.getSelectionCount()||this.list.select(0);this.configPanel.getLayout().setActiveItem(0)},onShow:function(){deluge.client.core&&
-deluge.client.core.get_config({success:this.onGotConfig,scope:this})},onClose:function(){this.hide()},onOk:function(){var a=this.optionsManager.getDirty();Ext.isObjectEmpty(a)||deluge.client.core.set_config(a,{success:this.onSetConfig,scope:this});for(var b in this.pages)if(this.pages[b].onOk)this.pages[b].onOk();this.hide()}});Ext.ns("Deluge.preferences");
-Deluge.preferences.ProxyField=Ext.extend(Ext.form.FieldSet,{border:!1,autoHeight:!0,labelWidth:70,initComponent:function(){Deluge.preferences.ProxyField.superclass.initComponent.call(this);this.proxyType=this.add({xtype:"combo",fieldLabel:_("Type:"),labelSeparator:"",name:"proxytype",mode:"local",width:150,store:new Ext.data.ArrayStore({fields:["id","text"],data:[[0,_("None")],[1,_("Socks4")],[2,_("Socks5")],[3,_("Socks5 Auth")],[4,_("HTTP")],[5,_("HTTP Auth")],[6,_("I2P")]]}),editable:!1,triggerAction:"all",
-valueField:"id",displayField:"text"});this.proxyType.on("change",this.onFieldChange,this);this.proxyType.on("select",this.onTypeSelect,this);this.hostname=this.add({xtype:"textfield",name:"hostname",fieldLabel:_("Host:"),labelSeparator:"",width:220});this.hostname.on("change",this.onFieldChange,this);this.port=this.add({xtype:"spinnerfield",name:"port",fieldLabel:_("Port:"),labelSeparator:"",width:80,decimalPrecision:0,minValue:0,maxValue:65535});this.port.on("change",this.onFieldChange,this);this.username=
-this.add({xtype:"textfield",name:"username",fieldLabel:_("Username:"),labelSeparator:"",width:220});this.username.on("change",this.onFieldChange,this);this.password=this.add({xtype:"textfield",name:"password",fieldLabel:_("Password:"),labelSeparator:"",inputType:"password",width:220});this.password.on("change",this.onFieldChange,this);this.proxy_host_resolve=this.add({xtype:"checkbox",name:"proxy_host_resolve",fieldLabel:"",boxLabel:_("Proxy Hostnames"),width:220});this.proxy_host_resolve.on("change",
-this.onFieldChange,this);this.proxy_peer_conn=this.add({xtype:"checkbox",name:"proxy_peer_conn",fieldLabel:"",boxLabel:_("Proxy Peers"),width:220});this.proxy_peer_conn.on("change",this.onFieldChange,this);this.proxy_tracker_conn=this.add({xtype:"checkbox",name:"proxy_tracker_conn",fieldLabel:"",boxLabel:_("Proxy Trackers"),width:220});this.proxy_tracker_conn.on("change",this.onFieldChange,this);var a=this.add({xtype:"fieldset",border:!1,title:_("Force Proxy"),autoHeight:!0,labelWidth:1,defaultType:"checkbox",
-style:"padding-left: 0px; margin-top: 10px"});this.force_proxy=a.add({fieldLabel:"",labelSeparator:"",height:20,name:"force_proxy",boxLabel:_("Force Use of Proxy")});this.force_proxy.on("change",this.onFieldChange,this);this.anonymous_mode=a.add({fieldLabel:"",labelSeparator:"",height:20,name:"anonymous_mode",boxLabel:_("Hide Client Identity")});this.anonymous_mode.on("change",this.onFieldChange,this);this.setting=!1},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(),proxy_hostnames:this.proxy_host_resolve.getValue(),proxy_peer_connections:this.proxy_peer_conn.getValue(),proxy_tracker_connections:this.proxy_tracker_conn.getValue(),force_proxy:this.force_proxy.getValue(),anonymous_mode:this.anonymous_mode.getValue()}},setValue:function(a){this.setting=!0;this.proxyType.setValue(a.type);var b=this.proxyType.getStore().find("id",
-a.type),c=this.proxyType.getStore().getAt(b);this.hostname.setValue(a.hostname);this.port.setValue(a.port);this.username.setValue(a.username);this.password.setValue(a.password);this.proxy_host_resolve.setValue(a.proxy_hostnames);this.proxy_peer_conn.setValue(a.proxy_peer_connections);this.proxy_tracker_conn.setValue(a.proxy_tracker_connections);this.force_proxy.setValue(a.force_proxy);this.anonymous_mode.setValue(a.anonymous_mode);this.onTypeSelect(this.type,c,b);this.setting=!1},onFieldChange:function(a,
-b,c){if(!this.setting){b=this.getValue();var d=Ext.apply({},b);d[a.getName()]=c;this.fireEvent("change",this,b,d)}},onTypeSelect:function(a,b,c){a=b.get("id");0<a?(this.hostname.show(),this.port.show(),this.proxy_peer_conn.show(),this.proxy_tracker_conn.show(),1<a&&6>a?this.proxy_host_resolve.show():this.proxy_host_resolve.hide()):(this.hostname.hide(),this.port.hide(),this.proxy_host_resolve.hide(),this.proxy_peer_conn.hide(),this.proxy_tracker_conn.hide());3==a||5==a?(this.username.show(),this.password.show()):
-(this.username.hide(),this.password.hide())}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Proxy=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Proxy"),header:!1,layout:"form",autoScroll:!0},a);Deluge.preferences.Proxy.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Proxy.superclass.initComponent.call(this);this.proxy=this.add(new Deluge.preferences.ProxyField({title:_("Proxy"),name:"proxy"}));this.proxy.on("change",this.onProxyChange,this);deluge.preferences.getOptionsManager().bind("proxy",this.proxy)},
-getValue:function(){return{proxy:this.proxy.getValue()}},setValue:function(a){for(var b in a)this[b].setValue(a[b])},onProxyChange:function(a,b,c){b=this.getValue();var d=Ext.apply({},b);d[a.getName()]=c;this.fireEvent("change",this,b,d)}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Queue=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Queue"),header:!1,layout:"form",initComponent:function(){Deluge.preferences.Queue.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("New Torrents"),style:"padding-top: 5px; margin-bottom: 0px;",autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("queue_new_to_top",b.add({fieldLabel:"",labelSeparator:"",height:22,boxLabel:_("Queue to top"),
-name:"queue_new_to_top"}));b=this.add({xtype:"fieldset",border:!1,title:_("Active Torrents"),autoHeight:!0,labelWidth:150,defaultType:"spinnerfield",style:"padding-top: 5px; margin-bottom: 0px"});a.bind("max_active_limit",b.add({fieldLabel:_("Total:"),labelSeparator:"",name:"max_active_limit",value:8,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));a.bind("max_active_downloading",b.add({fieldLabel:_("Downloading:"),labelSeparator:"",name:"max_active_downloading",value:3,width:80,decimalPrecision:0,
-minValue:-1,maxValue:99999}));a.bind("max_active_seeding",b.add({fieldLabel:_("Seeding:"),labelSeparator:"",name:"max_active_seeding",value:5,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));a.bind("dont_count_slow_torrents",b.add({xtype:"checkbox",name:"dont_count_slow_torrents",height:22,hideLabel:!0,boxLabel:_("Ignore slow torrents")}));a.bind("auto_manage_prefer_seeds",b.add({xtype:"checkbox",name:"auto_manage_prefer_seeds",hideLabel:!0,boxLabel:_("Prefer seeding torrents")}));b=this.add({xtype:"fieldset",
-border:!1,title:_("Seeding Rotation"),autoHeight:!0,labelWidth:150,defaultType:"spinnerfield",style:"padding-top: 5px; margin-bottom: 0px"});a.bind("share_ratio_limit",b.add({fieldLabel:_("Share Ratio:"),labelSeparator:"",name:"share_ratio_limit",value:8,width:80,incrementValue:0.1,minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2}));a.bind("seed_time_ratio_limit",b.add({fieldLabel:_("Time Ratio:"),labelSeparator:"",name:"seed_time_ratio_limit",value:3,width:80,incrementValue:0.1,
-minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2}));a.bind("seed_time_limit",b.add({fieldLabel:_("Time (m):"),labelSeparator:"",name:"seed_time_limit",value:5,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));b=this.add({xtype:"fieldset",border:!1,autoHeight:!0,style:"padding-top: 5px; margin-bottom: 0px",title:_("Share Ratio Reached"),layout:"table",layoutConfig:{columns:2},labelWidth:0,defaultType:"checkbox",defaults:{fieldLabel:"",labelSeparator:""}});this.stopAtRatio=
-b.add({name:"stop_seed_at_ratio",boxLabel:_("Share Ratio:")});this.stopAtRatio.on("check",this.onStopRatioCheck,this);a.bind("stop_seed_at_ratio",this.stopAtRatio);this.stopRatio=b.add({xtype:"spinnerfield",name:"stop_seed_ratio",ctCls:"x-deluge-indent-checkbox",disabled:!0,value:"2.0",width:60,incrementValue:0.1,minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2});a.bind("stop_seed_ratio",this.stopRatio);this.removeAtRatio=b.add({xtype:"radiogroup",columns:1,colspan:2,disabled:!0,
-style:"margin-left: 10px",items:[{boxLabel:_("Pause torrent"),name:"at_ratio",inputValue:!1,checked:!0},{boxLabel:_("Remove torrent"),name:"at_ratio",inputValue:!0}]});a.bind("remove_seed_at_ratio",this.removeAtRatio)},onStopRatioCheck:function(a,b){this.stopRatio.setDisabled(!b);this.removeAtRatio.setDisabled(!b)}});Ext.ns("Deluge");
-Deluge.StatusbarMenu=Ext.extend(Ext.menu.Menu,{initComponent:function(){Deluge.StatusbarMenu.superclass.initComponent.call(this);this.otherWin=new Deluge.OtherLimitWindow(this.initialConfig.otherWin||{});this.items.each(function(a){if("menucheckitem"==a.getXType())if("other"==a.value)a.on("click",this.onOtherClicked,this);else a.on("checkchange",this.onLimitChanged,this)},this)},setValue:function(a){var b=!1;this.value=a=0==a?-1:a;var c=null;this.items.each(function(d){d.setChecked&&(d.suspendEvents(),
-d.value==a?(d.setChecked(!0),b=!0):d.setChecked(!1),d.resumeEvents());"other"==d.value&&(c=d)});b||(c.suspendEvents(),c.setChecked(!0),c.resumeEvents())},onLimitChanged:function(a,b){if(b&&"other"!=a.value){var c={};c[a.group]=a.value;deluge.client.core.set_config(c,{success:function(){deluge.ui.update()}})}},onOtherClicked:function(a,b){this.otherWin.group=a.group;this.otherWin.setValue(this.value);this.otherWin.show()}});Ext.namespace("Deluge");
-Deluge.OptionsManager=Ext.extend(Ext.util.Observable,{constructor:function(a){a=a||{};this.binds={};this.changed={};this.options=a&&a.options||{};this.focused=null;this.addEvents({add:!0,changed:!0,reset:!0});this.on("changed",this.onChange,this);Deluge.OptionsManager.superclass.constructor.call(this)},addOptions:function(a){this.options=Ext.applyIf(this.options,a)},bind:function(a,b){this.binds[a]=this.binds[a]||[];this.binds[a].push(b);b._doption=a;b.on("focus",this.onFieldFocus,this);b.on("blur",
-this.onFieldBlur,this);b.on("change",this.onFieldChange,this);b.on("check",this.onFieldChange,this);b.on("spin",this.onFieldChange,this);return b},commit:function(){this.options=Ext.apply(this.options,this.changed);this.reset()},convertValueType:function(a,b){if(Ext.type(a)!=Ext.type(b))switch(Ext.type(a)){case "string":b=String(b);break;case "number":b=Number(b);break;case "boolean":"string"==Ext.type(b)?(b=b.toLowerCase(),b="true"==b||"1"==b||"on"==b?!0:!1):b=Boolean(b)}return b},get:function(){if(1==
-arguments.length){var a=arguments[0];return this.isDirty(a)?this.changed[a]:this.options[a]}var b={};Ext.each(arguments,function(a){this.has(a)&&(b[a]=this.isDirty(a)?this.changed[a]:this.options[a])},this);return b},getDefault:function(a){return this.options[a]},getDirty:function(){return this.changed},isDirty:function(a){return!Ext.isEmpty(this.changed[a])},has:function(a){return this.options[a]},reset:function(){this.changed={}},set:function(a,b){if(void 0!==a)if("object"==typeof a){var c=a;this.options=
-Ext.apply(this.options,c);for(a in c)this.onChange(a,c[a])}else this.options[a]=b,this.onChange(a,b)},update:function(a,b){if(void 0!==a)if(void 0===b)for(var c in a)this.update(c,a[c]);else{c=this.getDefault(a);b=this.convertValueType(c,b);var d=this.get(a);d!=b&&(c==b?this.isDirty(a)&&delete this.changed[a]:this.changed[a]=b,this.fireEvent("changed",a,b,d))}},onFieldBlur:function(a,b){this.focused==a&&(this.focused=null)},onFieldChange:function(a,b){a.field&&(a=a.field);this.update(a._doption,a.getValue())},
-onFieldFocus:function(a,b){this.focused=a},onChange:function(a,b,c){Ext.isEmpty(this.binds[a])||Ext.each(this.binds[a],function(a){a!=this.focused&&a.setValue(b)},this)}});Ext.namespace("Deluge.about");
-Deluge.about.AboutWindow=Ext.extend(Ext.Window,{id:"AboutWindow",title:_("About Deluge"),height:330,width:270,iconCls:"x-deluge-main-panel",resizable:!1,plain:!0,layout:{type:"vbox",align:"center"},buttonAlign:"center",initComponent:function(){Deluge.about.AboutWindow.superclass.initComponent.call(this);this.addEvents({build_ready:!0});var a=this,b=function(){deluge.client.core.get_libtorrent_version({success:function(b){d+="<br/>"+_("libtorrent:")+" "+b;Ext.getCmp("about_comment").setText(d,!1);
-a.fireEvent("build_ready")}})},c=deluge.version,d=_("A peer-to-peer file sharing program\nutilizing the BitTorrent protocol.").replace("\n","<br/>")+"<br/><br/>"+_("Client:")+" "+c+"<br/>";deluge.client.web.connected({success:function(a){a?deluge.client.daemon.get_version({success:function(a){d+=_("Server:")+" "+a+"<br/>";b()}}):this.fireEvent("build_ready")},failure:function(){this.fireEvent("build_ready")},scope:this});this.add([{xtype:"box",style:"padding-top: 5px",height:80,width:240,cls:"x-deluge-logo",
-hideLabel:!0},{xtype:"label",style:"padding-top: 10px; font-weight: bold; font-size: 16px;",text:_("Deluge")+" "+c},{xtype:"label",id:"about_comment",style:"padding-top: 10px; text-align:center; font-size: 12px;",html:d},{xtype:"label",style:"padding-top: 10px; font-size: 10px;",text:_("Copyright 2007-2018 Deluge Team")},{xtype:"label",style:"padding-top: 5px; font-size: 12px;",html:'<a href="https://deluge-torrent.org" target="_blank">deluge-torrent.org</a>'}]);this.addButton(_("Close"),this.onCloseClick,
-this)},show:function(){this.on("build_ready",function(){Deluge.about.AboutWindow.superclass.show.call(this)})},onCloseClick:function(){this.close()}});Ext.namespace("Deluge");Deluge.About=function(){(new Deluge.about.AboutWindow).show()};Ext.ns("Deluge");
-Deluge.AddConnectionWindow=Ext.extend(Ext.Window,{title:_("Add Connection"),iconCls:"x-deluge-add-window-icon",layout:"fit",width:300,height:195,constrainHeader:!0,bodyStyle:"padding: 10px 5px;",closeAction:"hide",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:"),labelSeparator:"",name:"host",anchor:"75%",value:""},{xtype:"spinnerfield",fieldLabel:_("Port:"),labelSeparator:"",name:"port",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:65535},value:"58846",anchor:"40%"},{fieldLabel:_("Username:"),labelSeparator:"",name:"username",anchor:"75%",value:""},{fieldLabel:_("Password:"),labelSeparator:"",anchor:"75%",name:"password",inputType:"password",value:""}]})},onAddClick:function(){var a=
-this.form.getForm().getValues();deluge.client.web.add_host(a.host,Number(a.port),a.username,a.password,{success:function(a){a[0]?this.fireEvent("hostadded"):Ext.MessageBox.show({title:_("Error"),msg:String.format(_("Unable to add host: {0}"),a[1]),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.hide()},scope:this})},onHide:function(){this.form.getForm().reset()}});Ext.ns("Deluge");var trackerUrlTest=/(((^https?)|(^udp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
-Ext.apply(Ext.form.VTypes,{trackerUrl:function(a,b){return trackerUrlTest.test(a)},trackerUrlText:"Not a valid tracker url"});
-Deluge.AddTrackerWindow=Ext.extend(Ext.Window,{title:_("Add Tracker"),layout:"fit",width:375,height:150,plain:!0,closable:!0,resizable:!1,constrainHeader:!0,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:"),labelSeparator:"",name:"trackers",anchor:"100%"}]})},onAddClick:function(){var a=this.form.getForm().findField("trackers").getValue(),a=a.split("\n"),b=[];Ext.each(a,function(a){Ext.form.VTypes.trackerUrl(a)&&b.push(a)},this);this.fireEvent("add",b);this.hide();this.form.getForm().findField("trackers").setValue("")},onCancelClick:function(){this.form.getForm().findField("trackers").setValue("");this.hide()}});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(a){Ext.ux.util.RpcClient.superclass.constructor.call(this,a);this._url=a.url||null;this._id=0;this.addEvents("connected","error");this.reloadMethods()},reloadMethods:function(){this._execute("system.listMethods",{success:this._setMethods,scope:this})},_execute:function(a,b){b=b||{};b.params=b.params||[];b.id=this._id;var c=Ext.encode({method:a,
-params:b.params,id:b.id});this._id++;return Ext.Ajax.request({url:this._url,method:"POST",success:this._onSuccess,failure:this._onFailure,scope:this,jsonData:c,options:b})},_onFailure:function(a,b){var c=b.options;errorObj={id:c.id,result:null,error:{msg:"HTTP: "+a.status+" "+a.statusText,code:255}};this.fireEvent("error",errorObj,a,b);"function"==Ext.type(c.failure)&&(c.scope?c.failure.call(c.scope,errorObj,a,b):c.failure(errorObj,a,b))},_onSuccess:function(a,b){var c=Ext.decode(a.responseText),
-d=b.options;c.error?(this.fireEvent("error",c,a,b),"function"==Ext.type(d.failure)&&(d.scope?d.failure.call(d.scope,c,a,b):d.failure(c,a,b))):"function"==Ext.type(d.success)&&(d.scope?d.success.call(d.scope,c.result,c,a,b):d.success(c.result,c,a,b))},_parseArgs:function(a){var b=[];Ext.each(a,function(a){b.push(a)});a=b[b.length-1];if("object"==Ext.type(a)){var c=Ext.keys(a),d=!1;Ext.each(this._optionKeys,function(a){-1<c.indexOf(a)&&(d=!0)});d?b.remove(a):a={}}else a={};a.params=b;return a},_setMethods:function(a){var b=
-{},c=this;Ext.each(a,function(a){var d=a.split("."),e=b[d[0]]||{};e[d[1]]=function(){var b=c._parseArgs(arguments);return c._execute(a,b)};b[d[0]]=e});for(var d in b)c[d]=b[d];Ext.each(this._components,function(a){!a in b&&delete this[a]},this);this._components=Ext.keys(b);this.fireEvent("connected",this)}});
-Deluge.ConnectionManager=Ext.extend(Ext.Window,{layout:"fit",width:300,height:220,bodyStyle:"padding: 10px 5px;",buttonAlign:"right",closeAction:"hide",closable:!0,plain:!0,constrainHeader:!0,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);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.list=new Ext.list.ListView({store:new Ext.data.ArrayStore({fields:[{name:"status",mapping:4},{name:"host",mapping:1},{name:"port",mapping:2},{name:"user",mapping:3},{name:"version",mapping:5}],id:0}),columns:[{header:_("Status"),width:0.24,sortable:!0,tpl:new Ext.XTemplate("<tpl if=\"status == 'Online'\">",_("Online"),"</tpl>","<tpl if=\"status == 'Offline'\">",_("Offline"),"</tpl>","<tpl if=\"status == 'Connected'\">",
-_("Connected"),"</tpl>"),dataIndex:"status"},{id:"host",header:_("Host"),width:0.51,sortable:!0,tpl:"{user}@{host}:{port}",dataIndex:"host"},{header:_("Version"),width:0.25,sortable:!0,tpl:'<tpl if="version">{version}</tpl>',dataIndex:"version"}],singleSelect:!0,listeners:{selectionchange:{fn:this.onSelectionChanged,scope:this}}});this.panel=this.add({autoScroll:!0,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-edit",cls:"x-btn-text-icon",text:_("Edit"),iconCls:"icon-edit",handler:this.onEditClick,scope:this},{id:"cm-remove",cls:"x-btn-text-icon",text:_("Remove"),iconCls:"icon-remove",handler:this.onRemoveClick,disabled:!0,scope:this},"->",{id:"cm-stop",cls:"x-btn-text-icon",text:_("Stop Daemon"),iconCls:"icon-error",handler:this.onStopClick,disabled:!0,scope:this}]})});this.update=this.update.createDelegate(this)},checkConnected:function(){deluge.client.web.connected({success:function(a){a?
-deluge.events.fire("connect"):this.show()},scope:this})},disconnect:function(a){deluge.events.fire("disconnect");a&&!this.isVisible()&&this.show()},loadHosts:function(){deluge.client.web.get_hosts({success:this.onGetHosts,scope:this})},update:function(){this.list.getStore().each(function(a){deluge.client.web.get_host_status(a.id,{success:this.onGetHostStatus,scope:this})},this)},updateButtons:function(a){var b=this.buttons[1],c=a.get("status");b.enable();"connected"==c.toLowerCase()?b.setText(_("Disconnect")):
-(b.setText(_("Connect")),"online"!=c.toLowerCase()&&b.disable());"connected"==c.toLowerCase()||"online"==c.toLowerCase()?(this.stopHostButton.enable(),this.stopHostButton.setText(_("Stop Daemon"))):"127.0.0.1"==a.get("host")||"localhost"==a.get("host")?(this.stopHostButton.enable(),this.stopHostButton.setText(_("Start Daemon"))):this.stopHostButton.disable()},onAddClick:function(a,b){this.addWindow||(this.addWindow=new Deluge.AddConnectionWindow,this.addWindow.on("hostadded",this.onHostChange,this));
-this.addWindow.show()},onEditClick:function(a,b){var c=this.list.getSelectedRecords()[0];c&&(this.editWindow||(this.editWindow=new Deluge.EditConnectionWindow,this.editWindow.on("hostedited",this.onHostChange,this)),this.editWindow.show(c))},onHostChange:function(){this.loadHosts()},onClose:function(a){this.hide()},onConnect:function(a){if(a=this.list.getSelectedRecords()[0]){var b=this,c=function(){deluge.client.web.disconnect({success:function(a){this.update(this);deluge.events.fire("disconnect")},
-scope:b})};"connected"==a.get("status").toLowerCase()?c():(-1<this.list.getStore().find("status","Connected",0,!1,!1)&&c(),deluge.client.web.connect(a.id,{success:function(a){deluge.client.reloadMethods();deluge.client.on("connected",function(a){deluge.events.fire("connect")},this,{single:!0})}}),this.hide())}},onGetHosts:function(a){this.list.getStore().loadData(a);Ext.each(a,function(a){deluge.client.web.get_host_status(a[0],{success:this.onGetHostStatus,scope:this})},this)},onGetHostStatus:function(a){var b=
-this.list.getStore().getById(a[0]);b.set("status",a[1]);b.set("version",a[2]);b.commit();(a=this.list.getSelectedRecords()[0])&&a==b&&this.updateButtons(b)},onHide:function(){this.running&&window.clearInterval(this.running)},onLogin:function(){deluge.config.first_login?Ext.MessageBox.confirm(_("Change Default Password"),_("We recommend changing the default password.<br><br>Would you like to change it now?"),function(a){this.checkConnected();"yes"==a&&(deluge.preferences.show(),deluge.preferences.selectPage("Interface"));
-deluge.client.web.set_config({first_login:!1})},this):this.checkConnected()},onLogout:function(){this.disconnect();!this.hidden&&this.rendered&&this.hide()},onRemoveClick:function(a){var b=this.list.getSelectedRecords()[0];b&&deluge.client.web.remove_host(b.id,{success:function(a){a?this.list.getStore().remove(b):Ext.MessageBox.show({title:_("Error"),msg:a[1],buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"})},scope:this})},onSelectionChanged:function(a,b){b[0]?
-(this.editHostButton.enable(),this.removeHostButton.enable(),this.stopHostButton.enable(),this.stopHostButton.setText(_("Stop Daemon")),this.updateButtons(this.list.getRecord(b[0]))):(this.editHostButton.disable(),this.removeHostButton.disable(),this.stopHostButton.disable())},onShow:function(){if(!this.addHostButton){var a=this.panel.getBottomToolbar();this.addHostButton=a.items.get("cm-add");this.editHostButton=a.items.get("cm-edit");this.removeHostButton=a.items.get("cm-remove");this.stopHostButton=
-a.items.get("cm-stop")}this.loadHosts();this.running||(this.running=window.setInterval(this.update,2E3,this))},onStopClick:function(a,b){var c=this.list.getSelectedRecords()[0];c&&("Offline"==c.get("status")?deluge.client.web.start_daemon(c.get("port")):deluge.client.web.stop_daemon(c.id,{success:function(a){a[0]||Ext.MessageBox.show({title:_("Error"),msg:a[1],buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"})}}))}});
-Deluge.CopyMagnet=Ext.extend(Ext.Window,{title:_("Copy Magnet URI"),width:375,closeAction:"hide",iconCls:"icon-magnet-copy",initComponent:function(){Deluge.CopyMagnet.superclass.initComponent.call(this);form=this.add({xtype:"form",defaultType:"textfield",hideLabels:!0});this.magnetURI=form.add({name:"URI",anchor:"100%"});this.addButton(_("Close"),this.onClose,this);this.addButton(_("Copy"),this.onCopy,this)},show:function(a){Deluge.CopyMagnet.superclass.show.call(this);a=deluge.torrents.getSelected();
-deluge.client.core.get_magnet_uri(a.id,{success:this.onRequestComplete,scope:this})},onRequestComplete:function(a){this.magnetURI.setValue(a)},onCopy:function(){this.magnetURI.focus();this.magnetURI.el.dom.select();document.execCommand("copy")},onClose:function(){this.hide()}});deluge.copyMagnetWindow=new Deluge.CopyMagnet;Ext.state.Manager.setProvider(new Ext.state.CookieProvider({expires:new Date((new Date).getTime()+31536E7)}));
-Ext.apply(Ext,{isObjectEmpty:function(a){for(var b in a)return!1;return!0},areObjectsEqual:function(a,b){var c=!0;if(!a||!b)return!1;for(var d in a)a[d]!=b[d]&&(c=!1);return c},keys:function(a){var b=[],c;for(c in a)a.hasOwnProperty(c)&&b.push(c);return b},values:function(a){var b=[],c;for(c in a)a.hasOwnProperty(c)&&b.push(a[c]);return b},splat:function(a){var b=Ext.type(a);return b?"array"!=b?[a]:a:[]}});Ext.getKeys=Ext.keys;Ext.BLANK_IMAGE_URL=deluge.config.base+"images/s.gif";
-Ext.USE_NATIVE_JSON=!0;
-Ext.apply(Deluge,{pluginStore:{},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>',progressBar:function(a,b,c,d){d=Ext.value(d,10);a=(b/100*a).toFixed(0);return String.format(Deluge.progressTpl,c,
-b,a-1,0<a-d?a-d:0)},createPlugin:function(a){return new Deluge.pluginStore[a]},hasPlugin:function(a){return Deluge.pluginStore[a]?!0:!1},registerPlugin:function(a,b){Deluge.pluginStore[a]=b}});deluge.plugins={};FILE_PRIORITY={"0":"Skip",1:"Low",2:"Low",3:"Low",4:"Normal",5:"High",6:"High",7:"High",9:"Mixed",Skip:0,Low:1,Normal:4,High:7,Mixed:9};
-FILE_PRIORITY_CSS={"0":"x-no-download",1:"x-low-download",2:"x-low-download",3:"x-low-download",4:"x-normal-download",5:"x-high-download",6:"x-high-download",7:"x-high-download",9:"x-mixed-download"};Ext.ns("Deluge");
-Deluge.EditConnectionWindow=Ext.extend(Ext.Window,{title:_("Edit Connection"),iconCls:"x-deluge-add-window-icon",layout:"fit",width:300,height:195,constrainHeader:!0,bodyStyle:"padding: 10px 5px;",closeAction:"hide",initComponent:function(){Deluge.EditConnectionWindow.superclass.initComponent.call(this);this.addEvents("hostedited");this.addButton(_("Close"),this.hide,this);this.addButton(_("Edit"),this.onEditClick,this);this.on("hide",this.onHide,this);this.form=this.add({xtype:"form",defaultType:"textfield",
-baseCls:"x-plain",labelWidth:60,items:[{fieldLabel:_("Host:"),labelSeparator:"",name:"host",anchor:"75%",value:""},{xtype:"spinnerfield",fieldLabel:_("Port:"),labelSeparator:"",name:"port",strategy:{xtype:"number",decimalPrecision:0,minValue:0,maxValue:65535},anchor:"40%",value:58846},{fieldLabel:_("Username:"),labelSeparator:"",name:"username",anchor:"75%",value:""},{fieldLabel:_("Password:"),labelSeparator:"",anchor:"75%",name:"password",inputType:"password",value:""}]})},show:function(a){Deluge.EditConnectionWindow.superclass.show.call(this);
-this.form.getForm().findField("host").setValue(a.get("host"));this.form.getForm().findField("port").setValue(a.get("port"));this.form.getForm().findField("username").setValue(a.get("user"));this.host_id=a.id},onEditClick:function(){var a=this.form.getForm().getValues();deluge.client.web.edit_host(this.host_id,a.host,Number(a.port),a.username,a.password,{success:function(a){a?this.fireEvent("hostedited"):(console.log(a),Ext.MessageBox.show({title:_("Error"),msg:String.format(_("Unable to edit host")),
-buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"}));this.hide()},scope:this})},onHide:function(){this.form.getForm().reset()}});Ext.ns("Deluge");
-Deluge.EditTrackerWindow=Ext.extend(Ext.Window,{title:_("Edit Tracker"),layout:"fit",width:375,height:110,plain:!0,closable:!0,resizable:!1,constrainHeader:!0,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:"),labelSeparator:"",name:"tracker",anchor:"100%"}]})},show:function(a){Deluge.EditTrackerWindow.superclass.show.call(this);this.record=a;this.form.getForm().findField("tracker").setValue(a.data.url)},onCancelClick:function(){this.hide()},onHide:function(){this.form.getForm().findField("tracker").setValue("")},onSaveClick:function(){var a=this.form.getForm().findField("tracker").getValue();this.record.set("url",
-a);this.record.commit();this.hide()}});Ext.ns("Deluge");
-Deluge.EditTrackersWindow=Ext.extend(Ext.Window,{title:_("Edit Trackers"),layout:"fit",width:350,height:220,plain:!0,closable:!0,resizable:!0,constrainHeader:!0,bodyStyle:"padding: 5px",buttonAlign:"right",closeAction:"hide",iconCls:"x-deluge-edit-trackers",initComponent:function(){Deluge.EditTrackersWindow.superclass.initComponent.call(this);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.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:0.1,dataIndex:"tier"},{header:_("Tracker"),width:0.9,dataIndex:"url",tpl:new Ext.XTemplate("{url:htmlEncode}")}],columnSort:{sortClasses:["",""]},stripeRows:!0,singleSelect:!0,listeners:{dblclick:{fn:this.onListNodeDblClicked,
-scope:this},selectionchange:{fn:this.onSelect,scope:this}}});this.panel=this.add({items:[this.list],autoScroll:!0,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()},onAddTrackers:function(a){var b=this.list.getStore();Ext.each(a,function(a){var d=!1,f=-1;b.each(function(b){b.get("tier")>f&&(f=b.get("tier"));if(a==b.get("tracker"))return d=!0,!1},this);d||b.add(new b.recordType({tier:f+1,url:a}))},this)},onCancelClick:function(){this.hide()},onEditClick:function(){var a=this.list.getSelectedRecords()[0];a&&this.editWindow.show(a)},onHide:function(){this.list.getStore().removeAll()},onListNodeDblClicked:function(a,
-b,c,d){this.editWindow.show(this.list.getRecord(c))},onOkClick:function(){var a=[];this.list.getStore().each(function(b){a.push({tier:b.get("tier"),url:b.get("url")})},this);deluge.client.core.set_torrent_trackers(this.torrentId,a,{failure:this.onSaveFail,scope:this});this.hide()},onRemoveClick:function(){var a=this.list.getSelectedRecords()[0];a&&this.list.getStore().remove(a)},onRequestComplete:function(a){this.list.getStore().loadData(a);this.list.getStore().sort("tier","ASC")},onSaveFail:function(){},
-onSelect:function(a){a.getSelectionCount()&&this.panel.getBottomToolbar().items.get(4).enable()},onShow:function(){this.panel.getBottomToolbar().items.get(4).disable();var a=deluge.torrents.getSelected();this.torrentId=a.id;deluge.client.core.get_torrent_status(a.id,["trackers"],{success:this.onRequestComplete,scope:this})},onDownClick:function(){var a=this.list.getSelectedRecords()[0];a&&(a.set("tier",a.get("tier")+1),a.store.sort("tier","ASC"),a.store.commitChanges(),this.list.select(a.store.indexOf(a)))},
-onUpClick:function(){var a=this.list.getSelectedRecords()[0];a&&0!=a.get("tier")&&(a.set("tier",a.get("tier")-1),a.store.sort("tier","ASC"),a.store.commitChanges(),this.list.select(a.store.indexOf(a)))}});
-Deluge.EventsManager=Ext.extend(Ext.util.Observable,{constructor:function(){this.toRegister=[];this.on("login",this.onLogin,this);Deluge.EventsManager.superclass.constructor.call(this)},addListener:function(a,b,c,d){this.addEvents(a);/[A-Z]/.test(a.substring(0,1))&&(deluge.client?deluge.client.web.register_event_listener(a):this.toRegister.push(a));Deluge.EventsManager.superclass.addListener.call(this,a,b,c,d)},getEvents:function(){deluge.client.web.get_events({success:this.onGetEventsSuccess,failure:this.onGetEventsFailure,
-scope:this})},start:function(){Ext.each(this.toRegister,function(a){deluge.client.web.register_event_listener(a)});this.running=!0;this.errorCount=0;this.getEvents()},stop:function(){this.running=!1},onLogin:function(){this.start()},onGetEventsSuccess:function(a){this.running&&(a&&Ext.each(a,function(a){var c=a[1];c.splice(0,0,a[0]);this.fireEvent.apply(this,c)},this),this.getEvents())},onGetEventsFailure:function(a,b){this.running&&(!b.isTimeout&&3<=this.errorCount++?this.stop():this.getEvents())}});
-Deluge.EventsManager.prototype.on=Deluge.EventsManager.prototype.addListener;Deluge.EventsManager.prototype.fire=Deluge.EventsManager.prototype.fireEvent;deluge.events=new Deluge.EventsManager;Ext.namespace("Deluge");
-Deluge.FileBrowser=Ext.extend(Ext.Window,{title:_("File Browser"),width:500,height:400,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"}]})}});Ext.ns("Deluge");
-Deluge.FilterPanel=Ext.extend(Ext.Panel,{autoScroll:!0,border:!1,show_zero:null,initComponent:function(){Deluge.FilterPanel.superclass.initComponent.call(this);this.filterType=this.initialConfig.filter;var a="";"state"==this.filterType?a=_("States"):"tracker_host"==this.filterType?a=_("Trackers"):"owner"==this.filterType?a=_("Owner"):"label"==this.filterType?a=_("Labels"):(a=this.filterType.replace("_"," "),parts=a.split(" "),a="",Ext.each(parts,function(b){fl=b.substring(0,1).toUpperCase();a+=fl+
-b.substring(1)+" "}));this.setTitle(_(a));var b=Deluge.FilterPanel.templates[this.filterType]?Deluge.FilterPanel.templates[this.filterType]:'<div class="x-deluge-filter x-deluge-{filter:lowercase}">{filter} ({count})</div>';this.list=this.add({xtype:"listview",singleSelect:!0,hideHeaders:!0,reserveScrollOffset:!0,store:new Ext.data.ArrayStore({idIndex:0,fields:["filter","count"]}),columns:[{id:"filter",sortable:!1,tpl:b,dataIndex:"filter"}]});this.relayEvents(this.list,["selectionchange"])},getState:function(){if(this.list.getSelectionCount()){var a=
-this.list.getSelectedRecords()[0];if(a&&"All"!=a.id)return a.id}},getStates:function(){return this.states},getStore:function(){return this.list.getStore()},updateStates:function(a){this.states={};Ext.each(a,function(a){this.states[a[0]]=a[1]},this);if(!(null==this.show_zero?deluge.config.sidebar_show_zero:this.show_zero)){var b=[];Ext.each(a,function(a){(0<a[1]||"All"==a[0])&&b.push(a)});a=b}var c=this.getStore(),d={};Ext.each(a,function(a,b){var e=c.getById(a[0]);e||(e=new c.recordType({filter:a[0],
-count:a[1]}),e.id=a[0],c.insert(b,e));e.beginEdit();e.set("filter",_(a[0]));e.set("count",a[1]);e.endEdit();d[a[0]]=!0},this);c.each(function(a){if(!d[a.id]){c.remove(a);var b=this.list.getSelectedRecords()[0];b&&b.id==a.id&&this.list.select(0)}},this);c.commitChanges();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:htmlEncode} ({count})</div>'};
-Deluge.Formatters=function(){var a={"&":"&amp;",">":"&gt;","<":"&lt;",'"':"&quot;","'":"&#39;"},b=RegExp("("+Object.keys(a).join("|")+")","g"),c=function(b,c){return a[c]};return Formatters={date:function(a){function b(a,c){for(var d=a+"";d.length<c;)d="0"+d;return d}a=new Date(1E3*a);return String.format("{0}/{1}/{2} {3}:{4}:{5}",b(a.getDate(),2),b(a.getMonth()+1,2),a.getFullYear(),b(a.getHours(),2),b(a.getMinutes(),2),b(a.getSeconds(),2))},size:function(a,b){if(!a&&!b)return"";a/=1024;if(1024>a)return a.toFixed(1)+
-" KiB";a/=1024;return 1024>a?a.toFixed(1)+" MiB":(a/1024).toFixed(1)+" GiB"},sizeShort:function(a,b){if(!a&&!b)return"";a/=1024;if(1024>a)return a.toFixed(1)+" K";a/=1024;return 1024>a?a.toFixed(1)+" M":(a/1024).toFixed(1)+" G"},speed:function(a,b){return!a&&!b?"":fsize(a,b)+"/s"},timeRemaining:function(a){if(0>=a)return"&infin;";a=a.toFixed(0);if(60>a)return a+"s";a/=60;if(60>a){var b=Math.floor(a);a=Math.round(60*(a-b));return 0<a?b+"m "+a+"s":b+"m"}a/=60;if(24>a){var c=Math.floor(a),b=Math.round(60*
-(a-c));return 0<b?c+"h "+b+"m":c+"h"}a/=24;b=Math.floor(a);c=Math.round(24*(a-b));return 0<c?b+"d "+c+"h":b+"d"},plain:function(a){return a},cssClassEscape:function(a){return a.toLowerCase().replace(".","_")},htmlEncode:function(a){return!a?a:String(a).replace(b,c)}}}();var fsize=Deluge.Formatters.size,fsize_short=Deluge.Formatters.sizeShort,fspeed=Deluge.Formatters.speed,ftime=Deluge.Formatters.timeRemaining,fdate=Deluge.Formatters.date,fplain=Deluge.Formatters.plain;
-Ext.util.Format.cssClassEscape=Deluge.Formatters.cssClassEscape;Ext.util.Format.htmlEncode=Deluge.Formatters.htmlEncode;
-Deluge.Keys={Grid:"queue name total_wanted 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 download_location last_seen_complete total_done total_uploaded max_download_speed max_upload_speed seeds_peers_ratio total_remaining completed_time time_since_transfer".split(" "),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 time_since_transfer seed_rank last_seen_complete completed_time owner public shared".split(" "),
-Files:["files","file_progress","file_priorities"],Peers:["peers"],Details:"name download_location total_size num_files message tracker_host comment creator".split(" "),Options:"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 move_completed move_completed_path super_seeding".split(" ")};Ext.each(Deluge.Keys.Grid,function(a){Deluge.Keys.Status.push(a)});
-Deluge.LoginWindow=Ext.extend(Ext.Window,{firstShow:!0,bodyStyle:"padding: 10px 5px;",buttonAlign:"center",closable:!1,closeAction:"hide",iconCls:"x-deluge-login-window-icon",layout:"fit",modal:!0,plain:!0,resizable:!1,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:120,
-labelAlign:"right",defaults:{width:110},defaultType:"textfield"});this.passwordField=this.form.add({xtype:"textfield",fieldLabel:_("Password:"),labelSeparator:"",grow:!0,growMin:"110",growMax:"145",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(a){this.show(!0)},scope:this})},show:function(a){this.firstShow&&(deluge.client.on("error",
-this.onClientError,this),this.firstShow=!1);if(a)return Deluge.LoginWindow.superclass.show.call(this);deluge.client.auth.check_session({success:function(a){a?deluge.events.fire("login"):this.show(!0)},failure:function(a){this.show(!0)},scope:this})},onSpecialKey:function(a,b){if(13==b.getKey())this.onLogin()},onLogin:function(){var a=this.passwordField;deluge.client.auth.login(a.getValue(),{success:function(b){b?(deluge.events.fire("login"),this.hide(),a.setRawValue("")):Ext.MessageBox.show({title:_("Login Failed"),
-msg:_("You entered an incorrect password"),buttons:Ext.MessageBox.OK,modal:!1,fn:function(){a.focus(!0,10)},icon:Ext.MessageBox.WARNING,iconCls:"x-deluge-icon-warning"})},scope:this})},onClientError:function(a,b,c){1==a.error.code&&(deluge.events.fire("logout"),this.show(!0))},onShow:function(){this.passwordField.focus(!0,300)}});
-deluge.menus={onTorrentActionSetOpt:function(a,b){var c=deluge.torrents.getSelectedIds(),d=a.initialConfig.torrentAction,f={};f[d[0]]=d[1];deluge.client.core.set_torrent_options(c,f)},onTorrentActionMethod:function(a,b){var c=deluge.torrents.getSelectedIds();deluge.client.core[a.initialConfig.torrentAction](c,{success:function(){deluge.ui.update()}})},onTorrentActionShow:function(a,b){var c=deluge.torrents.getSelectedIds();switch(a.initialConfig.torrentAction){case "copy_magnet":deluge.copyMagnetWindow.show();
-break;case "edit_trackers":deluge.editTrackers.show();break;case "remove":deluge.removeWindow.show(c);break;case "move":deluge.moveStorage.show(c)}}};
-deluge.menus.torrent=new Ext.menu.Menu({id:"torrentMenu",items:[{torrentAction:"pause_torrent",text:_("Pause"),iconCls:"icon-pause",handler:deluge.menus.onTorrentActionMethod,scope:deluge.menus},{torrentAction:"resume_torrent",text:_("Resume"),iconCls:"icon-resume",handler:deluge.menus.onTorrentActionMethod,scope:deluge.menus},"-",{text:_("Options"),iconCls:"icon-options",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{text:_("D/L Speed Limit"),iconCls:"x-deluge-downloading",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{torrentAction:["max_download_speed",
-5],text:_("5 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_download_speed",10],text:_("10 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_download_speed",30],text:_("30 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_download_speed",80],text:_("80 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_download_speed",300],text:_("300 KiB/s"),
-handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_download_speed",-1],text:_("Unlimited"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus}]})},{text:_("U/L Speed Limit"),iconCls:"x-deluge-seeding",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{torrentAction:["max_upload_speed",5],text:_("5 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_speed",10],text:_("10 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,
-scope:deluge.menus},{torrentAction:["max_upload_speed",30],text:_("30 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_speed",80],text:_("80 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_speed",300],text:_("300 KiB/s"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_speed",-1],text:_("Unlimited"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus}]})},
-{text:_("Connection Limit"),iconCls:"x-deluge-connections",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{torrentAction:["max_connections",50],text:"50",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_connections",100],text:"100",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_connections",200],text:"200",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_connections",300],text:"300",handler:deluge.menus.onTorrentActionSetOpt,
-scope:deluge.menus},{torrentAction:["max_connections",500],text:"500",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_connections",-1],text:_("Unlimited"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus}]})},{text:_("Upload Slot Limit"),iconCls:"icon-upload-slots",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{torrentAction:["max_upload_slots",0],text:"0",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_slots",
-1],text:"1",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_slots",2],text:"2",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_slots",3],text:"3",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_slots",5],text:"5",handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["max_upload_slots",-1],text:_("Unlimited"),handler:deluge.menus.onTorrentActionSetOpt,
-scope:deluge.menus}]})},{id:"auto_managed",text:_("Auto Managed"),hideOnClick:!1,menu:new Ext.menu.Menu({items:[{torrentAction:["auto_managed",!0],text:_("On"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus},{torrentAction:["auto_managed",!1],text:_("Off"),handler:deluge.menus.onTorrentActionSetOpt,scope:deluge.menus}]})}]})},"-",{text:_("Queue"),iconCls:"icon-queue",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{torrentAction:"queue_top",text:_("Top"),iconCls:"icon-top",handler:deluge.menus.onTorrentActionMethod,
-scope:deluge.menus},{torrentAction:"queue_up",text:_("Up"),iconCls:"icon-up",handler:deluge.menus.onTorrentActionMethod,scope:deluge.menus},{torrentAction:"queue_down",text:_("Down"),iconCls:"icon-down",handler:deluge.menus.onTorrentActionMethod,scope:deluge.menus},{torrentAction:"queue_bottom",text:_("Bottom"),iconCls:"icon-bottom",handler:deluge.menus.onTorrentActionMethod,scope:deluge.menus}]})},"-",{torrentAction:"copy_magnet",text:_("Copy Magnet URI"),iconCls:"icon-magnet-copy",handler:deluge.menus.onTorrentActionShow,
-scope:deluge.menus},{torrentAction:"force_reannounce",text:_("Update Tracker"),iconCls:"icon-update-tracker",handler:deluge.menus.onTorrentActionMethod,scope:deluge.menus},{torrentAction:"edit_trackers",text:_("Edit Trackers"),iconCls:"icon-edit-trackers",handler:deluge.menus.onTorrentActionShow,scope:deluge.menus},"-",{torrentAction:"remove",text:_("Remove Torrent"),iconCls:"icon-remove",handler:deluge.menus.onTorrentActionShow,scope:deluge.menus},"-",{torrentAction:"force_recheck",text:_("Force Recheck"),
-iconCls:"icon-recheck",handler:deluge.menus.onTorrentActionMethod,scope:deluge.menus},{torrentAction:"move",text:_("Move Download Folder"),iconCls:"icon-move",handler:deluge.menus.onTorrentActionShow,scope:deluge.menus}]});
-deluge.menus.filePriorities=new Ext.menu.Menu({id:"filePrioritiesMenu",items:[{id:"expandAll",text:_("Expand All"),iconCls:"icon-expand-all"},"-",{id:"skip",text:_("Skip"),iconCls:"icon-do-not-download",filePriority:FILE_PRIORITY.Skip},{id:"low",text:_("Low"),iconCls:"icon-low",filePriority:FILE_PRIORITY.Low},{id:"normal",text:_("Normal"),iconCls:"icon-normal",filePriority:FILE_PRIORITY.Normal},{id:"high",text:_("High"),iconCls:"icon-high",filePriority:FILE_PRIORITY.High}]});Ext.namespace("Deluge");
-Deluge.MoveStorage=Ext.extend(Ext.Window,{constructor:function(a){a=Ext.apply({title:_("Move Download Folder"),width:375,height:110,layout:"fit",buttonAlign:"right",closeAction:"hide",closable:!0,iconCls:"x-deluge-move-storage",plain:!0,constrainHeader:!0,resizable:!1},a);Deluge.MoveStorage.superclass.constructor.call(this,a)},initComponent:function(){Deluge.MoveStorage.superclass.initComponent.call(this);this.addButton(_("Cancel"),this.onCancel,this);this.addButton(_("Move"),this.onMove,this);this.form=
-this.add({xtype:"form",border:!1,defaultType:"textfield",width:300,bodyStyle:"padding: 5px"});this.moveLocation=this.form.add({fieldLabel:_("Download Folder"),name:"location",width:240})},hide:function(){Deluge.MoveStorage.superclass.hide.call(this);this.torrentIds=null},show:function(a){Deluge.MoveStorage.superclass.show.call(this);this.torrentIds=a},onCancel:function(){this.hide()},onMove:function(){var a=this.moveLocation.getValue();deluge.client.core.move_storage(this.torrentIds,a);this.hide()}});
-deluge.moveStorage=new Deluge.MoveStorage;
-Deluge.MultiOptionsManager=Ext.extend(Deluge.OptionsManager,{constructor:function(a){this.currentId=null;this.stored={};Deluge.MultiOptionsManager.superclass.constructor.call(this,a)},changeId:function(a,b){var c=this.currentId;this.currentId=a;if(!b)for(var d in this.options)this.binds[d]&&Ext.each(this.binds[d],function(a){a.setValue(this.get(d))},this);return c},commit:function(){this.stored[this.currentId]=Ext.apply(this.stored[this.currentId],this.changed[this.currentId]);this.reset()},get:function(){if(1==
-arguments.length){var a=arguments[0];return this.isDirty(a)?this.changed[this.currentId][a]:this.getDefault(a)}if(0==arguments.length){var b={};for(a in this.options)b[a]=this.isDirty(a)?this.changed[this.currentId][a]:this.getDefault(a)}else b={},Ext.each(arguments,function(a){b[a]=this.isDirty(a)?this.changed[this.currentId][a]:this.getDefault(a)},this);return b},getDefault:function(a){return this.has(a)?this.stored[this.currentId][a]:this.options[a]},getDirty:function(){return this.changed[this.currentId]?
-this.changed[this.currentId]:{}},isDirty:function(a){return this.changed[this.currentId]&&!Ext.isEmpty(this.changed[this.currentId][a])},has:function(a){return this.stored[this.currentId]&&!Ext.isEmpty(this.stored[this.currentId][a])},reset:function(){this.changed[this.currentId]&&delete this.changed[this.currentId];this.stored[this.currentId]&&delete this.stored[this.currentId]},resetAll:function(){this.changed={};this.stored={};this.changeId(null)},setDefault:function(a,b){if(void 0!==a)if(void 0===
-b)for(var c in a)this.setDefault(c,a[c]);else c=this.getDefault(a),b=this.convertValueType(c,b),c!=b&&(this.stored[this.currentId]||(this.stored[this.currentId]={}),this.stored[this.currentId][a]=b,this.isDirty(a)||this.fireEvent("changed",a,b,c))},update:function(a,b){if(void 0!==a)if(void 0===b)for(var c in a)this.update(c,a[c]);else{this.changed[this.currentId]||(this.changed[this.currentId]={});c=this.getDefault(a);b=this.convertValueType(c,b);var d=this.get(a);d!=b&&(c==b?this.isDirty(a)&&delete this.changed[this.currentId][a]:
-this.changed[this.currentId][a]=b,this.fireEvent("changed",a,b,d))}}});Ext.ns("Deluge");
-Deluge.OtherLimitWindow=Ext.extend(Ext.Window,{layout:"fit",width:210,height:100,constrainHeader:!0,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"}]});this.initialConfig.unit?this.form.add({border:!1,baseCls:"x-plain",bodyStyle:"padding: 5px",html:this.initialConfig.unit}):this.setSize(180,
-100);this.addButton(_("Cancel"),this.onCancelClick,this);this.addButton(_("OK"),this.onOkClick,this);this.afterMethod("show",this.doFocusField,this)},setValue:function(a){this.form.getForm().setValues({limit:a})},onCancelClick:function(){this.form.getForm().reset();this.hide()},onOkClick:function(){var a={};a[this.group]=this.form.getForm().getValues().limit;deluge.client.core.set_config(a,{success:function(){deluge.ui.update()}});this.hide()},doFocusField:function(){this.form.getForm().findField("limit").focus(!0,
-10)}});Ext.ns("Deluge");
-Deluge.Plugin=Ext.extend(Ext.util.Observable,{name:null,constructor:function(a){this.isDelugePlugin=!0;this.addEvents({enabled:!0,disabled:!0});Deluge.Plugin.superclass.constructor.call(this,a)},disable:function(){this.fireEvent("disabled",this);if(this.onDisable)this.onDisable()},enable:function(){deluge.client.reloadMethods();this.fireEvent("enable",this);if(this.onEnable)this.onEnable()},registerTorrentStatus:function(a,b,c){c=c||{};var d=c.colCfg||{};c=c.storeCfg||{};c=Ext.apply(c,{name:a});deluge.torrents.meta.fields.push(c);
-deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);d=Ext.apply(d,{header:b,dataIndex:a});b=deluge.torrents.columns.slice(0);b.push(d);deluge.torrents.colModel.setConfig(b);deluge.torrents.columns=b;Deluge.Keys.Grid.push(a);deluge.torrents.getView().refresh(!0)},deregisterTorrentStatus:function(a){var b=[];Ext.each(deluge.torrents.meta.fields,function(c){c.name!=a&&b.push(c)});deluge.torrents.meta.fields=b;deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);var c=
-[];Ext.each(deluge.torrents.columns,function(b){b.dataIndex!=a&&c.push(b)});deluge.torrents.colModel.setConfig(c);deluge.torrents.columns=c;var d=[];Ext.each(Deluge.Keys.Grid,function(b){b==a&&d.push(b)});Deluge.Keys.Grid=d;deluge.torrents.getView().refresh(!0)}});Ext.ns("Deluge.plugins");
-Deluge.RemoveWindow=Ext.extend(Ext.Window,{title:_("Remove Torrent"),layout:"fit",width:350,height:100,constrainHeader:!0,buttonAlign:"right",closeAction:"hide",closable:!0,iconCls:"x-deluge-remove-window-icon",plain:!0,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(a){deluge.client.core.remove_torrents(this.torrentIds,a,{success:function(a){!0==a&&console.log("Error(s) occured when trying to delete torrent(s).");this.onRemoved(this.torrentIds)},scope:this,torrentIds:this.torrentIds})},show:function(a){Deluge.RemoveWindow.superclass.show.call(this);this.torrentIds=a},onCancel:function(){this.hide();this.torrentIds=null},onRemove:function(){this.remove(!1)},onRemoveData:function(){this.remove(!0)},
-onRemoved:function(a){deluge.events.fire("torrentsRemoved",a);this.hide();deluge.ui.update()}});deluge.removeWindow=new Deluge.RemoveWindow;
-Deluge.Sidebar=Ext.extend(Ext.Panel,{panels:{},selected:null,constructor:function(a){a=Ext.apply({id:"sidebar",region:"west",cls:"deluge-sidebar",title:_("Filters"),layout:"accordion",split:!0,width:200,minSize:100,collapsible:!0},a);Deluge.Sidebar.superclass.constructor.call(this,a)},initComponent:function(){Deluge.Sidebar.superclass.initComponent.call(this);deluge.events.on("disconnect",this.onDisconnect,this)},createFilter:function(a,b){var c=new Deluge.FilterPanel({filter:a});c.on("selectionchange",
-function(a,b){deluge.ui.update()});this.add(c);this.doLayout();this.panels[a]=c;c.header.on("click",function(a){deluge.config.sidebar_multiple_filters||deluge.ui.update();c.list.getSelectionCount()||c.list.select(0)});this.fireEvent("filtercreate",this,c);c.updateStates(b);this.fireEvent("afterfiltercreate",this,c)},getFilter:function(a){return this.panels[a]},getFilterStates:function(){var a={};if(deluge.config.sidebar_multiple_filters)this.items.each(function(b){var c=b.getState();null!=c&&(a[b.filterType]=
-c)},this);else{var b=this.getLayout().activeItem;if(b){var c=b.getState();if(null==!c)return;a[b.filterType]=c}}return a},hasFilter:function(a){return this.panels[a]?!0:!1},onDisconnect:function(){for(var a in this.panels)this.remove(this.panels[a]);this.panels={};this.selected=null},onFilterSelect:function(a,b,c){deluge.ui.update()},update:function(a){for(var b in a){var c=a[b];-1<Ext.getKeys(this.panels).indexOf(b)?this.panels[b].updateStates(c):this.createFilter(b,c)}Ext.each(Ext.keys(this.panels),
-function(b){-1==Ext.keys(a).indexOf(b)&&(this.remove(this.panels[b]),this.doLayout(),delete this.panels[b])},this)}});Ext.namespace("Deluge");
-Deluge.Statusbar=Ext.extend(Ext.ux.StatusBar,{constructor:function(a){a=Ext.apply({id:"deluge-statusbar",defaultIconCls:"x-deluge-statusbar x-not-connected",defaultText:_("Not Connected")},a);Deluge.Statusbar.superclass.constructor.call(this,a)},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:!1},{text:"100",value:"100",group:"max_connections_global",checked:!1},{text:"200",value:"200",group:"max_connections_global",checked:!1},{text:"300",value:"300",group:"max_connections_global",checked:!1},{text:"500",value:"500",group:"max_connections_global",checked:!1},{text:_("Unlimited"),value:"-1",group:"max_connections_global",
-checked:!1},"-",{text:_("Other"),value:"other",group:"max_connections_global",checked:!1}],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:!1},{value:"10",text:_("10 KiB/s"),group:"max_download_speed",checked:!1},{value:"30",text:_("30 KiB/s"),group:"max_download_speed",checked:!1},
-{value:"80",text:_("80 KiB/s"),group:"max_download_speed",checked:!1},{value:"300",text:_("300 KiB/s"),group:"max_download_speed",checked:!1},{value:"-1",text:_("Unlimited"),group:"max_download_speed",checked:!1},"-",{value:"other",text:_("Other"),group:"max_download_speed",checked:!1}],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:!1},{value:"10",text:_("10 KiB/s"),group:"max_upload_speed",checked:!1},{value:"30",text:_("30 KiB/s"),group:"max_upload_speed",checked:!1},{value:"80",text:_("80 KiB/s"),group:"max_upload_speed",checked:!1},{value:"300",text:_("300 KiB/s"),group:"max_upload_speed",checked:!1},{value:"-1",text:_("Unlimited"),group:"max_upload_speed",checked:!1},"-",{value:"other",text:_("Other"),group:"max_upload_speed",checked:!1}],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-externalip",text:" ",cls:"x-btn-text",tooltip:_("External IP Address")},"-",{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 folder"),handler:function(){deluge.preferences.show();deluge.preferences.selectPage("Downloads")}});this.created=!0},onConnect:function(){this.setStatus({iconCls:"x-connected",text:""});this.created?Ext.each(this.buttons,function(a){a.show();a.enable()}):this.createButtons();this.doLayout()},onDisconnect:function(){this.clearStatus({useDefaults:!0});Ext.each(this.buttons,function(a){a.hide();a.disable()});this.doLayout()},update:function(a){function b(a){return a+
-" KiB/s"}if(a){var c=function(a,b){var c=this.items.get("statusbar-"+a);if(0<b.limit.value)var e=b.value.formatter?b.value.formatter(b.value.value,!0):b.value.value,l=b.limit.formatter?b.limit.formatter(b.limit.value,!0):b.limit.value,e=String.format(b.format,e,l);else e=b.value.formatter?b.value.formatter(b.value.value,!0):b.value.value;c.setText(e);c.menu&&c.menu.setValue(b.limit.value)}.createDelegate(this);c("connections",{value:{value:a.num_connections},limit:{value:a.max_num_connections},format:"{0} ({1})"});
-c("downspeed",{value:{value:a.download_rate,formatter:Deluge.Formatters.speed},limit:{value:a.max_download,formatter:b},format:"{0} ({1})"});c("upspeed",{value:{value:a.upload_rate,formatter:Deluge.Formatters.speed},limit:{value:a.max_upload,formatter:b},format:"{0} ({1})"});c("traffic",{value:{value:a.download_protocol_rate,formatter:Deluge.Formatters.speed},limit:{value:a.upload_protocol_rate,formatter:Deluge.Formatters.speed},format:"{0}/{1}"});this.items.get("statusbar-dht").setText(a.dht_nodes);
-this.items.get("statusbar-freespace").setText(0<=a.free_space?fsize(a.free_space):_("Error"));this.items.get("statusbar-externalip").setText(String.format(_("<b>IP</b> {0}"),a.external_ip?a.external_ip:_("n/a")))}}});
-Deluge.Toolbar=Ext.extend(Ext.Toolbar,{constructor:function(a){a=Ext.apply({items:[{id:"tbar-deluge-text",text:_("Deluge"),iconCls:"x-deluge-main-panel",handler:this.onAboutClick},new Ext.Toolbar.Separator,{id:"create",disabled:!0,hidden:!0,text:_("Create"),iconCls:"icon-create",handler:this.onTorrentAction},{id:"add",disabled:!0,text:_("Add"),iconCls:"icon-add",handler:this.onTorrentAdd},{id:"remove",disabled:!0,text:_("Remove"),iconCls:"icon-remove",handler:this.onTorrentAction},new Ext.Toolbar.Separator,
-{id:"pause",disabled:!0,text:_("Pause"),iconCls:"icon-pause",handler:this.onTorrentAction},{id:"resume",disabled:!0,text:_("Resume"),iconCls:"icon-resume",handler:this.onTorrentAction},new Ext.Toolbar.Separator,{id:"up",cls:"x-btn-text-icon",disabled:!0,text:_("Up"),iconCls:"icon-up",handler:this.onTorrentAction},{id:"down",disabled:!0,text:_("Down"),iconCls:"icon-down",handler:this.onTorrentAction},new Ext.Toolbar.Separator,{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:!0,text:_("Logout"),handler:this.onLogout,scope:this}]},a);Deluge.Toolbar.superclass.constructor.call(this,a)},connectedButtons:"add remove pause resume up down".split(" "),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(a){this.items.get(a).enable()},this)},onDisconnect:function(){Ext.each(this.connectedButtons,function(a){this.items.get(a).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")},
-onAboutClick:function(){(new Deluge.about.AboutWindow).show()},onPreferencesClick:function(){deluge.preferences.show()},onTorrentAction:function(a){var b=deluge.torrents.getSelections(),c=[];Ext.each(b,function(a){c.push(a.id)});switch(a.id){case "remove":deluge.removeWindow.show(c);break;case "pause":case "resume":deluge.client.core[a.id+"_torrent"](c,{success:function(){deluge.ui.update()}});break;case "up":case "down":deluge.client.core["queue_"+a.id](c,{success:function(){deluge.ui.update()}})}},
-onTorrentAdd:function(){deluge.add.show()}});
-(function(){function a(a){if(a)return fspeed(a)}function b(a){return-1==a?"":fspeed(1024*a)}function c(a,b,c){return 0>a?"&infin;":parseFloat((new Number(a)).toFixed(3))}function d(a){return 0<a?fdate(a):_("Never")}Deluge.TorrentGrid=Ext.extend(Ext.grid.GridPanel,{torrents:{},columns:[{id:"queue",header:"#",width:30,sortable:!0,renderer:function(a){return-1==a?"":a+1},dataIndex:"queue"},{id:"name",header:_("Name"),width:150,sortable:!0,renderer:function(a,b,c){return String.format('<div class="torrent-name x-deluge-{0}">{1}</div>',
-c.data.state.toLowerCase(),Ext.util.Format.htmlEncode(a))},dataIndex:"name"},{header:_("Size"),width:75,sortable:!0,renderer:fsize,dataIndex:"total_wanted"},{header:_("Progress"),width:150,sortable:!0,renderer:function(a,b,c){a=new Number(a);c=_(c.data.state)+" "+a.toFixed(2)+"%";b=new Number((this.style?this.style:b.style).match(/\w+:\s*(\d+)\w+/)[1]);return Deluge.progressBar(a,b-8,c)},dataIndex:"progress"},{header:_("Seeds"),hidden:!0,width:60,sortable:!0,renderer:function(a,b,c){return-1<c.data.total_seeds?
-String.format("{0} ({1})",a,c.data.total_seeds):a},dataIndex:"num_seeds"},{header:_("Peers"),hidden:!0,width:60,sortable:!0,renderer:function(a,b,c){return-1<c.data.total_peers?String.format("{0} ({1})",a,c.data.total_peers):a},dataIndex:"num_peers"},{header:_("Down Speed"),width:80,sortable:!0,renderer:a,dataIndex:"download_payload_rate"},{header:_("Up Speed"),width:80,sortable:!0,renderer:a,dataIndex:"upload_payload_rate"},{header:_("ETA"),width:60,sortable:!0,renderer:function(a){return 0===a?
-"":-1>=a?"&infin;":ftime(a)},dataIndex:"eta"},{header:_("Ratio"),hidden:!0,width:60,sortable:!0,renderer:c,dataIndex:"ratio"},{header:_("Avail"),hidden:!0,width:60,sortable:!0,renderer:c,dataIndex:"distributed_copies"},{header:_("Added"),hidden:!0,width:80,sortable:!0,renderer:fdate,dataIndex:"time_added"},{header:_("Complete Seen"),hidden:!0,width:80,sortable:!0,renderer:d,dataIndex:"last_seen_complete"},{header:_("Completed"),hidden:!0,width:80,sortable:!0,renderer:d,dataIndex:"completed_time"},
-{header:_("Tracker"),hidden:!0,width:120,sortable:!0,renderer:function(a,b,c){return String.format('<div style="background: url('+deluge.config.base+'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>',Ext.util.Format.htmlEncode(a))},dataIndex:"tracker_host"},{header:_("Download Folder"),hidden:!0,width:120,sortable:!0,renderer:fplain,dataIndex:"download_location"},{header:_("Owner"),width:80,sortable:!0,renderer:fplain,dataIndex:"owner"},{header:_("Public"),hidden:!0,width:80,sortable:!0,renderer:fplain,
-dataIndex:"public"},{header:_("Shared"),hidden:!0,width:80,sortable:!0,renderer:fplain,dataIndex:"shared"},{header:_("Downloaded"),hidden:!0,width:75,sortable:!0,renderer:fsize,dataIndex:"total_done"},{header:_("Uploaded"),hidden:!0,width:75,sortable:!0,renderer:fsize,dataIndex:"total_uploaded"},{header:_("Remaining"),hidden:!0,width:75,sortable:!0,renderer:fsize,dataIndex:"total_remaining"},{header:_("Down Limit"),hidden:!0,width:75,sortable:!0,renderer:b,dataIndex:"max_download_speed"},{header:_("Up Limit"),
-hidden:!0,width:75,sortable:!0,renderer:b,dataIndex:"max_upload_speed"},{header:_("Seeds:Peers"),hidden:!0,width:75,sortable:!0,renderer:c,dataIndex:"seeds_peers_ratio"},{header:_("Last Transfer"),hidden:!0,width:75,sortable:!0,renderer:ftime,dataIndex:"time_since_transfer"}],meta:{root:"torrents",idProperty:"id",fields:[{name:"queue",sortType:Deluge.data.SortTypes.asQueuePosition},{name:"name",sortType:Deluge.data.SortTypes.asName},{name:"total_wanted",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_rate",type:"int"},{name:"eta",type:"int",sortType:function(a){return 0===a?Number.MAX_VALUE:-1>=a?Number.MAX_SAFE_INTEGER:a}},{name:"ratio",type:"float"},{name:"distributed_copies",type:"float"},{name:"time_added",type:"int"},{name:"last_seen_complete",type:"int"},{name:"completed_time",type:"int"},
-{name:"tracker_host"},{name:"download_location"},{name:"total_done",type:"int"},{name:"total_uploaded",type:"int"},{name:"total_remaining",type:"int"},{name:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"},{name:"time_since_transfer",type:"int"}]},keys:[{key:"a",ctrl:!0,stopEvent:!0,handler:function(){deluge.torrents.getSelectionModel().selectAll()}},{key:[46],stopEvent:!0,handler:function(){ids=deluge.torrents.getSelectedIds();deluge.removeWindow.show(ids)}}],
-constructor:function(a){a=Ext.apply({id:"torrentGrid",store:new Ext.data.JsonStore(this.meta),columns:this.columns,keys:this.keys,region:"center",cls:"deluge-torrents",stripeRows:!0,autoExpandColumn:"name",autoExpandMin:150,deferredRender:!1,autoScroll:!0,stateful:!0,view:new Ext.ux.grid.BufferView({rowHeight:26,scrollDelay:!1})},a);Deluge.TorrentGrid.superclass.constructor.call(this,a)},initComponent:function(){Deluge.TorrentGrid.superclass.initComponent.call(this);deluge.events.on("torrentsRemoved",
-this.onTorrentsRemoved,this);deluge.events.on("disconnect",this.onDisconnect,this);this.on("rowcontextmenu",function(a,b,c){c.stopEvent();a=a.getSelectionModel();a.isSelected(b)||a.selectRow(b);deluge.menus.torrent.showAt(c.getPoint())})},getTorrent:function(a){return this.getStore().getAt(a)},getSelected:function(){return this.getSelectionModel().getSelected()},getSelections:function(){return this.getSelectionModel().getSelections()},getSelectedId:function(){return this.getSelectionModel().getSelected().id},
-getSelectedIds:function(){var a=[];Ext.each(this.getSelectionModel().getSelections(),function(b){a.push(b.id)});return a},update:function(a,b){var c=this.getStore();b&&(c.removeAll(),this.torrents={});var d=[],h;for(h in a){var m=a[h];if(this.torrents[h]){var k=c.getById(h);k.beginEdit();for(var n in m)k.get(n)!=m[n]&&k.set(n,m[n]);k.endEdit()}else k=new Deluge.data.Torrent(m),k.id=h,this.torrents[h]=1,d.push(k)}c.add(d);c.each(function(b){a[b.id]||(c.remove(b),delete this.torrents[b.id])},this);
-c.commitChanges();(d=c.getSortState())&&c.sort(d.field,d.direction)},onDisconnect:function(){this.getStore().removeAll();this.torrents={}},onTorrentsRemoved:function(a){var b=this.getSelectionModel();Ext.each(a,function(a){var c=this.getStore().getById(a);b.isSelected(c)&&b.deselectRow(this.getStore().indexOf(c));this.getStore().remove(c);delete this.torrents[a]},this)}});deluge.torrents=new Deluge.TorrentGrid})();
-var TORRENT_STATE_TRANSLATION=[_("All"),_("Active"),_("Allocating"),_("Checking"),_("Downloading"),_("Seeding"),_("Paused"),_("Checking"),_("Queued"),_("Error")];
-deluge.ui={errorCount:0,filters:null,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.detailsPanel=new Ext.Panel({id:"detailsPanel",cls:"detailsPanel",
-region:"south",split:!0,height:215,minSize:100,collapsible:!0,layout:"fit",items:[deluge.details]});this.MainPanel=new Ext.Panel({id:"mainPanel",iconCls:"x-deluge-main-panel",layout:"border",border:!1,tbar:deluge.toolbar,items:[deluge.sidebar,this.detailsPanel,deluge.torrents],bbar:deluge.statusbar});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"});for(var a in Deluge.pluginStore)a=Deluge.createPlugin(a),a.enable(),deluge.plugins[a.name]=a;Ext.QuickTips.init();deluge.client.on("connected",function(a){deluge.login.show()},this,{single:!0});this.update=this.update.createDelegate(this);this.checkConnection=this.checkConnection.createDelegate(this);this.originalTitle=document.title},
-checkConnection:function(){deluge.client.web.connected({success:this.onConnectionSuccess,failure:this.onConnectionError,scope:this})},update:function(){var a=deluge.sidebar.getFilterStates();this.oldFilters=this.filters;this.filters=a;deluge.client.web.update_ui(Deluge.Keys.Grid,a,{success:this.onUpdate,failure:this.onUpdateError,scope:this});deluge.details.update()},onConnectionError:function(a){},onConnectionSuccess:function(a){deluge.statusbar.setStatus({iconCls:"x-deluge-statusbar icon-ok",text:_("Connection restored")});
-clearInterval(this.checking);a||deluge.connectionManager.show()},onUpdateError:function(a){2==this.errorCount&&(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,2E3));this.errorCount++},onUpdate:function(a){a.connected?(deluge.config.show_session_speed&&
-(document.title="D: "+fsize_short(a.stats.download_rate,!0)+" U: "+fsize_short(a.stats.upload_rate,!0)+" - "+this.originalTitle),Ext.areObjectsEqual(this.filters,this.oldFilters)?deluge.torrents.update(a.torrents):deluge.torrents.update(a.torrents,!0),deluge.statusbar.update(a.stats),deluge.sidebar.update(a.filters),this.errorCount=0):deluge.connectionManager.disconnect(!0)},onConnect:function(){this.running||(this.running=setInterval(this.update,2E3),this.update());deluge.client.web.get_plugins({success:this.onGotPlugins,
-scope:this})},onDisconnect:function(){this.stop()},onGotPlugins:function(a){Ext.each(a.enabled_plugins,function(a){deluge.plugins[a]||deluge.client.web.get_plugin_resources(a,{success:this.onGotPluginResources,scope:this})},this)},onPluginEnabled:function(a){deluge.plugins[a]?deluge.plugins[a].enable():deluge.client.web.get_plugin_resources(a,{success:this.onGotPluginResources,scope:this})},onGotPluginResources:function(a){Ext.each(Deluge.debug?a.debug_scripts:a.scripts,function(b){Ext.ux.JSLoader({url:deluge.config.base+
-b,onLoad:this.onPluginLoaded,pluginName:a.name})},this)},onPluginDisabled:function(a){deluge.plugins[a]&&deluge.plugins[a].disable()},onPluginLoaded:function(a){Deluge.hasPlugin(a.pluginName)&&(plugin=Deluge.createPlugin(a.pluginName),plugin.enable(),deluge.plugins[plugin.name]=plugin)},stop:function(){this.running&&(clearInterval(this.running),this.running=!1,deluge.torrents.getStore().removeAll())}};Ext.onReady(function(a){deluge.ui.initialize()});
diff --git a/deluge/ui/web/js/deluge-all/ConnectionManager.js b/deluge/ui/web/js/deluge-all/ConnectionManager.js
index 5261726..2e61e22 100644
--- a/deluge/ui/web/js/deluge-all/ConnectionManager.js
+++ b/deluge/ui/web/js/deluge-all/ConnectionManager.js
@@ -162,13 +162,23 @@ Deluge.ConnectionManager = Ext.extend(Ext.Window, {
},
update: function () {
+ this.updating = setTimeout(this.update, 2000);
this.list.getStore().each(function (r) {
deluge.client.web.get_host_status(r.id, {
- success: this.onGetHostStatus,
+ success: this.onUpdate,
scope: this,
});
}, this);
},
+ onUpdate: function (host) {
+ if (!this.isVisible()) return;
+ this.onGetHostStatus(host);
+
+ if (this.updating) {
+ clearTimeout(this.updating);
+ }
+ this.updating = setTimeout(this.update, 2000);
+ },
/**
* Updates the buttons in the Connection Manager UI according to the
@@ -312,7 +322,10 @@ Deluge.ConnectionManager = Ext.extend(Ext.Window, {
// private
onHide: function () {
- if (this.running) window.clearInterval(this.running);
+ if (this.updating) {
+ window.clearTimeout(this.updating);
+ this.updating = undefined;
+ }
},
// private
@@ -396,8 +409,8 @@ Deluge.ConnectionManager = Ext.extend(Ext.Window, {
this.stopHostButton = bbar.items.get('cm-stop');
}
this.loadHosts();
- if (this.running) return;
- this.running = window.setInterval(this.update, 2000, this);
+ if (this.updating) return;
+ this.updating = window.setTimeout(this.update, 2000);
},
// private
diff --git a/deluge/ui/web/js/deluge-all/Sidebar.js b/deluge/ui/web/js/deluge-all/Sidebar.js
index eb08a89..a6512b2 100644
--- a/deluge/ui/web/js/deluge-all/Sidebar.js
+++ b/deluge/ui/web/js/deluge-all/Sidebar.js
@@ -60,14 +60,16 @@ Deluge.Sidebar = Ext.extend(Ext.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);
- }
- });
+ if (panel.header) {
+ 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);
diff --git a/deluge/ui/web/js/deluge-all/UI.js b/deluge/ui/web/js/deluge-all/UI.js
index cc877d5..f7edc84 100644
--- a/deluge/ui/web/js/deluge-all/UI.js
+++ b/deluge/ui/web/js/deluge-all/UI.js
@@ -134,14 +134,24 @@ deluge.ui = {
deluge.details.update();
},
- onConnectionError: function (error) {},
+ onConnectionError: function (error) {
+ if (this.checking) {
+ clearTimeout(this.checking);
+ }
+ this.checking = setTimeout(this.checkConnection, 2000);
+ },
onConnectionSuccess: function (result) {
+ if (this.checking) {
+ clearTimeout(this.checking);
+ this.checking = undefined;
+ }
+ this.running = setTimeout(this.update, 2000);
+ this.update();
deluge.statusbar.setStatus({
iconCls: 'x-deluge-statusbar icon-ok',
text: _('Connection restored'),
});
- clearInterval(this.checking);
if (!result) {
deluge.connectionManager.show();
}
@@ -159,9 +169,13 @@ deluge.ui = {
deluge.statusbar.setStatus({
text: _('Lost connection to webserver'),
});
- this.checking = setInterval(this.checkConnection, 2000);
+ this.checking = setTimeout(this.checkConnection, 2000);
}
this.errorCount++;
+ if (this.running) {
+ clearTimeout(this.running);
+ this.running = undefined;
+ }
},
/**
@@ -170,10 +184,15 @@ deluge.ui = {
* Updates the various components in the interface.
*/
onUpdate: function (data) {
+ if (this.running) {
+ clearTimeout(this.running);
+ this.running = undefined;
+ }
if (!data['connected']) {
deluge.connectionManager.disconnect(true);
return;
}
+ this.running = setTimeout(this.update, 2000);
if (deluge.config.show_session_speed) {
document.title =
@@ -201,7 +220,7 @@ deluge.ui = {
*/
onConnect: function () {
if (!this.running) {
- this.running = setInterval(this.update, 2000);
+ this.running = setTimeout(this.update, 2000);
this.update();
}
deluge.client.web.get_plugins({
@@ -280,8 +299,8 @@ deluge.ui = {
*/
stop: function () {
if (this.running) {
- clearInterval(this.running);
- this.running = false;
+ clearTimeout(this.running);
+ this.running = undefined;
deluge.torrents.getStore().removeAll();
}
},
diff --git a/deluge/ui/web/js/deluge-all/details/FilesTab.js b/deluge/ui/web/js/deluge-all/details/FilesTab.js
index 60de832..36ef968 100644
--- a/deluge/ui/web/js/deluge-all/details/FilesTab.js
+++ b/deluge/ui/web/js/deluge-all/details/FilesTab.js
@@ -214,7 +214,9 @@ Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
{
success: function () {
Ext.each(nodes, function (node) {
- node.setColumnValue(3, baseItem.filePriority);
+ node.attributes.priority =
+ baseItem.filePriority;
+ node.ui.updateColumns();
});
},
scope: this,
diff --git a/deluge/ui/web/js/deluge-all/details/OptionsTab.js b/deluge/ui/web/js/deluge-all/details/OptionsTab.js
index 7e59cba..f8a08be 100644
--- a/deluge/ui/web/js/deluge-all/details/OptionsTab.js
+++ b/deluge/ui/web/js/deluge-all/details/OptionsTab.js
@@ -86,7 +86,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
xtype: 'number',
decimalPrecision: 1,
minValue: -1,
- maxValue: 99999,
+ maxValue: 9999999,
},
});
this.fieldsets.bandwidth.add({
@@ -113,7 +113,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
xtype: 'number',
decimalPrecision: 1,
minValue: -1,
- maxValue: 99999,
+ maxValue: 9999999,
},
});
this.fieldsets.bandwidth.add({
diff --git a/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js b/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js
index 8c32da5..563dedd 100644
--- a/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js
+++ b/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js
@@ -40,7 +40,7 @@ Deluge.preferences.Bandwidth = Ext.extend(Ext.form.FormPanel, {
defaultType: 'spinnerfield',
defaults: {
minValue: -1,
- maxValue: 99999,
+ maxValue: 9999999,
},
style: 'margin-bottom: 0px; padding-bottom: 0px;',
autoHeight: true,
diff --git a/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js b/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js
index 1787826..da205c2 100644
--- a/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js
+++ b/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js
@@ -40,7 +40,7 @@ Deluge.preferences.Daemon = Ext.extend(Ext.form.FormPanel, {
value: 58846,
decimalPrecision: 0,
minValue: -1,
- maxValue: 99999,
+ maxValue: 65535,
})
);
diff --git a/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js b/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js
index b6b76eb..1b710f2 100644
--- a/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js
+++ b/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js
@@ -140,7 +140,7 @@ Deluge.preferences.Interface = Ext.extend(Ext.form.FormPanel, {
fieldLabel: _('Session Timeout:'),
decimalPrecision: 0,
minValue: -1,
- maxValue: 99999,
+ maxValue: Number.MAX_SAFE_INTEGER || Number.MAX_VALUE,
})
);
om.bind(
diff --git a/deluge/ui/web/js/extjs/ext-extensions-debug.js b/deluge/ui/web/js/extjs/ext-extensions-debug.js
deleted file mode 100644
index 8a05e61..0000000
--- a/deluge/ui/web/js/extjs/ext-extensions-debug.js
+++ /dev/null
@@ -1,2927 +0,0 @@
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-Ext.ns('Ext.ux.form');
-
-/**
- * @class Ext.ux.form.FileUploadField
- * @extends Ext.form.TextField
- * Creates a file upload field.
- * @xtype fileuploadfield
- */
-Ext.ux.form.FileUploadField = Ext.extend(Ext.form.TextField, {
- /**
- * @cfg {String} buttonText The button text to display on the upload button (defaults to
- * 'Browse...'). Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text
- * value will be used instead if available.
- */
- buttonText: 'Browse...',
- /**
- * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible
- * text field (defaults to false). If true, all inherited TextField members will still be available.
- */
- buttonOnly: false,
- /**
- * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field
- * (defaults to 3). Note that this only applies if {@link #buttonOnly} = false.
- */
- buttonOffset: 3,
-
- /**
- * @cfg {Boolean} multiple True to select more than one file. (defaults to false).
- * Note that this only applies if the HTML doc is using HTML5.
- */
- multiple: false,
-
- /**
- * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object.
- */
-
- // private
- readOnly: true,
-
- /**
- * @hide
- * @method autoSize
- */
- autoSize: Ext.emptyFn,
-
- // private
- initComponent: function () {
- Ext.ux.form.FileUploadField.superclass.initComponent.call(this);
-
- this.addEvents(
- /**
- * @event fileselected
- * Fires when the underlying file input field's value has changed from the user
- * selecting a new file from the system file selection dialog.
- * @param {Ext.ux.form.FileUploadField} this
- * @param {String} value The file value returned by the underlying file input field
- */
- 'fileselected'
- );
- },
-
- // private
- onRender: function (ct, position) {
- Ext.ux.form.FileUploadField.superclass.onRender.call(
- this,
- ct,
- position
- );
-
- this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
- this.el.addClass('x-form-file-text');
- this.el.dom.removeAttribute('name');
- this.createFileInput();
-
- var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
- text: this.buttonText,
- });
- this.button = new Ext.Button(
- Ext.apply(btnCfg, {
- renderTo: this.wrap,
- cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : ''),
- })
- );
-
- if (this.buttonOnly) {
- this.el.hide();
- this.wrap.setWidth(this.button.getEl().getWidth());
- }
-
- this.bindListeners();
- this.resizeEl = this.positionEl = this.wrap;
- },
-
- bindListeners: function () {
- this.fileInput.on({
- scope: this,
- mouseenter: function () {
- this.button.addClass(['x-btn-over', 'x-btn-focus']);
- },
- mouseleave: function () {
- this.button.removeClass([
- 'x-btn-over',
- 'x-btn-focus',
- 'x-btn-click',
- ]);
- },
- mousedown: function () {
- this.button.addClass('x-btn-click');
- },
- mouseup: function () {
- this.button.removeClass([
- 'x-btn-over',
- 'x-btn-focus',
- 'x-btn-click',
- ]);
- },
- change: function () {
- var value = this.fileInput.dom.files;
- // Fallback to value.
- if (!value) value = this.fileInput.dom.value;
- this.setValue(value);
- this.fireEvent('fileselected', this, value);
- },
- });
- },
-
- createFileInput: function () {
- this.fileInput = this.wrap.createChild({
- id: this.getFileInputId(),
- name: this.name || this.getId(),
- cls: 'x-form-file',
- tag: 'input',
- type: 'file',
- size: 1,
- });
- this.fileInput.dom.multiple = this.multiple;
- },
-
- reset: function () {
- if (this.rendered) {
- this.fileInput.remove();
- this.createFileInput();
- this.bindListeners();
- }
- Ext.ux.form.FileUploadField.superclass.reset.call(this);
- },
-
- // private
- getFileInputId: function () {
- return this.id + '-file';
- },
-
- // private
- onResize: function (w, h) {
- Ext.ux.form.FileUploadField.superclass.onResize.call(this, w, h);
-
- this.wrap.setWidth(w);
-
- if (!this.buttonOnly) {
- var w =
- this.wrap.getWidth() -
- this.button.getEl().getWidth() -
- this.buttonOffset;
- this.el.setWidth(w);
- }
- },
-
- // private
- onDestroy: function () {
- Ext.ux.form.FileUploadField.superclass.onDestroy.call(this);
- Ext.destroy(this.fileInput, this.button, this.wrap);
- },
-
- onDisable: function () {
- Ext.ux.form.FileUploadField.superclass.onDisable.call(this);
- this.doDisable(true);
- },
-
- onEnable: function () {
- Ext.ux.form.FileUploadField.superclass.onEnable.call(this);
- this.doDisable(false);
- },
-
- // private
- doDisable: function (disabled) {
- this.fileInput.dom.disabled = disabled;
- this.button.setDisabled(disabled);
- },
-
- // private
- preFocus: Ext.emptyFn,
-
- // private
- alignErrorIcon: function () {
- this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
- },
-});
-
-Ext.reg('fileuploadfield', Ext.ux.form.FileUploadField);
-
-// backwards compat
-Ext.form.FileUploadField = Ext.ux.form.FileUploadField;
-/**
- * Ext.ux.form.RadioGroup.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-// Allow radiogroups to be treated as a single form element.
-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);
- },
-
- getName: function () {
- return this.items.first().getName();
- },
-
- getValue: function () {
- 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
- );
- }
- });
- },
-});
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-Ext.ns('Ext.ux.form');
-
-/**
- * @class Ext.ux.form.SpinnerField
- * @extends Ext.form.NumberField
- * Creates a field utilizing Ext.ux.Spinner
- * @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,
-
- constructor: function (config) {
- var spinnerConfig = Ext.copyTo(
- {},
- config,
- 'incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass'
- );
-
- 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;
-
- Ext.ux.form.SpinnerField.superclass.constructor.call(
- this,
- Ext.apply(config, { plugins: plugins })
- );
- },
-
- // private
- getResizeEl: 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]);
- }
- },
-
- validateBlur: function () {
- return true;
- },
-});
-
-Ext.reg('spinnerfield', Ext.ux.form.SpinnerField);
-
-//backwards compat
-Ext.form.SpinnerField = Ext.ux.form.SpinnerField;
-/**
- * Ext.ux.form.SpinnerField.js
- *
- * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-Ext.override(Ext.ux.form.SpinnerField, {
- onBlur: Ext.form.Field.prototype.onBlur,
-});
-/**
- * Ext.ux.form.SpinnerGroup.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.ns('Ext.ux.form');
-
-/**
- *
- */
-Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
- // private
- defaultType: 'spinnerfield',
- anchor: '98%',
-
- // private
- groupCls: 'x-form-spinner-group',
-
- colCfg: {},
-
- // private
- onRender: function (ct, position) {
- if (!this.el) {
- var panelCfg = {
- cls: this.groupCls,
- layout: 'column',
- border: false,
- renderTo: ct,
- };
- var colCfg = Ext.apply(
- {
- defaultType: this.defaultType,
- layout: 'form',
- border: false,
- labelWidth: 60,
- defaults: {
- hideLabel: true,
- anchor: '60%',
- },
- },
- this.colCfg
- );
-
- if (this.items[0].items) {
- // The container has standard ColumnLayout configs, so pass them in directly
-
- Ext.apply(panelCfg, {
- layoutConfig: { columns: this.items.length },
- defaults: this.defaults,
- items: this.items,
- });
- for (var i = 0, len = this.items.length; i < len; i++) {
- Ext.applyIf(this.items[i], colCfg);
- }
- } else {
- // The container has field item configs, so we have to generate the column
- // panels first then move the items into the columns as needed.
-
- var numCols,
- cols = [];
-
- if (typeof this.columns == 'string') {
- // 'auto' so create a col per item
- this.columns = this.items.length;
- }
- if (!Ext.isArray(this.columns)) {
- var cs = [];
- for (var i = 0; i < this.columns; i++) {
- cs.push((100 / this.columns) * 0.01); // distribute by even %
- }
- this.columns = cs;
- }
-
- numCols = this.columns.length;
-
- // Generate the column configs with the correct width setting
- for (var i = 0; i < numCols; i++) {
- 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
- );
- }
- cols.push(cc);
- }
-
- // Distribute the original items into the columns
- if (this.vertical) {
- var rows = Math.ceil(this.items.length / numCols),
- ri = 0;
- for (var i = 0, len = this.items.length; i < len; i++) {
- if (i > 0 && i % rows == 0) {
- ri++;
- }
- if (this.items[i].fieldLabel) {
- this.items[i].hideLabel = false;
- }
- cols[ri].items.push(this.items[i]);
- }
- } else {
- for (var i = 0, len = this.items.length; i < len; i++) {
- var ci = i % numCols;
- if (this.items[i].fieldLabel) {
- this.items[i].hideLabel = false;
- }
- cols[ci].items.push(this.items[i]);
- }
- }
-
- Ext.apply(panelCfg, {
- layoutConfig: { columns: numCols },
- items: cols,
- });
- }
-
- this.panel = new Ext.Panel(panelCfg);
- this.el = this.panel.getEl();
-
- if (this.forId && this.itemCls) {
- var l = this.el.up(this.itemCls).child('label', true);
- if (l) {
- l.setAttribute('htmlFor', this.forId);
- }
- }
-
- var fields = this.panel.findBy(function (c) {
- return c.isFormField;
- }, this);
-
- this.items = new Ext.util.MixedCollection();
- this.items.addAll(fields);
-
- this.items.each(function (field) {
- field.on('spin', this.onFieldChange, this);
- field.on('change', this.onFieldChange, this);
- }, this);
-
- 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;
- }
- }
-
- Ext.ux.form.SpinnerGroup.superclass.onRender.call(this, ct, position);
- },
-
- onFieldChange: function (spinner) {
- this.fireEvent('change', this, this.getValue());
- },
-
- initValue: Ext.emptyFn,
-
- getValue: function () {
- var value = [this.items.getCount()];
- this.items.each(function (item, i) {
- value[i] = Number(item.getValue());
- });
- return value;
- },
-
- getRawValue: function () {
- var value = [this.items.getCount()];
- this.items.each(function (item, i) {
- value[i] = Number(item.getRawValue());
- });
- return value;
- },
-
- setValue: function (value) {
- 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]);
- });
- }
- },
-});
-Ext.reg('spinnergroup', Ext.ux.form.SpinnerGroup);
-/**
- * Ext.ux.form.ToggleField.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-Ext.namespace('Ext.ux.form');
-
-/**
- * Ext.ux.form.ToggleField class
- *
- * @author Damien Churchill
- * @version v0.1
- *
- * @class Ext.ux.form.ToggleField
- * @extends Ext.form.TriggerField
- */
-Ext.ux.form.ToggleField = Ext.extend(Ext.form.Field, {
- cls: 'x-toggle-field',
-
- initComponent: function () {
- Ext.ux.form.ToggleField.superclass.initComponent.call(this);
-
- this.toggle = new Ext.form.Checkbox();
- this.toggle.on('check', this.onToggleCheck, this);
-
- 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();
-
- 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);
- },
-
- // 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);
- },
-
- onToggleCheck: function (toggle, checked) {
- this.input.setDisabled(!checked);
- },
-});
-Ext.reg('togglefield', Ext.ux.form.ToggleField);
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-Ext.ns('Ext.ux.grid');
-
-/**
- * @class Ext.ux.grid.BufferView
- * @extends Ext.grid.GridView
- * 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} 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 {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,
-
- 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();
- },
-
- getStyleRowHeight: function () {
- return Ext.isBorderBox
- ? this.rowHeight + this.borderHeight
- : this.rowHeight;
- },
-
- getCalculatedRowHeight: function () {
- return this.rowHeight + this.borderHeight;
- },
-
- getVisibleRowCount: function () {
- var rh = this.getCalculatedRowHeight(),
- visibleHeight = this.scroller.dom.clientHeight;
- return visibleHeight < 1 ? 0 : Math.ceil(visibleHeight / rh);
- },
-
- getVisibleRows: function () {
- var count = this.getVisibleRowCount(),
- sc = this.scroller.dom.scrollTop,
- 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,
- rh = this.getStyleRowHeight(),
- vr = this.getVisibleRows(),
- tstyle = 'width:' + this.getTotalWidth() + ';height:' + rh + 'px;',
- // buffers
- 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,
- 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;
- },
-
- 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();
- }
- },
-
- doUpdate: function () {
- if (this.getVisibleRowCount() > 0) {
- var g = this.grid,
- cm = g.colModel,
- ds = g.store,
- cs = this.getColumnData(),
- vr = this.getVisibleRows(),
- row;
- for (var i = vr.first; i <= vr.last; i++) {
- // if row is NOT rendered and is visible, render it
- if (!this.isRowRendered(i) && (row = this.getRow(i))) {
- var html = this.doRender(
- cs,
- [ds.getAt(i)],
- ds,
- i,
- cm.getColumnCount(),
- g.stripeRows,
- true
- );
- row.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);
- },
-
- 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 = '';
- }
- }
- }
- },
-
- removeTask: function (name) {
- var task = this[name];
- if (task && task.cancel) {
- task.cancel();
- this[name] = null;
- }
- },
-
- destroy: function () {
- this.removeTask('cleanTask');
- this.removeTask('renderTask');
- Ext.ux.grid.BufferView.superclass.destroy.call(this);
- },
-
- layout: function () {
- Ext.ux.grid.BufferView.superclass.layout.call(this);
- this.update();
- },
-});
-/**
- * Ext.ux.layout.FormLayoutFix.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-// Taken from http://extjs.com/forum/showthread.php?t=75273
-// 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);
- }
- },
-});
-/**
- * Ext.ux.tree.MultiSelectionModelFix.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-/**
- * This enhances the MSM to allow for shift selecting in tree grids etc.
- * @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;
-
- // 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);
-
- // 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 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);
- }
- return node;
- },
-});
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-Ext.ns('Ext.ux.tree');
-
-/**
- * @class Ext.ux.tree.TreeGrid
- * @extends Ext.tree.TreePanel
- *
- * @xtype treegrid
- */
-Ext.ux.tree.TreeGrid = Ext.extend(Ext.tree.TreePanel, {
- rootVisible: false,
- useArrows: true,
- lines: false,
- borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
- cls: 'x-treegrid',
-
- columnResize: true,
- enableSort: true,
- reserveScrollOffset: true,
- enableHdMenu: true,
-
- columnsText: 'Columns',
-
- initComponent: function () {
- if (!this.root) {
- this.root = new Ext.tree.AsyncTreeNode({ text: 'Root' });
- }
-
- // initialize the loader
- var l = this.loader;
- if (!l) {
- l = new Ext.ux.tree.TreeGridLoader({
- dataUrl: this.dataUrl,
- requestMethod: this.requestMethod,
- store: this.store,
- });
- } else if (Ext.isObject(l) && !l.load) {
- l = new Ext.ux.tree.TreeGridLoader(l);
- }
- this.loader = l;
-
- Ext.ux.tree.TreeGrid.superclass.initComponent.call(this);
-
- this.initColumns();
-
- if (this.enableSort) {
- this.treeGridSorter = new Ext.ux.tree.TreeGridSorter(
- this,
- this.enableSort
- );
- }
-
- if (this.columnResize) {
- this.colResizer = new Ext.tree.ColumnResizer(this.columnResize);
- this.colResizer.init(this);
- }
-
- var c = this.columns;
- if (!this.internalTpl) {
- this.internalTpl = new Ext.XTemplate(
- '<div class="x-grid3-header">',
- '<div class="x-treegrid-header-inner">',
- '<div class="x-grid3-header-offset">',
- '<table style="table-layout: fixed;" cellspacing="0" cellpadding="0" border="0"><colgroup><tpl for="columns"><col /></tpl></colgroup>',
- '<thead><tr class="x-grid3-hd-row">',
- '<tpl for="columns">',
- '<td class="x-grid3-hd x-grid3-cell x-treegrid-hd" style="text-align: {align};" id="',
- this.id,
- '-xlhd-{#}">',
- '<div class="x-grid3-hd-inner x-treegrid-hd-inner" unselectable="on">',
- this.enableHdMenu
- ? '<a class="x-grid3-hd-btn" href="#"></a>'
- : '',
- '{header}<img class="x-grid3-sort-icon" src="',
- Ext.BLANK_IMAGE_URL,
- '" />',
- '</div>',
- '</td></tpl>',
- '</tr></thead>',
- '</table>',
- '</div></div>',
- '</div>',
- '<div class="x-treegrid-root-node">',
- '<table class="x-treegrid-root-table" cellpadding="0" cellspacing="0" style="table-layout: fixed;"></table>',
- '</div>'
- );
- }
-
- if (!this.colgroupTpl) {
- this.colgroupTpl = new Ext.XTemplate(
- '<colgroup><tpl for="columns"><col style="width: {width}px"/></tpl></colgroup>'
- );
- }
- },
-
- initColumns: function () {
- var cs = this.columns,
- len = cs.length,
- columns = [],
- i,
- c;
-
- for (i = 0; i < len; i++) {
- c = cs[i];
- if (!c.isColumn) {
- c.xtype = c.xtype
- ? /^tg/.test(c.xtype)
- ? c.xtype
- : 'tg' + c.xtype
- : 'tgcolumn';
- c = Ext.create(c);
- }
- c.init(this);
- columns.push(c);
-
- if (this.enableSort !== false && c.sortable !== false) {
- c.sortable = true;
- this.enableSort = true;
- }
- }
-
- this.columns = columns;
- },
-
- onRender: function () {
- Ext.tree.TreePanel.superclass.onRender.apply(this, arguments);
-
- this.el.addClass('x-treegrid');
-
- this.outerCt = this.body.createChild({
- cls:
- 'x-tree-root-ct x-treegrid-ct ' +
- (this.useArrows
- ? 'x-tree-arrows'
- : this.lines
- ? 'x-tree-lines'
- : 'x-tree-no-lines'),
- });
-
- this.internalTpl.overwrite(this.outerCt, { columns: this.columns });
-
- this.mainHd = Ext.get(this.outerCt.dom.firstChild);
- this.innerHd = Ext.get(this.mainHd.dom.firstChild);
- this.innerBody = Ext.get(this.outerCt.dom.lastChild);
- this.innerCt = Ext.get(this.innerBody.dom.firstChild);
-
- this.colgroupTpl.insertFirst(this.innerCt, { columns: this.columns });
-
- if (this.hideHeaders) {
- this.el.child('.x-grid3-header').setDisplayed('none');
- } else if (this.enableHdMenu !== false) {
- this.hmenu = new Ext.menu.Menu({ id: this.id + '-hctx' });
- if (this.enableColumnHide !== false) {
- this.colMenu = new Ext.menu.Menu({
- id: this.id + '-hcols-menu',
- });
- this.colMenu.on({
- scope: this,
- beforeshow: this.beforeColMenuShow,
- itemclick: this.handleHdMenuClick,
- });
- this.hmenu.add({
- itemId: 'columns',
- hideOnClick: false,
- text: this.columnsText,
- menu: this.colMenu,
- iconCls: 'x-cols-icon',
- });
- }
- this.hmenu.on('itemclick', this.handleHdMenuClick, this);
- }
- },
-
- setRootNode: function (node) {
- node.attributes.uiProvider = Ext.ux.tree.TreeGridRootNodeUI;
- node = Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this, node);
- if (this.innerCt) {
- this.colgroupTpl.insertFirst(this.innerCt, {
- columns: this.columns,
- });
- }
- return node;
- },
-
- clearInnerCt: function () {
- if (Ext.isIE) {
- var dom = this.innerCt.dom;
- while (dom.firstChild) {
- dom.removeChild(dom.firstChild);
- }
- } else {
- Ext.ux.tree.TreeGrid.superclass.clearInnerCt.call(this);
- }
- },
-
- initEvents: function () {
- Ext.ux.tree.TreeGrid.superclass.initEvents.apply(this, arguments);
-
- this.mon(this.innerBody, 'scroll', this.syncScroll, this);
- this.mon(this.innerHd, 'click', this.handleHdDown, this);
- this.mon(this.mainHd, {
- scope: this,
- mouseover: this.handleHdOver,
- mouseout: this.handleHdOut,
- });
- },
-
- onResize: function (w, h) {
- Ext.ux.tree.TreeGrid.superclass.onResize.apply(this, arguments);
-
- var bd = this.innerBody.dom;
- var hd = this.innerHd.dom;
-
- if (!bd) {
- return;
- }
-
- if (Ext.isNumber(h)) {
- bd.style.height =
- this.body.getHeight(true) - hd.offsetHeight + 'px';
- }
-
- if (Ext.isNumber(w)) {
- var sw = Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
- if (
- this.reserveScrollOffset ||
- bd.offsetWidth - bd.clientWidth > 10
- ) {
- this.setScrollOffset(sw);
- } else {
- var me = this;
- setTimeout(function () {
- me.setScrollOffset(
- bd.offsetWidth - bd.clientWidth > 10 ? sw : 0
- );
- }, 10);
- }
- }
- },
-
- updateColumnWidths: function () {
- var cols = this.columns,
- colCount = cols.length,
- groups = this.outerCt.query('colgroup'),
- groupCount = groups.length,
- c,
- g,
- i,
- j;
-
- for (i = 0; i < colCount; i++) {
- c = cols[i];
- for (j = 0; j < groupCount; j++) {
- g = groups[j];
- g.childNodes[i].style.width = (c.hidden ? 0 : c.width) + 'px';
- }
- }
-
- for (
- i = 0, groups = this.innerHd.query('td'), len = groups.length;
- i < len;
- i++
- ) {
- c = Ext.fly(groups[i]);
- if (cols[i] && cols[i].hidden) {
- c.addClass('x-treegrid-hd-hidden');
- } else {
- c.removeClass('x-treegrid-hd-hidden');
- }
- }
-
- var tcw = this.getTotalColumnWidth();
- Ext.fly(this.innerHd.dom.firstChild).setWidth(
- tcw + (this.scrollOffset || 0)
- );
- this.outerCt.select('table').setWidth(tcw);
- this.syncHeaderScroll();
- },
-
- getVisibleColumns: function () {
- var columns = [],
- cs = this.columns,
- len = cs.length,
- i;
-
- for (i = 0; i < len; i++) {
- if (!cs[i].hidden) {
- columns.push(cs[i]);
- }
- }
- return columns;
- },
-
- getTotalColumnWidth: function () {
- var total = 0;
- for (
- var i = 0, cs = this.getVisibleColumns(), len = cs.length;
- i < len;
- i++
- ) {
- total += cs[i].width;
- }
- return total;
- },
-
- setScrollOffset: function (scrollOffset) {
- this.scrollOffset = scrollOffset;
- this.updateColumnWidths();
- },
-
- // private
- handleHdDown: function (e, t) {
- var hd = e.getTarget('.x-treegrid-hd');
-
- if (hd && Ext.fly(t).hasClass('x-grid3-hd-btn')) {
- var ms = this.hmenu.items,
- cs = this.columns,
- index = this.findHeaderIndex(hd),
- c = cs[index],
- sort = c.sortable;
-
- e.stopEvent();
- Ext.fly(hd).addClass('x-grid3-hd-menu-open');
- this.hdCtxIndex = index;
-
- this.fireEvent('headerbuttonclick', ms, c, hd, index);
-
- this.hmenu.on(
- 'hide',
- function () {
- Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
- },
- this,
- { single: true }
- );
-
- this.hmenu.show(t, 'tl-bl?');
- } else if (hd) {
- var index = this.findHeaderIndex(hd);
- this.fireEvent('headerclick', this.columns[index], hd, index);
- }
- },
-
- // private
- handleHdOver: function (e, t) {
- var hd = e.getTarget('.x-treegrid-hd');
- if (hd && !this.headersDisabled) {
- index = this.findHeaderIndex(hd);
- this.activeHdRef = t;
- this.activeHdIndex = index;
- var el = Ext.get(hd);
- this.activeHdRegion = el.getRegion();
- el.addClass('x-grid3-hd-over');
- this.activeHdBtn = el.child('.x-grid3-hd-btn');
- if (this.activeHdBtn) {
- this.activeHdBtn.dom.style.height =
- hd.firstChild.offsetHeight - 1 + 'px';
- }
- }
- },
-
- // private
- handleHdOut: function (e, t) {
- var hd = e.getTarget('.x-treegrid-hd');
- if (hd && (!Ext.isIE || !e.within(hd, true))) {
- this.activeHdRef = null;
- Ext.fly(hd).removeClass('x-grid3-hd-over');
- hd.style.cursor = '';
- }
- },
-
- findHeaderIndex: function (hd) {
- hd = hd.dom || hd;
- var cs = hd.parentNode.childNodes;
- for (var i = 0, c; (c = cs[i]); i++) {
- if (c == hd) {
- return i;
- }
- }
- return -1;
- },
-
- // private
- beforeColMenuShow: function () {
- var cols = this.columns,
- colCount = cols.length,
- i,
- c;
- this.colMenu.removeAll();
- for (i = 1; i < colCount; i++) {
- c = cols[i];
- if (c.hideable !== false) {
- this.colMenu.add(
- new Ext.menu.CheckItem({
- itemId: 'col-' + i,
- text: c.header,
- checked: !c.hidden,
- hideOnClick: false,
- disabled: c.hideable === false,
- })
- );
- }
- }
- },
-
- // private
- handleHdMenuClick: function (item) {
- var index = this.hdCtxIndex,
- id = item.getItemId();
-
- if (
- this.fireEvent(
- 'headermenuclick',
- this.columns[index],
- id,
- index
- ) !== false
- ) {
- index = id.substr(4);
- if (index > 0 && this.columns[index]) {
- this.setColumnVisible(index, !item.checked);
- }
- }
-
- return true;
- },
-
- setColumnVisible: function (index, visible) {
- this.columns[index].hidden = !visible;
- this.updateColumnWidths();
- },
-
- /**
- * Scrolls the grid to the top
- */
- scrollToTop: function () {
- this.innerBody.dom.scrollTop = 0;
- this.innerBody.dom.scrollLeft = 0;
- },
-
- // private
- syncScroll: function () {
- this.syncHeaderScroll();
- var mb = this.innerBody.dom;
- this.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
- },
-
- // private
- syncHeaderScroll: function () {
- var mb = this.innerBody.dom;
- this.innerHd.dom.scrollLeft = mb.scrollLeft;
- this.innerHd.dom.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore)
- },
-
- registerNode: function (n) {
- Ext.ux.tree.TreeGrid.superclass.registerNode.call(this, n);
- if (!n.uiProvider && !n.isRoot && !n.ui.isTreeGridNodeUI) {
- n.ui = new Ext.ux.tree.TreeGridNodeUI(n);
- }
- },
-});
-
-Ext.reg('treegrid', Ext.ux.tree.TreeGrid);
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-/**
- * @class Ext.tree.ColumnResizer
- * @extends Ext.util.Observable
- */
-Ext.tree.ColumnResizer = Ext.extend(Ext.util.Observable, {
- /**
- * @cfg {Number} minWidth The minimum width the column can be dragged to.
- * Defaults to <tt>14</tt>.
- */
- minWidth: 14,
-
- constructor: function (config) {
- Ext.apply(this, config);
- Ext.tree.ColumnResizer.superclass.constructor.call(this);
- },
-
- init: function (tree) {
- this.tree = tree;
- tree.on('render', this.initEvents, this);
- },
-
- initEvents: function (tree) {
- tree.mon(tree.innerHd, 'mousemove', this.handleHdMove, this);
- this.tracker = new Ext.dd.DragTracker({
- onBeforeStart: this.onBeforeStart.createDelegate(this),
- onStart: this.onStart.createDelegate(this),
- onDrag: this.onDrag.createDelegate(this),
- onEnd: this.onEnd.createDelegate(this),
- tolerance: 3,
- autoStart: 300,
- });
- this.tracker.initEl(tree.innerHd);
- tree.on('beforedestroy', this.tracker.destroy, this.tracker);
- },
-
- handleHdMove: function (e, t) {
- var hw = 5,
- x = e.getPageX(),
- hd = e.getTarget('.x-treegrid-hd', 3, true);
-
- if (hd) {
- var r = hd.getRegion(),
- ss = hd.dom.style,
- pn = hd.dom.parentNode;
-
- if (x - r.left <= hw && hd.dom !== pn.firstChild) {
- var ps = hd.dom.previousSibling;
- while (ps && Ext.fly(ps).hasClass('x-treegrid-hd-hidden')) {
- ps = ps.previousSibling;
- }
- if (ps) {
- this.activeHd = Ext.get(ps);
- ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
- }
- } else if (r.right - x <= hw) {
- var ns = hd.dom;
- while (ns && Ext.fly(ns).hasClass('x-treegrid-hd-hidden')) {
- ns = ns.previousSibling;
- }
- if (ns) {
- this.activeHd = Ext.get(ns);
- ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
- }
- } else {
- delete this.activeHd;
- ss.cursor = '';
- }
- }
- },
-
- onBeforeStart: function (e) {
- this.dragHd = this.activeHd;
- return !!this.dragHd;
- },
-
- onStart: function (e) {
- this.dragHeadersDisabled = this.tree.headersDisabled;
- this.tree.headersDisabled = true;
- this.proxy = this.tree.body.createChild({ cls: 'x-treegrid-resizer' });
- this.proxy.setHeight(this.tree.body.getHeight());
-
- var x = this.tracker.getXY()[0];
-
- this.hdX = this.dragHd.getX();
- this.hdIndex = this.tree.findHeaderIndex(this.dragHd);
-
- this.proxy.setX(this.hdX);
- this.proxy.setWidth(x - this.hdX);
-
- this.maxWidth =
- this.tree.outerCt.getWidth() -
- this.tree.innerBody.translatePoints(this.hdX).left;
- },
-
- onDrag: function (e) {
- var cursorX = this.tracker.getXY()[0];
- this.proxy.setWidth(
- (cursorX - this.hdX).constrain(this.minWidth, this.maxWidth)
- );
- },
-
- onEnd: function (e) {
- var nw = this.proxy.getWidth(),
- tree = this.tree,
- disabled = this.dragHeadersDisabled;
-
- this.proxy.remove();
- delete this.dragHd;
-
- tree.columns[this.hdIndex].width = nw;
- tree.updateColumnWidths();
-
- setTimeout(function () {
- tree.headersDisabled = disabled;
- }, 100);
- },
-});
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-(function () {
- Ext.override(Ext.list.Column, {
- init: function () {
- var types = Ext.data.Types,
- st = this.sortType;
-
- if (this.type) {
- if (Ext.isString(this.type)) {
- this.type =
- Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
- }
- } else {
- this.type = types.AUTO;
- }
-
- // named sortTypes are supported, here we look them up
- if (Ext.isString(st)) {
- this.sortType = Ext.data.SortTypes[st];
- } else if (Ext.isEmpty(st)) {
- this.sortType = this.type.sortType;
- }
- },
- });
-
- Ext.tree.Column = Ext.extend(Ext.list.Column, {});
- Ext.tree.NumberColumn = Ext.extend(Ext.list.NumberColumn, {});
- Ext.tree.DateColumn = Ext.extend(Ext.list.DateColumn, {});
- Ext.tree.BooleanColumn = Ext.extend(Ext.list.BooleanColumn, {});
-
- Ext.reg('tgcolumn', Ext.tree.Column);
- Ext.reg('tgnumbercolumn', Ext.tree.NumberColumn);
- Ext.reg('tgdatecolumn', Ext.tree.DateColumn);
- Ext.reg('tgbooleancolumn', Ext.tree.BooleanColumn);
-})();
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-/**
- * @class Ext.ux.tree.TreeGridLoader
- * @extends Ext.tree.TreeLoader
- */
-Ext.ux.tree.TreeGridLoader = Ext.extend(Ext.tree.TreeLoader, {
- createNode: function (attr) {
- if (!attr.uiProvider) {
- attr.uiProvider = Ext.ux.tree.TreeGridNodeUI;
- }
- return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
- },
-});
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-/**
- * @class Ext.ux.tree.TreeGridNodeUI
- * @extends Ext.tree.TreeNodeUI
- */
-Ext.ux.tree.TreeGridNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
- isTreeGridNodeUI: true,
-
- renderElements: function (n, a, targetNode, bulkRender) {
- var t = n.getOwnerTree(),
- cols = t.columns,
- c = cols[0],
- i,
- buf,
- len;
-
- this.indentMarkup = n.parentNode
- ? n.parentNode.ui.getChildIndent()
- : '';
-
- buf = [
- '<tbody class="x-tree-node">',
- '<tr ext:tree-node-id="',
- n.id,
- '" class="x-tree-node-el x-tree-node-leaf ',
- a.cls,
- '">',
- '<td class="x-treegrid-col">',
- '<span class="x-tree-node-indent">',
- this.indentMarkup,
- '</span>',
- '<img src="',
- this.emptyIcon,
- '" class="x-tree-ec-icon x-tree-elbow" />',
- '<img src="',
- a.icon || this.emptyIcon,
- '" class="x-tree-node-icon',
- a.icon ? ' x-tree-node-inline-icon' : '',
- a.iconCls ? ' ' + a.iconCls : '',
- '" unselectable="on" />',
- '<a hidefocus="on" class="x-tree-node-anchor" href="',
- a.href ? a.href : '#',
- '" tabIndex="1" ',
- a.hrefTarget ? ' target="' + a.hrefTarget + '"' : '',
- '>',
- '<span unselectable="on">',
- c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text,
- '</span></a>',
- '</td>',
- ];
-
- for (i = 1, len = cols.length; i < len; i++) {
- c = cols[i];
- buf.push(
- '<td class="x-treegrid-col ',
- c.cls ? c.cls : '',
- '">',
- '<div unselectable="on" class="x-treegrid-text"',
- c.align ? ' style="text-align: ' + c.align + ';"' : '',
- '>',
- c.tpl ? c.tpl.apply(a) : a[c.dataIndex],
- '</div>',
- '</td>'
- );
- }
-
- buf.push(
- '</tr><tr class="x-tree-node-ct"><td colspan="',
- cols.length,
- '">',
- '<table class="x-treegrid-node-ct-table" cellpadding="0" cellspacing="0" style="table-layout: fixed; display: none; width: ',
- t.innerCt.getWidth(),
- 'px;"><colgroup>'
- );
- for (i = 0, len = cols.length; i < len; i++) {
- buf.push(
- '<col style="width: ',
- cols[i].hidden ? 0 : cols[i].width,
- 'px;" />'
- );
- }
- buf.push('</colgroup></table></td></tr></tbody>');
-
- if (bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()) {
- this.wrap = Ext.DomHelper.insertHtml(
- 'beforeBegin',
- n.nextSibling.ui.getEl(),
- buf.join('')
- );
- } else {
- this.wrap = Ext.DomHelper.insertHtml(
- 'beforeEnd',
- targetNode,
- buf.join('')
- );
- }
-
- this.elNode = this.wrap.childNodes[0];
- this.ctNode = this.wrap.childNodes[1].firstChild.firstChild;
- var cs = this.elNode.firstChild.childNodes;
- this.indentNode = cs[0];
- this.ecNode = cs[1];
- this.iconNode = cs[2];
- this.anchor = cs[3];
- this.textNode = cs[3].firstChild;
- },
-
- // private
- animExpand: function (cb) {
- this.ctNode.style.display = '';
- Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this, cb);
- },
-});
-
-Ext.ux.tree.TreeGridRootNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
- isTreeGridNodeUI: true,
-
- // private
- render: function () {
- if (!this.rendered) {
- this.wrap = this.ctNode = this.node.ownerTree.innerCt.dom;
- this.node.expanded = true;
- }
-
- if (Ext.isWebKit) {
- // weird table-layout: fixed issue in webkit
- var ct = this.ctNode;
- ct.style.tableLayout = null;
- (function () {
- ct.style.tableLayout = 'fixed';
- }.defer(1));
- }
- },
-
- destroy: function () {
- if (this.elNode) {
- Ext.dd.Registry.unregister(this.elNode.id);
- }
- delete this.node;
- },
-
- collapse: Ext.emptyFn,
- expand: Ext.emptyFn,
-});
-/**
- * Ext.ux.tree.TreeGridNodeUIFix.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
- * the additional special exception to link portions of this program with the OpenSSL library.
- * See LICENSE for more details.
- */
-
-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];
-
- // 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;
- }
- },
-});
-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);
- },
-});
-Ext.reg('tgrendercolumn', Ext.tree.RenderColumn);
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-Ext.ns('Ext.ux.tree');
-
-/**
- * @class Ext.ux.tree.TreeGridSorter
- * @extends Ext.tree.TreeSorter
- * Provides sorting of nodes in a {@link Ext.ux.tree.TreeGrid}. The TreeGridSorter automatically monitors events on the
- * associated TreeGrid that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange).
- * Example usage:<br />
- * <pre><code>
- new Ext.ux.tree.TreeGridSorter(myTreeGrid, {
- folderSort: true,
- dir: "desc",
- sortType: function(node) {
- // sort by a custom, typed attribute:
- return parseInt(node.id, 10);
- }
- });
- </code></pre>
- * @constructor
- * @param {TreeGrid} tree
- * @param {Object} config
- */
-Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, {
- /**
- * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to <tt>['sort-asc', 'sort-desc']</tt>)
- */
- sortClasses: ['sort-asc', 'sort-desc'],
- /**
- * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to <tt>'Sort Ascending'</tt>)
- */
- sortAscText: 'Sort Ascending',
- /**
- * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to <tt>'Sort Descending'</tt>)
- */
- sortDescText: 'Sort Descending',
-
- constructor: function (tree, config) {
- if (!Ext.isObject(config)) {
- config = {
- property: tree.columns[0].dataIndex || 'text',
- folderSort: true,
- };
- }
-
- Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(
- this,
- arguments
- );
-
- this.tree = tree;
- tree.on('headerclick', this.onHeaderClick, this);
- tree.ddAppendOnly = true;
-
- var me = this;
- this.defaultSortFn = function (n1, n2) {
- var desc = me.dir && me.dir.toLowerCase() == 'desc',
- prop = me.property || 'text',
- sortType = me.sortType,
- caseSensitive = me.caseSensitive === true,
- leafAttr = me.leafAttr || 'leaf',
- attr1 = n1.attributes,
- attr2 = n2.attributes;
-
- if (me.folderSort) {
- if (attr1[leafAttr] && !attr2[leafAttr]) {
- return 1;
- }
- if (!attr1[leafAttr] && attr2[leafAttr]) {
- return -1;
- }
- }
- var prop1 = attr1[prop],
- prop2 = attr2[prop],
- v1 = sortType
- ? sortType(prop1)
- : caseSensitive
- ? prop1
- : prop1.toUpperCase();
- v2 = sortType
- ? sortType(prop2)
- : caseSensitive
- ? prop2
- : prop2.toUpperCase();
-
- if (v1 < v2) {
- return desc ? +1 : -1;
- } else if (v1 > v2) {
- return desc ? -1 : +1;
- } else {
- return 0;
- }
- };
-
- tree.on('afterrender', this.onAfterTreeRender, this, { single: true });
- tree.on('headermenuclick', this.onHeaderMenuClick, this);
- },
-
- onAfterTreeRender: function () {
- if (this.tree.hmenu) {
- this.tree.hmenu.insert(
- 0,
- {
- itemId: 'asc',
- text: this.sortAscText,
- cls: 'xg-hmenu-sort-asc',
- },
- {
- itemId: 'desc',
- text: this.sortDescText,
- cls: 'xg-hmenu-sort-desc',
- }
- );
- }
- this.updateSortIcon(0, 'asc');
- },
-
- onHeaderMenuClick: function (c, id, index) {
- if (id === 'asc' || id === 'desc') {
- this.onHeaderClick(c, null, index);
- return false;
- }
- },
-
- onHeaderClick: function (c, el, i) {
- if (c && !this.tree.headersDisabled) {
- var me = this;
-
- me.property = c.dataIndex;
- me.dir = c.dir = c.dir === 'desc' ? 'asc' : 'desc';
- me.sortType = c.sortType;
- me.caseSensitive === Ext.isBoolean(c.caseSensitive)
- ? c.caseSensitive
- : this.caseSensitive;
- me.sortFn = c.sortFn || this.defaultSortFn;
-
- this.tree.root.cascade(function (n) {
- if (!n.isLeaf()) {
- me.updateSort(me.tree, n);
- }
- });
-
- this.updateSortIcon(i, c.dir);
- }
- },
-
- // private
- updateSortIcon: function (col, dir) {
- var sc = this.sortClasses,
- hds = this.tree.innerHd.select('td').removeClass(sc);
- hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]);
- },
-});
-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.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
- );
-};
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-/**
- * @class Ext.ux.Spinner
- * @extends Ext.util.Observable
- * 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,
-
- constructor: function (config) {
- Ext.ux.Spinner.superclass.constructor.call(this, config);
- Ext.apply(this, config);
- this.mimicing = false;
- },
-
- 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);
- },
-
- 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');
- }
-
- 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());
- }
-
- 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.initTrigger();
- this.initSpinner();
- },
-
- 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.disabled = false;
- this.wrap.removeClass(this.field.disabledClass);
- }
- },
-
- doDisable: function () {
- if (this.wrap) {
- this.disabled = true;
- 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());
- },
-
- 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
- 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);
- },
-
- 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,
- });
-
- this.keyNav = new Ext.KeyNav(this.el, {
- up: function (e) {
- e.preventDefault();
- this.onSpinUp();
- },
-
- down: function (e) {
- e.preventDefault();
- this.onSpinDown();
- },
-
- pageUp: function (e) {
- e.preventDefault();
- this.onSpinUpAlternate();
- },
-
- pageDown: function (e) {
- e.preventDefault();
- this.onSpinDownAlternate();
- },
-
- 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.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.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);
- },
-
- //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
- 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
- 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
- //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;
- }
-
- 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
- endDrag: function () {
- this.proxy.hide();
- },
-
- //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]();
- }
-
- 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
- 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
- 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);
-
- v = isNaN(v) ? this.defaultValue : v;
- v = this.fixBoundries(v);
- this.field.setRawValue(v);
- },
-
- 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;
- }
-
- 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)
- );
- },
-
- 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.dd) {
- this.dd.unreg();
- this.dd = null;
- }
-
- if (this.proxy) {
- this.proxy.remove();
- }
-
- if (this.repeater) {
- this.repeater.purgeListeners();
- }
- if (this.mimicing) {
- Ext.get(Ext.isIE ? document.body : document).un(
- 'mousedown',
- this.mimicBlur,
- this
- );
- }
- },
-});
-
-//backwards compat
-Ext.form.Spinner = Ext.ux.Spinner;
-/**
- * Ext JS Library 3.4.0
- * Copyright(c) 2006-2011 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-/**
- * @class Ext.ux.StatusBar
- * <p>Basic status bar component that can be used as the bottom toolbar of any {@link Ext.Panel}. In addition to
- * supporting the standard {@link Ext.Toolbar} interface for adding buttons, menus and other items, the StatusBar
- * provides a greedy status element that can be aligned to either side and has convenient methods for setting the
- * status text and icon. You can also indicate that something is processing using the {@link #showBusy} method.</p>
- * <pre><code>
-new Ext.Panel({
- title: 'StatusBar',
- // etc.
- bbar: new Ext.ux.StatusBar({
- id: 'my-status',
-
- // defaults to use when the status is cleared:
- defaultText: 'Default status text',
- defaultIconCls: 'default-icon',
-
- // values to set initially:
- text: 'Ready',
- iconCls: 'ready-icon',
-
- // any standard Toolbar items:
- items: [{
- text: 'A Button'
- }, '-', 'Plain Text']
- })
-});
-
-// Update the status bar later in code:
-var sb = Ext.getCmp('my-status');
-sb.setStatus({
- text: 'OK',
- iconCls: 'ok-icon',
- clear: true // auto-clear after a set interval
-});
-
-// Set the status bar to show that something is processing:
-sb.showBusy();
-
-// processing....
-
-sb.clearStatus(); // once completeed
-</code></pre>
- * @extends Ext.Toolbar
- * @constructor
- * Creates a new StatusBar
- * @param {Object/Array} config A config object
- */
-Ext.ux.StatusBar = Ext.extend(Ext.Toolbar, {
- /**
- * @cfg {String} statusAlign
- * The alignment of the status element within the overall StatusBar layout. When the StatusBar is rendered,
- * it creates an internal div containing the status text and icon. Any additional Toolbar items added in the
- * StatusBar's {@link #items} config, or added via {@link #add} or any of the supported add* methods, will be
- * rendered, in added order, to the opposite side. The status element is greedy, so it will automatically
- * expand to take up all sapce left over by any other items. Example usage:
- * <pre><code>
-// Create a left-aligned status bar containing a button,
-// separator and text item that will be right-aligned (default):
-new Ext.Panel({
- title: 'StatusBar',
- // etc.
- bbar: new Ext.ux.StatusBar({
- defaultText: 'Default status text',
- id: 'status-id',
- items: [{
- text: 'A Button'
- }, '-', 'Plain Text']
- })
-});
-
-// By adding the statusAlign config, this will create the
-// exact same toolbar, except the status and toolbar item
-// layout will be reversed from the previous example:
-new Ext.Panel({
- title: 'StatusBar',
- // etc.
- bbar: new Ext.ux.StatusBar({
- defaultText: 'Default status text',
- id: 'status-id',
- statusAlign: 'right',
- items: [{
- text: 'A Button'
- }, '-', 'Plain Text']
- })
-});
-</code></pre>
- */
- /**
- * @cfg {String} defaultText
- * The default {@link #text} value. This will be used anytime the status bar is cleared with the
- * <tt>useDefaults:true</tt> option (defaults to '').
- */
- /**
- * @cfg {String} defaultIconCls
- * The default {@link #iconCls} value (see the iconCls docs for additional details about customizing the icon).
- * This will be used anytime the status bar is cleared with the <tt>useDefaults:true</tt> option (defaults to '').
- */
- /**
- * @cfg {String} text
- * A string that will be <b>initially</b> set as the status message. This string
- * will be set as innerHTML (html tags are accepted) for the toolbar item.
- * If not specified, the value set for <code>{@link #defaultText}</code>
- * will be used.
- */
- /**
- * @cfg {String} iconCls
- * A CSS class that will be <b>initially</b> set as the status bar icon and is
- * expected to provide a background image (defaults to '').
- * Example usage:<pre><code>
-// Example CSS rule:
-.x-statusbar .x-status-custom {
- padding-left: 25px;
- background: transparent url(images/custom-icon.gif) no-repeat 3px 2px;
-}
-
-// Setting a default icon:
-var sb = new Ext.ux.StatusBar({
- defaultIconCls: 'x-status-custom'
-});
-
-// Changing the icon:
-sb.setStatus({
- text: 'New status',
- iconCls: 'x-status-custom'
-});
-</code></pre>
- */
-
- /**
- * @cfg {String} cls
- * The base class applied to the containing element for this component on render (defaults to 'x-statusbar')
- */
- cls: 'x-statusbar',
- /**
- * @cfg {String} busyIconCls
- * The default <code>{@link #iconCls}</code> applied when calling
- * <code>{@link #showBusy}</code> (defaults to <tt>'x-status-busy'</tt>).
- * It can be overridden at any time by passing the <code>iconCls</code>
- * argument into <code>{@link #showBusy}</code>.
- */
- busyIconCls: 'x-status-busy',
- /**
- * @cfg {String} busyText
- * The default <code>{@link #text}</code> applied when calling
- * <code>{@link #showBusy}</code> (defaults to <tt>'Loading...'</tt>).
- * It can be overridden at any time by passing the <code>text</code>
- * argument into <code>{@link #showBusy}</code>.
- */
- busyText: 'Loading...',
- /**
- * @cfg {Number} autoClear
- * The number of milliseconds to wait after setting the status via
- * <code>{@link #setStatus}</code> before automatically clearing the status
- * text and icon (defaults to <tt>5000</tt>). Note that this only applies
- * when passing the <tt>clear</tt> argument to <code>{@link #setStatus}</code>
- * since that is the only way to defer clearing the status. This can
- * be overridden by specifying a different <tt>wait</tt> value in
- * <code>{@link #setStatus}</code>. Calls to <code>{@link #clearStatus}</code>
- * always clear the status bar immediately and ignore this value.
- */
- autoClear: 5000,
-
- /**
- * @cfg {String} emptyText
- * The text string to use if no text has been set. Defaults to
- * <tt>'&nbsp;'</tt>). If there are no other items in the toolbar using
- * an empty string (<tt>''</tt>) for this value would end up in the toolbar
- * height collapsing since the empty string will not maintain the toolbar
- * height. Use <tt>''</tt> if the toolbar should collapse in height
- * vertically when no text is specified and there are no other items in
- * the toolbar.
- */
- emptyText: '&nbsp;',
-
- // private
- activeThreadId: 0,
-
- // private
- initComponent: function () {
- if (this.statusAlign == 'right') {
- this.cls += ' x-status-right';
- }
- Ext.ux.StatusBar.superclass.initComponent.call(this);
- },
-
- // private
- afterRender: function () {
- Ext.ux.StatusBar.superclass.afterRender.call(this);
-
- var right = this.statusAlign == 'right';
- this.currIconCls = this.iconCls || this.defaultIconCls;
- this.statusEl = new Ext.Toolbar.TextItem({
- cls: 'x-status-text ' + (this.currIconCls || ''),
- text: this.text || this.defaultText || '',
- });
-
- if (right) {
- this.add('->');
- this.add(this.statusEl);
- } else {
- this.insert(0, this.statusEl);
- this.insert(1, '->');
- }
- this.doLayout();
- },
-
- /**
- * Sets the status {@link #text} and/or {@link #iconCls}. Also supports automatically clearing the
- * status that was set after a specified interval.
- * @param {Object/String} config A config object specifying what status to set, or a string assumed
- * to be the status text (and all other options are defaulted as explained below). A config
- * object containing any or all of the following properties can be passed:<ul>
- * <li><tt>text</tt> {String} : (optional) The status text to display. If not specified, any current
- * status text will remain unchanged.</li>
- * <li><tt>iconCls</tt> {String} : (optional) The CSS class used to customize the status icon (see
- * {@link #iconCls} for details). If not specified, any current iconCls will remain unchanged.</li>
- * <li><tt>clear</tt> {Boolean/Number/Object} : (optional) Allows you to set an internal callback that will
- * automatically clear the status text and iconCls after a specified amount of time has passed. If clear is not
- * specified, the new status will not be auto-cleared and will stay until updated again or cleared using
- * {@link #clearStatus}. If <tt>true</tt> is passed, the status will be cleared using {@link #autoClear},
- * {@link #defaultText} and {@link #defaultIconCls} via a fade out animation. If a numeric value is passed,
- * it will be used as the callback interval (in milliseconds), overriding the {@link #autoClear} value.
- * All other options will be defaulted as with the boolean option. To customize any other options,
- * you can pass an object in the format:<ul>
- * <li><tt>wait</tt> {Number} : (optional) The number of milliseconds to wait before clearing
- * (defaults to {@link #autoClear}).</li>
- * <li><tt>anim</tt> {Number} : (optional) False to clear the status immediately once the callback
- * executes (defaults to true which fades the status out).</li>
- * <li><tt>useDefaults</tt> {Number} : (optional) False to completely clear the status text and iconCls
- * (defaults to true which uses {@link #defaultText} and {@link #defaultIconCls}).</li>
- * </ul></li></ul>
- * Example usage:<pre><code>
-// Simple call to update the text
-statusBar.setStatus('New status');
-
-// Set the status and icon, auto-clearing with default options:
-statusBar.setStatus({
- text: 'New status',
- iconCls: 'x-status-custom',
- clear: true
-});
-
-// Auto-clear with custom options:
-statusBar.setStatus({
- text: 'New status',
- iconCls: 'x-status-custom',
- clear: {
- wait: 8000,
- anim: false,
- useDefaults: false
- }
-});
-</code></pre>
- * @return {Ext.ux.StatusBar} this
- */
- setStatus: function (o) {
- o = o || {};
-
- if (typeof o == 'string') {
- o = { text: o };
- }
- if (o.text !== undefined) {
- this.setText(o.text);
- }
- if (o.iconCls !== undefined) {
- this.setIcon(o.iconCls);
- }
-
- if (o.clear) {
- var c = o.clear,
- wait = this.autoClear,
- defaults = { useDefaults: true, anim: true };
-
- if (typeof c == 'object') {
- c = Ext.applyIf(c, defaults);
- if (c.wait) {
- wait = c.wait;
- }
- } else if (typeof c == 'number') {
- wait = c;
- c = defaults;
- } else if (typeof c == 'boolean') {
- c = defaults;
- }
-
- c.threadId = this.activeThreadId;
- this.clearStatus.defer(wait, this, [c]);
- }
- return this;
- },
-
- /**
- * Clears the status {@link #text} and {@link #iconCls}. Also supports clearing via an optional fade out animation.
- * @param {Object} config (optional) A config object containing any or all of the following properties. If this
- * object is not specified the status will be cleared using the defaults below:<ul>
- * <li><tt>anim</tt> {Boolean} : (optional) True to clear the status by fading out the status element (defaults
- * to false which clears immediately).</li>
- * <li><tt>useDefaults</tt> {Boolean} : (optional) True to reset the text and icon using {@link #defaultText} and
- * {@link #defaultIconCls} (defaults to false which sets the text to '' and removes any existing icon class).</li>
- * </ul>
- * @return {Ext.ux.StatusBar} this
- */
- clearStatus: function (o) {
- o = o || {};
-
- if (o.threadId && o.threadId !== this.activeThreadId) {
- // this means the current call was made internally, but a newer
- // thread has set a message since this call was deferred. Since
- // we don't want to overwrite a newer message just ignore.
- return this;
- }
-
- var text = o.useDefaults ? this.defaultText : this.emptyText,
- iconCls = o.useDefaults
- ? this.defaultIconCls
- ? this.defaultIconCls
- : ''
- : '';
-
- if (o.anim) {
- // animate the statusEl Ext.Element
- this.statusEl.el.fadeOut({
- remove: false,
- useDisplay: true,
- scope: this,
- callback: function () {
- this.setStatus({
- text: text,
- iconCls: iconCls,
- });
-
- this.statusEl.el.show();
- },
- });
- } else {
- // hide/show the el to avoid jumpy text or icon
- this.statusEl.hide();
- this.setStatus({
- text: text,
- iconCls: iconCls,
- });
- this.statusEl.show();
- }
- return this;
- },
-
- /**
- * Convenience method for setting the status text directly. For more flexible options see {@link #setStatus}.
- * @param {String} text (optional) The text to set (defaults to '')
- * @return {Ext.ux.StatusBar} this
- */
- setText: function (text) {
- this.activeThreadId++;
- this.text = text || '';
- if (this.rendered) {
- this.statusEl.setText(this.text);
- }
- return this;
- },
-
- /**
- * Returns the current status text.
- * @return {String} The status text
- */
- getText: function () {
- return this.text;
- },
-
- /**
- * Convenience method for setting the status icon directly. For more flexible options see {@link #setStatus}.
- * See {@link #iconCls} for complete details about customizing the icon.
- * @param {String} iconCls (optional) The icon class to set (defaults to '', and any current icon class is removed)
- * @return {Ext.ux.StatusBar} this
- */
- setIcon: function (cls) {
- this.activeThreadId++;
- 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;
- }
- } else {
- this.currIconCls = cls;
- }
- return this;
- },
-
- /**
- * Convenience method for setting the status text and icon to special values that are pre-configured to indicate
- * a "busy" state, usually for loading or processing activities.
- * @param {Object/String} config (optional) A config object in the same format supported by {@link #setStatus}, or a
- * string to use as the status text (in which case all other options for setStatus will be defaulted). Use the
- * <tt>text</tt> and/or <tt>iconCls</tt> properties on the config to override the default {@link #busyText}
- * and {@link #busyIconCls} settings. If the config argument is not specified, {@link #busyText} and
- * {@link #busyIconCls} will be used in conjunction with all of the default options for {@link #setStatus}.
- * @return {Ext.ux.StatusBar} this
- */
- showBusy: function (o) {
- if (typeof o == 'string') {
- o = { text: o };
- }
- o = Ext.applyIf(o || {}, {
- text: this.busyText,
- iconCls: this.busyIconCls,
- });
- return this.setStatus(o);
- },
-});
-Ext.reg('statusbar', Ext.ux.StatusBar);
diff --git a/deluge/ui/web/js/extjs/ext-extensions.js b/deluge/ui/web/js/extjs/ext-extensions.js
deleted file mode 100644
index e6cb62c..0000000
--- a/deluge/ui/web/js/extjs/ext-extensions.js
+++ /dev/null
@@ -1,84 +0,0 @@
-Ext.ns("Ext.ux.form");
-Ext.ux.form.FileUploadField=Ext.extend(Ext.form.TextField,{buttonText:"Browse...",buttonOnly:!1,buttonOffset:3,multiple:!1,readOnly:!0,autoSize:Ext.emptyFn,initComponent:function(){Ext.ux.form.FileUploadField.superclass.initComponent.call(this);this.addEvents("fileselected")},onRender:function(a,b){Ext.ux.form.FileUploadField.superclass.onRender.call(this,a,b);this.wrap=this.el.wrap({cls:"x-form-field-wrap x-form-file-wrap"});this.el.addClass("x-form-file-text");this.el.dom.removeAttribute("name");this.createFileInput();
-var c=Ext.applyIf(this.buttonCfg||{},{text:this.buttonText});this.button=new Ext.Button(Ext.apply(c,{renderTo:this.wrap,cls:"x-form-file-btn"+(c.iconCls?" x-btn-icon":"")}));this.buttonOnly&&(this.el.hide(),this.wrap.setWidth(this.button.getEl().getWidth()));this.bindListeners();this.resizeEl=this.positionEl=this.wrap},bindListeners:function(){this.fileInput.on({scope:this,mouseenter:function(){this.button.addClass(["x-btn-over","x-btn-focus"])},mouseleave:function(){this.button.removeClass(["x-btn-over",
-"x-btn-focus","x-btn-click"])},mousedown:function(){this.button.addClass("x-btn-click")},mouseup:function(){this.button.removeClass(["x-btn-over","x-btn-focus","x-btn-click"])},change:function(){var a=this.fileInput.dom.files;a||(a=this.fileInput.dom.value);this.setValue(a);this.fireEvent("fileselected",this,a)}})},createFileInput:function(){this.fileInput=this.wrap.createChild({id:this.getFileInputId(),name:this.name||this.getId(),cls:"x-form-file",tag:"input",type:"file",size:1});this.fileInput.dom.multiple=
-this.multiple},reset:function(){this.rendered&&(this.fileInput.remove(),this.createFileInput(),this.bindListeners());Ext.ux.form.FileUploadField.superclass.reset.call(this)},getFileInputId:function(){return this.id+"-file"},onResize:function(a,b){Ext.ux.form.FileUploadField.superclass.onResize.call(this,a,b);this.wrap.setWidth(a);this.buttonOnly||(a=this.wrap.getWidth()-this.button.getEl().getWidth()-this.buttonOffset,this.el.setWidth(a))},onDestroy:function(){Ext.ux.form.FileUploadField.superclass.onDestroy.call(this);
-Ext.destroy(this.fileInput,this.button,this.wrap)},onDisable:function(){Ext.ux.form.FileUploadField.superclass.onDisable.call(this);this.doDisable(!0)},onEnable:function(){Ext.ux.form.FileUploadField.superclass.onEnable.call(this);this.doDisable(!1)},doDisable:function(a){this.fileInput.dom.disabled=a;this.button.setDisabled(a)},preFocus:Ext.emptyFn,alignErrorIcon:function(){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])}});Ext.reg("fileuploadfield",Ext.ux.form.FileUploadField);
-Ext.form.FileUploadField=Ext.ux.form.FileUploadField;
-Ext.override(Ext.form.RadioGroup,{afterRender:function(){this.items.each(function(a){this.relayEvents(a,["check"])},this);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()},getValue:function(){return this.items.first().getGroupValue()},setValue:function(a){this.items.each?this.items.each(function(b){if(b.rendered){var c=b.el.getValue()==String(a);b.el.dom.checked=
-c;b.el.dom.defaultChecked=c;b.wrap[c?"addClass":"removeClass"](b.checkedCls)}}):(this.value=a,this.lazyValue=!0)}});Ext.ns("Ext.ux.form");
-Ext.ux.form.SpinnerField=Ext.extend(Ext.form.NumberField,{actionMode:"wrap",deferHeight:!0,autoSize:Ext.emptyFn,onBlur:Ext.emptyFn,adjustSize:Ext.BoxComponent.prototype.adjustSize,constructor:function(a){var b=Ext.copyTo({},a,"incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass"),b=this.spinner=new Ext.ux.Spinner(b),b=a.plugins?Ext.isArray(a.plugins)?a.plugins.push(b):[a.plugins,b]:b;Ext.ux.form.SpinnerField.superclass.constructor.call(this,Ext.apply(a,{plugins:b}))},
-getResizeEl:function(){return this.wrap},getPositionEl:function(){return this.wrap},alignErrorIcon:function(){this.wrap&&this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])},validateBlur:function(){return!0}});Ext.reg("spinnerfield",Ext.ux.form.SpinnerField);Ext.form.SpinnerField=Ext.ux.form.SpinnerField;Ext.override(Ext.ux.form.SpinnerField,{onBlur:Ext.form.Field.prototype.onBlur});Ext.ns("Ext.ux.form");
-Ext.ux.form.SpinnerGroup=Ext.extend(Ext.form.CheckboxGroup,{defaultType:"spinnerfield",anchor:"98%",groupCls:"x-form-spinner-group",colCfg:{},onRender:function(a,b){if(!this.el){var c={cls:this.groupCls,layout:"column",border:!1,renderTo:a},d=Ext.apply({defaultType:this.defaultType,layout:"form",border:!1,labelWidth:60,defaults:{hideLabel:!0,anchor:"60%"}},this.colCfg);if(this.items[0].items){Ext.apply(c,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=
-0,g=this.items.length;e<g;e++)Ext.applyIf(this.items[e],d)}else{var f,h=[];"string"==typeof this.columns&&(this.columns=this.items.length);if(!Ext.isArray(this.columns)){f=[];for(e=0;e<this.columns;e++)f.push(0.01*(100/this.columns));this.columns=f}f=this.columns.length;for(e=0;e<f;e++)g=Ext.apply({items:[]},d),g[1>=this.columns[e]?"columnWidth":"width"]=this.columns[e],this.defaults&&(g.defaults=Ext.apply(g.defaults||{},this.defaults)),h.push(g);if(this.vertical)for(var d=Math.ceil(this.items.length/
-f),k=0,e=0,g=this.items.length;e<g;e++)0<e&&0==e%d&&k++,this.items[e].fieldLabel&&(this.items[e].hideLabel=!1),h[k].items.push(this.items[e]);else{e=0;for(g=this.items.length;e<g;e++)d=e%f,this.items[e].fieldLabel&&(this.items[e].hideLabel=!1),h[d].items.push(this.items[e])}Ext.apply(c,{layoutConfig:{columns:f},items:h})}this.panel=new Ext.Panel(c);this.el=this.panel.getEl();this.forId&&this.itemCls&&(c=this.el.up(this.itemCls).child("label",!0))&&c.setAttribute("htmlFor",this.forId);c=this.panel.findBy(function(a){return a.isFormField},
-this);this.items=new Ext.util.MixedCollection;this.items.addAll(c);this.items.each(function(a){a.on("spin",this.onFieldChange,this);a.on("change",this.onFieldChange,this)},this);this.lazyValueSet&&(this.setValue(this.value),delete this.value,delete this.lazyValueSet);this.lazyRawValueSet&&(this.setRawValue(this.rawValue),delete this.rawValue,delete this.lazyRawValueSet)}Ext.ux.form.SpinnerGroup.superclass.onRender.call(this,a,b)},onFieldChange:function(a){this.fireEvent("change",this,this.getValue())},
-initValue:Ext.emptyFn,getValue:function(){var a=[this.items.getCount()];this.items.each(function(b,c){a[c]=Number(b.getValue())});return a},getRawValue:function(){var a=[this.items.getCount()];this.items.each(function(b,c){a[c]=Number(b.getRawValue())});return a},setValue:function(a){this.rendered?this.items.each(function(b,c){b.setValue(a[c])}):(this.value=a,this.lazyValueSet=!0)},setRawValue:function(a){this.rendered?this.items.each(function(b,c){b.setRawValue(a[c])}):(this.rawValue=a,this.lazyRawValueSet=
-!0)}});Ext.reg("spinnergroup",Ext.ux.form.SpinnerGroup);Ext.namespace("Ext.ux.form");
-Ext.ux.form.ToggleField=Ext.extend(Ext.form.Field,{cls:"x-toggle-field",initComponent:function(){Ext.ux.form.ToggleField.superclass.initComponent.call(this);this.toggle=new Ext.form.Checkbox;this.toggle.on("check",this.onToggleCheck,this);this.input=new Ext.form.TextField({disabled:!0})},onRender:function(a,b){this.el||(this.panel=new Ext.Panel({cls:this.groupCls,layout:"table",layoutConfig:{columns:2},border:!1,renderTo:a}),this.panel.ownerCt=this,this.el=this.panel.getEl(),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,a,b)},onResize:function(a,b){this.panel.setSize(a,b);this.panel.doLayout();var c=a-this.toggle.getSize().width-25;this.input.setSize(c,b)},onToggleCheck:function(a,b){this.input.setDisabled(!b)}});Ext.reg("togglefield",Ext.ux.form.ToggleField);Ext.ns("Ext.ux.grid");
-Ext.ux.grid.BufferView=Ext.extend(Ext.grid.GridView,{rowHeight:19,borderHeight:2,scrollDelay:100,cacheSize:20,cleanDelay:500,initTemplates:function(){Ext.ux.grid.BufferView.superclass.initTemplates.call(this);var a=this.templates;a.rowHolder=new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}"></div>');a.rowHolder.disableFormats=!0;a.rowHolder.compile();a.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>");a.rowBody.disableFormats=!0;a.rowBody.compile()},getStyleRowHeight:function(){return Ext.isBorderBox?this.rowHeight+this.borderHeight:this.rowHeight},getCalculatedRowHeight:function(){return this.rowHeight+this.borderHeight},getVisibleRowCount:function(){var a=this.getCalculatedRowHeight(),
-b=this.scroller.dom.clientHeight;return 1>b?0:Math.ceil(b/a)},getVisibleRows:function(){var a=this.getVisibleRowCount(),b=this.scroller.dom.scrollTop,b=0===b?0:Math.floor(b/this.getCalculatedRowHeight())-1;return{first:Math.max(b,0),last:Math.min(b+a+2,this.ds.getCount()-1)}},doRender:function(a,b,c,d,e,g,f){for(var h=this.templates,k=h.cell,l=h.row,t=h.rowBody,p=e-1,u=this.getStyleRowHeight(),y=this.getVisibleRows(),x=[],n,m={},q={tstyle:"width:"+this.getTotalWidth()+";height:"+u+"px;"},r,w=0,A=
-b.length;w<A;w++){r=b[w];var u=[],v=w+d,z=v>=y.first&&v<=y.last;if(z)for(var s=0;s<e;s++){n=a[s];m.id=n.id;m.css=0===s?"x-grid3-cell-first ":s==p?"x-grid3-cell-last ":"";m.attr=m.cellAttr="";m.value=n.renderer(r.data[n.name],m,r,v,s,c);m.style=n.style;if(void 0===m.value||""===m.value)m.value="&#160;";r.dirty&&"undefined"!==typeof r.modified[n.name]&&(m.css+=" x-grid3-dirty-cell");u[u.length]=k.apply(m)}n=[];g&&0===(v+1)%2&&(n[0]="x-grid3-row-alt");r.dirty&&(n[1]=" x-grid3-dirty-row");q.cols=e;this.getRowClass&&
-(n[2]=this.getRowClass(r,v,q,c));q.alt=n.join(" ");q.cells=u.join("");x[x.length]=!z?h.rowHolder.apply(q):f?t.apply(q):l.apply(q)}return x.join("")},isRowRendered:function(a){return(a=this.getRow(a))&&0<a.childNodes.length},syncScroll:function(){Ext.ux.grid.BufferView.superclass.syncScroll.apply(this,arguments);this.update()},update:function(){this.scrollDelay?(this.renderTask||(this.renderTask=new Ext.util.DelayedTask(this.doUpdate,this)),this.renderTask.delay(this.scrollDelay)):this.doUpdate()},
-onRemove:function(a,b,c,d){Ext.ux.grid.BufferView.superclass.onRemove.apply(this,arguments);!0!==d&&this.update()},doUpdate:function(){if(0<this.getVisibleRowCount()){for(var a=this.grid,b=a.colModel,c=a.store,d=this.getColumnData(),e=this.getVisibleRows(),g,f=e.first;f<=e.last;f++)if(!this.isRowRendered(f)&&(g=this.getRow(f))){var h=this.doRender(d,[c.getAt(f)],c,f,b.getColumnCount(),a.stripeRows,!0);g.innerHTML=h}this.clean()}},clean:function(){this.cleanTask||(this.cleanTask=new Ext.util.DelayedTask(this.doClean,
-this));this.cleanTask.delay(this.cleanDelay)},doClean:function(){if(0<this.getVisibleRowCount()){var a=this.getVisibleRows();a.first-=this.cacheSize;a.last+=this.cacheSize;var b=0,c=this.getRows();0>=a.first&&(b=a.last+1);for(var d=this.ds.getCount();b<d;b++)if((b<a.first||b>a.last)&&c[b].innerHTML)c[b].innerHTML=""}},removeTask:function(a){var b=this[a];b&&b.cancel&&(b.cancel(),this[a]=null)},destroy:function(){this.removeTask("cleanTask");this.removeTask("renderTask");Ext.ux.grid.BufferView.superclass.destroy.call(this)},
-layout:function(){Ext.ux.grid.BufferView.superclass.layout.call(this);this.update()}});
-Ext.override(Ext.layout.FormLayout,{renderItem:function(a,b,c){if(a&&!a.rendered&&(a.isFormField||a.fieldLabel)&&"hidden"!=a.inputType){var d=this.getTemplateArgs(a);"number"==typeof b&&(b=c.dom.childNodes[b]||null);a.formItem=b?this.fieldTpl.insertBefore(b,d,!0):this.fieldTpl.append(c,d,!0);a.actionMode="formItem";a.render("x-form-el-"+a.id);a.container=a.formItem;a.actionMode="container"}else Ext.layout.FormLayout.superclass.renderItem.apply(this,arguments)}});
-Ext.override(Ext.tree.MultiSelectionModel,{onNodeClick:function(a,b){if(b.ctrlKey&&this.isSelected(a))this.unselect(a);else if(b.shiftKey&&!this.isSelected(a)){var c=a.parentNode;if(this.lastSelNode.parentNode.id==c.id){var d=c.indexOf(a),e=c.indexOf(this.lastSelNode);this.select(this.lastSelNode,b,!1,!0);d>e&&(d+=e,e=d-e,d-=e);c.eachChild(function(a){var f=c.indexOf(a);d<f&&f<e&&this.select(a,b,!0,!0)},this);this.select(a,b,!0)}}else this.select(a,b,b.ctrlKey)},select:function(a,b,c,d){!0!==c&&this.clearSelections(!0);
-if(this.isSelected(a))return this.lastSelNode=a;this.selNodes.push(a);this.lastSelNode=this.selMap[a.id]=a;a.ui.onSelectedChange(!0);!0!==d&&this.fireEvent("selectionchange",this,this.selNodes);return a}});Ext.ns("Ext.ux.tree");
-Ext.ux.tree.TreeGrid=Ext.extend(Ext.tree.TreePanel,{rootVisible:!1,useArrows:!0,lines:!1,borderWidth:Ext.isBorderBox?0:2,cls:"x-treegrid",columnResize:!0,enableSort:!0,reserveScrollOffset:!0,enableHdMenu:!0,columnsText:"Columns",initComponent:function(){this.root||(this.root=new Ext.tree.AsyncTreeNode({text:"Root"}));var a=this.loader;a?Ext.isObject(a)&&!a.load&&(a=new Ext.ux.tree.TreeGridLoader(a)):a=new Ext.ux.tree.TreeGridLoader({dataUrl:this.dataUrl,requestMethod:this.requestMethod,store:this.store});
-this.loader=a;Ext.ux.tree.TreeGrid.superclass.initComponent.call(this);this.initColumns();this.enableSort&&(this.treeGridSorter=new Ext.ux.tree.TreeGridSorter(this,this.enableSort));this.columnResize&&(this.colResizer=new Ext.tree.ColumnResizer(this.columnResize),this.colResizer.init(this));this.internalTpl||(this.internalTpl=new Ext.XTemplate('<div class="x-grid3-header">','<div class="x-treegrid-header-inner">','<div class="x-grid3-header-offset">','<table style="table-layout: fixed;" cellspacing="0" cellpadding="0" border="0"><colgroup><tpl for="columns"><col /></tpl></colgroup>',
-'<thead><tr class="x-grid3-hd-row">','<tpl for="columns">','<td class="x-grid3-hd x-grid3-cell x-treegrid-hd" style="text-align: {align};" id="',this.id,'-xlhd-{#}">','<div class="x-grid3-hd-inner x-treegrid-hd-inner" unselectable="on">',this.enableHdMenu?'<a class="x-grid3-hd-btn" href="#"></a>':"",'{header}<img class="x-grid3-sort-icon" src="',Ext.BLANK_IMAGE_URL,'" />',"</div>","</td></tpl>","</tr></thead>","</table>","</div></div>","</div>",'<div class="x-treegrid-root-node">','<table class="x-treegrid-root-table" cellpadding="0" cellspacing="0" style="table-layout: fixed;"></table>',
-"</div>"));this.colgroupTpl||(this.colgroupTpl=new Ext.XTemplate('<colgroup><tpl for="columns"><col style="width: {width}px"/></tpl></colgroup>'))},initColumns:function(){var a=this.columns,b=a.length,c=[],d,e;for(d=0;d<b;d++)e=a[d],e.isColumn||(e.xtype=e.xtype?/^tg/.test(e.xtype)?e.xtype:"tg"+e.xtype:"tgcolumn",e=Ext.create(e)),e.init(this),c.push(e),!1!==this.enableSort&&!1!==e.sortable&&(this.enableSort=e.sortable=!0);this.columns=c},onRender:function(){Ext.tree.TreePanel.superclass.onRender.apply(this,
-arguments);this.el.addClass("x-treegrid");this.outerCt=this.body.createChild({cls:"x-tree-root-ct x-treegrid-ct "+(this.useArrows?"x-tree-arrows":this.lines?"x-tree-lines":"x-tree-no-lines")});this.internalTpl.overwrite(this.outerCt,{columns:this.columns});this.mainHd=Ext.get(this.outerCt.dom.firstChild);this.innerHd=Ext.get(this.mainHd.dom.firstChild);this.innerBody=Ext.get(this.outerCt.dom.lastChild);this.innerCt=Ext.get(this.innerBody.dom.firstChild);this.colgroupTpl.insertFirst(this.innerCt,{columns:this.columns});
-this.hideHeaders?this.el.child(".x-grid3-header").setDisplayed("none"):!1!==this.enableHdMenu&&(this.hmenu=new Ext.menu.Menu({id:this.id+"-hctx"}),!1!==this.enableColumnHide&&(this.colMenu=new Ext.menu.Menu({id:this.id+"-hcols-menu"}),this.colMenu.on({scope:this,beforeshow:this.beforeColMenuShow,itemclick:this.handleHdMenuClick}),this.hmenu.add({itemId:"columns",hideOnClick:!1,text:this.columnsText,menu:this.colMenu,iconCls:"x-cols-icon"})),this.hmenu.on("itemclick",this.handleHdMenuClick,this))},
-setRootNode:function(a){a.attributes.uiProvider=Ext.ux.tree.TreeGridRootNodeUI;a=Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this,a);this.innerCt&&this.colgroupTpl.insertFirst(this.innerCt,{columns:this.columns});return a},clearInnerCt:function(){if(Ext.isIE)for(var a=this.innerCt.dom;a.firstChild;)a.removeChild(a.firstChild);else Ext.ux.tree.TreeGrid.superclass.clearInnerCt.call(this)},initEvents:function(){Ext.ux.tree.TreeGrid.superclass.initEvents.apply(this,arguments);this.mon(this.innerBody,
-"scroll",this.syncScroll,this);this.mon(this.innerHd,"click",this.handleHdDown,this);this.mon(this.mainHd,{scope:this,mouseover:this.handleHdOver,mouseout:this.handleHdOut})},onResize:function(a,b){Ext.ux.tree.TreeGrid.superclass.onResize.apply(this,arguments);var c=this.innerBody.dom,d=this.innerHd.dom;if(c&&(Ext.isNumber(b)&&(c.style.height=this.body.getHeight(!0)-d.offsetHeight+"px"),Ext.isNumber(a))){var e=Ext.num(this.scrollOffset,Ext.getScrollBarWidth());if(this.reserveScrollOffset||10<c.offsetWidth-
-c.clientWidth)this.setScrollOffset(e);else{var g=this;setTimeout(function(){g.setScrollOffset(10<c.offsetWidth-c.clientWidth?e:0)},10)}}},updateColumnWidths:function(){var a=this.columns,b=a.length,c=this.outerCt.query("colgroup"),d=c.length,e,g,f,h;for(f=0;f<b;f++){e=a[f];for(h=0;h<d;h++)g=c[h],g.childNodes[f].style.width=(e.hidden?0:e.width)+"px"}f=0;c=this.innerHd.query("td");for(len=c.length;f<len;f++)e=Ext.fly(c[f]),a[f]&&a[f].hidden?e.addClass("x-treegrid-hd-hidden"):e.removeClass("x-treegrid-hd-hidden");
-a=this.getTotalColumnWidth();Ext.fly(this.innerHd.dom.firstChild).setWidth(a+(this.scrollOffset||0));this.outerCt.select("table").setWidth(a);this.syncHeaderScroll()},getVisibleColumns:function(){var a=[],b=this.columns,c=b.length,d;for(d=0;d<c;d++)b[d].hidden||a.push(b[d]);return a},getTotalColumnWidth:function(){for(var a=0,b=0,c=this.getVisibleColumns(),d=c.length;b<d;b++)a+=c[b].width;return a},setScrollOffset:function(a){this.scrollOffset=a;this.updateColumnWidths()},handleHdDown:function(a,
-b){var c=a.getTarget(".x-treegrid-hd");if(c&&Ext.fly(b).hasClass("x-grid3-hd-btn")){var d=this.hmenu.items,e=this.columns,g=this.findHeaderIndex(c),e=e[g];a.stopEvent();Ext.fly(c).addClass("x-grid3-hd-menu-open");this.hdCtxIndex=g;this.fireEvent("headerbuttonclick",d,e,c,g);this.hmenu.on("hide",function(){Ext.fly(c).removeClass("x-grid3-hd-menu-open")},this,{single:!0});this.hmenu.show(b,"tl-bl?")}else c&&(g=this.findHeaderIndex(c),this.fireEvent("headerclick",this.columns[g],c,g))},handleHdOver:function(a,
-b){var c=a.getTarget(".x-treegrid-hd");if(c&&!this.headersDisabled){index=this.findHeaderIndex(c);this.activeHdRef=b;this.activeHdIndex=index;var d=Ext.get(c);this.activeHdRegion=d.getRegion();d.addClass("x-grid3-hd-over");if(this.activeHdBtn=d.child(".x-grid3-hd-btn"))this.activeHdBtn.dom.style.height=c.firstChild.offsetHeight-1+"px"}},handleHdOut:function(a,b){var c=a.getTarget(".x-treegrid-hd");if(c&&(!Ext.isIE||!a.within(c,!0)))this.activeHdRef=null,Ext.fly(c).removeClass("x-grid3-hd-over"),c.style.cursor=
-""},findHeaderIndex:function(a){a=a.dom||a;for(var b=a.parentNode.childNodes,c=0,d;d=b[c];c++)if(d==a)return c;return-1},beforeColMenuShow:function(){var a=this.columns,b=a.length,c,d;this.colMenu.removeAll();for(c=1;c<b;c++)d=a[c],!1!==d.hideable&&this.colMenu.add(new Ext.menu.CheckItem({itemId:"col-"+c,text:d.header,checked:!d.hidden,hideOnClick:!1,disabled:!1===d.hideable}))},handleHdMenuClick:function(a){var b=this.hdCtxIndex,c=a.getItemId();!1!==this.fireEvent("headermenuclick",this.columns[b],
-c,b)&&(b=c.substr(4),0<b&&this.columns[b]&&this.setColumnVisible(b,!a.checked));return!0},setColumnVisible:function(a,b){this.columns[a].hidden=!b;this.updateColumnWidths()},scrollToTop:function(){this.innerBody.dom.scrollTop=0;this.innerBody.dom.scrollLeft=0},syncScroll:function(){this.syncHeaderScroll();var a=this.innerBody.dom;this.fireEvent("bodyscroll",a.scrollLeft,a.scrollTop)},syncHeaderScroll:function(){var a=this.innerBody.dom;this.innerHd.dom.scrollLeft=a.scrollLeft;this.innerHd.dom.scrollLeft=
-a.scrollLeft},registerNode:function(a){Ext.ux.tree.TreeGrid.superclass.registerNode.call(this,a);!a.uiProvider&&(!a.isRoot&&!a.ui.isTreeGridNodeUI)&&(a.ui=new Ext.ux.tree.TreeGridNodeUI(a))}});Ext.reg("treegrid",Ext.ux.tree.TreeGrid);
-Ext.tree.ColumnResizer=Ext.extend(Ext.util.Observable,{minWidth:14,constructor:function(a){Ext.apply(this,a);Ext.tree.ColumnResizer.superclass.constructor.call(this)},init:function(a){this.tree=a;a.on("render",this.initEvents,this)},initEvents:function(a){a.mon(a.innerHd,"mousemove",this.handleHdMove,this);this.tracker=new Ext.dd.DragTracker({onBeforeStart:this.onBeforeStart.createDelegate(this),onStart:this.onStart.createDelegate(this),onDrag:this.onDrag.createDelegate(this),onEnd:this.onEnd.createDelegate(this),
-tolerance:3,autoStart:300});this.tracker.initEl(a.innerHd);a.on("beforedestroy",this.tracker.destroy,this.tracker)},handleHdMove:function(a,b){var c=a.getPageX(),d=a.getTarget(".x-treegrid-hd",3,!0);if(d){var e=d.getRegion(),g=d.dom.style,f=d.dom.parentNode;if(5>=c-e.left&&d.dom!==f.firstChild){for(c=d.dom.previousSibling;c&&Ext.fly(c).hasClass("x-treegrid-hd-hidden");)c=c.previousSibling;c&&(this.activeHd=Ext.get(c),g.cursor=Ext.isWebKit?"e-resize":"col-resize")}else if(5>=e.right-c){for(c=d.dom;c&&
-Ext.fly(c).hasClass("x-treegrid-hd-hidden");)c=c.previousSibling;c&&(this.activeHd=Ext.get(c),g.cursor=Ext.isWebKit?"w-resize":"col-resize")}else delete this.activeHd,g.cursor=""}},onBeforeStart:function(a){this.dragHd=this.activeHd;return!!this.dragHd},onStart:function(a){this.dragHeadersDisabled=this.tree.headersDisabled;this.tree.headersDisabled=!0;this.proxy=this.tree.body.createChild({cls:"x-treegrid-resizer"});this.proxy.setHeight(this.tree.body.getHeight());a=this.tracker.getXY()[0];this.hdX=
-this.dragHd.getX();this.hdIndex=this.tree.findHeaderIndex(this.dragHd);this.proxy.setX(this.hdX);this.proxy.setWidth(a-this.hdX);this.maxWidth=this.tree.outerCt.getWidth()-this.tree.innerBody.translatePoints(this.hdX).left},onDrag:function(a){a=this.tracker.getXY()[0];this.proxy.setWidth((a-this.hdX).constrain(this.minWidth,this.maxWidth))},onEnd:function(a){a=this.proxy.getWidth();var b=this.tree,c=this.dragHeadersDisabled;this.proxy.remove();delete this.dragHd;b.columns[this.hdIndex].width=a;b.updateColumnWidths();
-setTimeout(function(){b.headersDisabled=c},100)}});
-(function(){Ext.override(Ext.list.Column,{init:function(){var a=Ext.data.Types,b=this.sortType;this.type?Ext.isString(this.type)&&(this.type=Ext.data.Types[this.type.toUpperCase()]||a.AUTO):this.type=a.AUTO;Ext.isString(b)?this.sortType=Ext.data.SortTypes[b]:Ext.isEmpty(b)&&(this.sortType=this.type.sortType)}});Ext.tree.Column=Ext.extend(Ext.list.Column,{});Ext.tree.NumberColumn=Ext.extend(Ext.list.NumberColumn,{});Ext.tree.DateColumn=Ext.extend(Ext.list.DateColumn,{});Ext.tree.BooleanColumn=Ext.extend(Ext.list.BooleanColumn,
-{});Ext.reg("tgcolumn",Ext.tree.Column);Ext.reg("tgnumbercolumn",Ext.tree.NumberColumn);Ext.reg("tgdatecolumn",Ext.tree.DateColumn);Ext.reg("tgbooleancolumn",Ext.tree.BooleanColumn)})();Ext.ux.tree.TreeGridLoader=Ext.extend(Ext.tree.TreeLoader,{createNode:function(a){a.uiProvider||(a.uiProvider=Ext.ux.tree.TreeGridNodeUI);return Ext.tree.TreeLoader.prototype.createNode.call(this,a)}});
-Ext.ux.tree.TreeGridNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:!0,renderElements:function(a,b,c,d){var e=a.getOwnerTree(),g=e.columns,f=g[0],h,k,l;this.indentMarkup=a.parentNode?a.parentNode.ui.getChildIndent():"";k=['<tbody class="x-tree-node">','<tr ext:tree-node-id="',a.id,'" class="x-tree-node-el x-tree-node-leaf ',b.cls,'">','<td class="x-treegrid-col">','<span class="x-tree-node-indent">',this.indentMarkup,"</span>",'<img src="',this.emptyIcon,'" class="x-tree-ec-icon x-tree-elbow" />',
-'<img src="',b.icon||this.emptyIcon,'" class="x-tree-node-icon',b.icon?" x-tree-node-inline-icon":"",b.iconCls?" "+b.iconCls:"",'" unselectable="on" />','<a hidefocus="on" class="x-tree-node-anchor" href="',b.href?b.href:"#",'" tabIndex="1" ',b.hrefTarget?' target="'+b.hrefTarget+'"':"",">",'<span unselectable="on">',f.tpl?f.tpl.apply(b):b[f.dataIndex]||f.text,"</span></a>","</td>"];h=1;for(l=g.length;h<l;h++)f=g[h],k.push('<td class="x-treegrid-col ',f.cls?f.cls:"",'">','<div unselectable="on" class="x-treegrid-text"',
-f.align?' style="text-align: '+f.align+';"':"",">",f.tpl?f.tpl.apply(b):b[f.dataIndex],"</div>","</td>");k.push('</tr><tr class="x-tree-node-ct"><td colspan="',g.length,'">','<table class="x-treegrid-node-ct-table" cellpadding="0" cellspacing="0" style="table-layout: fixed; display: none; width: ',e.innerCt.getWidth(),'px;"><colgroup>');h=0;for(l=g.length;h<l;h++)k.push('<col style="width: ',g[h].hidden?0:g[h].width,'px;" />');k.push("</colgroup></table></td></tr></tbody>");!0!==d&&a.nextSibling&&
-a.nextSibling.ui.getEl()?this.wrap=Ext.DomHelper.insertHtml("beforeBegin",a.nextSibling.ui.getEl(),k.join("")):this.wrap=Ext.DomHelper.insertHtml("beforeEnd",c,k.join(""));this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1].firstChild.firstChild;a=this.elNode.firstChild.childNodes;this.indentNode=a[0];this.ecNode=a[1];this.iconNode=a[2];this.anchor=a[3];this.textNode=a[3].firstChild},animExpand:function(a){this.ctNode.style.display="";Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this,
-a)}});Ext.ux.tree.TreeGridRootNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:!0,render:function(){this.rendered||(this.wrap=this.ctNode=this.node.ownerTree.innerCt.dom,this.node.expanded=!0);if(Ext.isWebKit){var a=this.ctNode;a.style.tableLayout=null;(function(){a.style.tableLayout="fixed"}).defer(1)}},destroy:function(){this.elNode&&Ext.dd.Registry.unregister(this.elNode.id);delete this.node},collapse:Ext.emptyFn,expand:Ext.emptyFn});
-Ext.override(Ext.ux.tree.TreeGridNodeUI,{updateColumns:function(){if(this.rendered){var a=this.node.attributes,b=this.node.getOwnerTree().columns,c=b[0];this.anchor.firstChild.innerHTML=c.tpl?c.tpl.apply(a):a[c.dataIndex]||c.text;i=1;for(len=b.length;i<len;i++)c=b[i],this.elNode.childNodes[i].firstChild.innerHTML=c.tpl?c.tpl.apply(a):a[c.dataIndex]||c.text}}});
-Ext.tree.RenderColumn=Ext.extend(Ext.tree.Column,{constructor:function(a){a.tpl=a.tpl||new Ext.XTemplate("{"+a.dataIndex+":this.format}");a.tpl.format=a.renderer;a.tpl.col=this;Ext.tree.RenderColumn.superclass.constructor.call(this,a)}});Ext.reg("tgrendercolumn",Ext.tree.RenderColumn);Ext.ns("Ext.ux.tree");
-Ext.ux.tree.TreeGridSorter=Ext.extend(Ext.tree.TreeSorter,{sortClasses:["sort-asc","sort-desc"],sortAscText:"Sort Ascending",sortDescText:"Sort Descending",constructor:function(a,b){Ext.isObject(b)||(b={property:a.columns[0].dataIndex||"text",folderSort:!0});Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(this,arguments);this.tree=a;a.on("headerclick",this.onHeaderClick,this);a.ddAppendOnly=!0;var c=this;this.defaultSortFn=function(a,b){var g=c.dir&&"desc"==c.dir.toLowerCase(),f=c.property||
-"text",h=c.sortType,k=!0===c.caseSensitive,l=c.leafAttr||"leaf",t=a.attributes,p=b.attributes;if(c.folderSort){if(t[l]&&!p[l])return 1;if(!t[l]&&p[l])return-1}l=t[f];f=p[f];p=h?h(l):k?l:l.toUpperCase();v2=h?h(f):k?f:f.toUpperCase();return p<v2?g?1:-1:p>v2?g?-1:1:0};a.on("afterrender",this.onAfterTreeRender,this,{single:!0});a.on("headermenuclick",this.onHeaderMenuClick,this)},onAfterTreeRender:function(){this.tree.hmenu&&this.tree.hmenu.insert(0,{itemId:"asc",text:this.sortAscText,cls:"xg-hmenu-sort-asc"},
-{itemId:"desc",text:this.sortDescText,cls:"xg-hmenu-sort-desc"});this.updateSortIcon(0,"asc")},onHeaderMenuClick:function(a,b,c){if("asc"===b||"desc"===b)return this.onHeaderClick(a,null,c),!1},onHeaderClick:function(a,b,c){if(a&&!this.tree.headersDisabled){var d=this;d.property=a.dataIndex;d.dir=a.dir="desc"===a.dir?"asc":"desc";d.sortType=a.sortType;d.caseSensitive===Ext.isBoolean(a.caseSensitive)?a.caseSensitive:this.caseSensitive;d.sortFn=a.sortFn||this.defaultSortFn;this.tree.root.cascade(function(a){a.isLeaf()||
-d.updateSort(d.tree,a)});this.updateSortIcon(c,a.dir)}},updateSortIcon:function(a,b){var c=this.sortClasses;this.tree.innerHd.select("td").removeClass(c).item(a).addClass(c["desc"==b?1:0])}});
-Ext.ux.JSLoader=function(a){Ext.ux.JSLoader.scripts[++Ext.ux.JSLoader.index]={url:a.url,success:!0,jsLoadObj:null,options:a,onLoad:a.onLoad||Ext.emptyFn,onError:a.onError||Ext.ux.JSLoader.stdError,scope:a.scope||this};Ext.Ajax.request({url:a.url,scriptIndex:Ext.ux.JSLoader.index,success:function(a,c){var d=Ext.ux.JSLoader.scripts[c.scriptIndex];try{eval(a.responseText)}catch(e){d.success=!1,d.onError(d.options,e)}d.success&&d.onLoad.call(d.scope,d.options)},failure:function(a,c){var d=Ext.ux.JSLoader.scripts[c.scriptIndex];
-d.success=!1;d.onError(d.options,a.status)}})};Ext.ux.JSLoader.index=0;Ext.ux.JSLoader.scripts=[];Ext.ux.JSLoader.stdError=function(a,b){window.alert("Error loading script:\n\n"+a.url+"\n\nstatus: "+b)};
-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:!1,constructor:function(a){Ext.ux.Spinner.superclass.constructor.call(this,a);Ext.apply(this,a);this.mimicing=!1},init:function(a){this.field=a;a.afterMethod("onRender",this.doRender,this);a.afterMethod("onEnable",this.doEnable,this);a.afterMethod("onDisable",this.doDisable,
-this);a.afterMethod("afterRender",this.doAfterRender,this);a.afterMethod("onResize",this.doResize,this);a.afterMethod("onFocus",this.doFocus,this);a.beforeMethod("onDestroy",this.doDestroy,this)},doRender:function(a,b){var c=this.el=this.field.getEl(),d=this.field;d.wrap?this.wrap=d.wrap.addClass("x-form-field-wrap"):d.wrap=this.wrap=c.wrap({cls:"x-form-field-wrap"});this.trigger=this.wrap.createChild({tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.triggerClass});d.width||this.wrap.setWidth(c.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.proxy=this.trigger.createProxy("",this.splitter,!0);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()},doAfterRender:function(){var a;
-if(Ext.isIE&&this.el.getY()!=(a=this.trigger.getY()))this.el.position(),this.el.setY(a)},doEnable:function(){this.wrap&&(this.disabled=!1,this.wrap.removeClass(this.field.disabledClass))},doDisable:function(){this.wrap&&(this.disabled=!0,this.wrap.addClass(this.field.disabledClass),this.el.removeClass(this.field.disabledClass))},doResize:function(a,b){"number"==typeof a&&this.el.setWidth(a-this.trigger.getWidth());this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth())},doFocus:function(){this.mimicing||
-(this.wrap.addClass("x-trigger-wrap-focus"),this.mimicing=!0,Ext.get(Ext.isIE?document.body:document).on("mousedown",this.mimicBlur,this,{delay:10}),this.el.on("keydown",this.checkTab,this))},checkTab:function(a){a.getKey()==a.TAB&&this.triggerBlur()},mimicBlur:function(a){!this.wrap.contains(a.target)&&this.field.validateBlur(a)&&this.triggerBlur()},triggerBlur:function(){this.mimicing=!1;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")},initSpinner:function(){this.field.addEvents({spin:!0,spinup:!0,spindown:!0});this.keyNav=new Ext.KeyNav(this.el,{up:function(a){a.preventDefault();this.onSpinUp()},down:function(a){a.preventDefault();this.onSpinDown()},pageUp:function(a){a.preventDefault();this.onSpinUpAlternate()},
-pageDown:function(a){a.preventDefault();this.onSpinDownAlternate()},scope:this});this.repeater=new Ext.util.ClickRepeater(this.trigger,{accelerate:this.accelerate});this.field.mon(this.repeater,"click",this.onTriggerClick,this,{preventDefault:!0});this.field.mon(this.trigger,{mouseover:this.onMouseOver,mouseout:this.onMouseOut,mousemove:this.onMouseMove,mousedown:this.onMouseDown,mouseup:this.onMouseUp,scope:this,preventDefault:!0});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)},onMouseOver:function(){if(!this.disabled){var a=this.getMiddle();this.tmpHoverClass=Ext.EventObject.getPageY()<a?"x-form-spinner-overup":"x-form-spinner-overdown";this.trigger.addClass(this.tmpHoverClass)}},onMouseOut:function(){this.trigger.removeClass(this.tmpHoverClass)},onMouseMove:function(){if(!this.disabled){var a=
-this.getMiddle();Ext.EventObject.getPageY()>a&&"x-form-spinner-overup"==this.tmpHoverClass||Ext.EventObject.getPageY()}},onMouseDown:function(){if(!this.disabled){var a=this.getMiddle();this.tmpClickClass=Ext.EventObject.getPageY()<a?"x-form-spinner-clickup":"x-form-spinner-clickdown";this.trigger.addClass(this.tmpClickClass)}},onMouseUp:function(){this.trigger.removeClass(this.tmpClickClass)},onTriggerClick:function(){if(!this.disabled&&!this.el.dom.readOnly){var a=this.getMiddle();this["onSpin"+
-(Ext.EventObject.getPageY()<a?"Up":"Down")]()}},getMiddle:function(){var a=this.trigger.getTop(),b=this.trigger.getHeight();return a+b/2},isSpinnable:function(){return this.disabled||this.el.dom.readOnly?(Ext.EventObject.preventDefault(),!1):!0},handleMouseWheel:function(a){if(!1!=this.wrap.hasClass("x-trigger-wrap-focus")){var b=a.getWheelDelta();0<b?(this.onSpinUp(),a.stopEvent()):0>b&&(this.onSpinDown(),a.stopEvent())}},startDrag:function(){this.proxy.show();this._previousY=Ext.fly(this.dd.getDragEl()).getTop()},
-endDrag:function(){this.proxy.hide()},onDrag:function(){if(!this.disabled){var a=Ext.fly(this.dd.getDragEl()).getTop(),b="";this._previousY>a&&(b="Up");this._previousY<a&&(b="Down");if(""!=b)this["onSpin"+b]();this._previousY=a}},onSpinUp:function(){if(!1!=this.isSpinnable())if(!0==Ext.EventObject.shiftKey)this.onSpinUpAlternate();else this.spin(!1,!1),this.field.fireEvent("spin",this),this.field.fireEvent("spinup",this)},onSpinDown:function(){if(!1!=this.isSpinnable())if(!0==Ext.EventObject.shiftKey)this.onSpinDownAlternate();
-else this.spin(!0,!1),this.field.fireEvent("spin",this),this.field.fireEvent("spindown",this)},onSpinUpAlternate:function(){!1!=this.isSpinnable()&&(this.spin(!1,!0),this.field.fireEvent("spin",this),this.field.fireEvent("spinup",this))},onSpinDownAlternate:function(){!1!=this.isSpinnable()&&(this.spin(!0,!0),this.field.fireEvent("spin",this),this.field.fireEvent("spindown",this))},spin:function(a,b){var c=parseFloat(this.field.getValue()),d=!0==b?this.alternateIncrementValue:this.incrementValue;
-!0==a?c-=d:c+=d;c=isNaN(c)?this.defaultValue:c;c=this.fixBoundries(c);this.field.setRawValue(c)},fixBoundries:function(a){void 0!=this.field.minValue&&a<this.field.minValue&&(a=this.field.minValue);void 0!=this.field.maxValue&&a>this.field.maxValue&&(a=this.field.maxValue);return this.fixPrecision(a)},fixPrecision:function(a){var b=isNaN(a);return!this.field.allowDecimals||-1==this.field.decimalPrecision||b||!a?b?"":a:parseFloat(parseFloat(a).toFixed(this.field.decimalPrecision))},doDestroy:function(){this.trigger&&
-this.trigger.remove();this.wrap&&(this.wrap.remove(),delete this.field.wrap);this.splitter&&this.splitter.remove();this.dd&&(this.dd.unreg(),this.dd=null);this.proxy&&this.proxy.remove();this.repeater&&this.repeater.purgeListeners();this.mimicing&&Ext.get(Ext.isIE?document.body:document).un("mousedown",this.mimicBlur,this)}});Ext.form.Spinner=Ext.ux.Spinner;
-Ext.ux.StatusBar=Ext.extend(Ext.Toolbar,{cls:"x-statusbar",busyIconCls:"x-status-busy",busyText:"Loading...",autoClear:5E3,emptyText:"&nbsp;",activeThreadId:0,initComponent:function(){"right"==this.statusAlign&&(this.cls+=" x-status-right");Ext.ux.StatusBar.superclass.initComponent.call(this)},afterRender:function(){Ext.ux.StatusBar.superclass.afterRender.call(this);var a="right"==this.statusAlign;this.currIconCls=this.iconCls||this.defaultIconCls;this.statusEl=new Ext.Toolbar.TextItem({cls:"x-status-text "+
-(this.currIconCls||""),text:this.text||this.defaultText||""});a?(this.add("->"),this.add(this.statusEl)):(this.insert(0,this.statusEl),this.insert(1,"->"));this.doLayout()},setStatus:function(a){a=a||{};"string"==typeof a&&(a={text:a});void 0!==a.text&&this.setText(a.text);void 0!==a.iconCls&&this.setIcon(a.iconCls);if(a.clear){a=a.clear;var b=this.autoClear,c={useDefaults:!0,anim:!0};"object"==typeof a?(a=Ext.applyIf(a,c),a.wait&&(b=a.wait)):"number"==typeof a?(b=a,a=c):"boolean"==typeof a&&(a=c);
-a.threadId=this.activeThreadId;this.clearStatus.defer(b,this,[a])}return this},clearStatus:function(a){a=a||{};if(a.threadId&&a.threadId!==this.activeThreadId)return this;var b=a.useDefaults?this.defaultText:this.emptyText,c=a.useDefaults?this.defaultIconCls?this.defaultIconCls:"":"";a.anim?this.statusEl.el.fadeOut({remove:!1,useDisplay:!0,scope:this,callback:function(){this.setStatus({text:b,iconCls:c});this.statusEl.el.show()}}):(this.statusEl.hide(),this.setStatus({text:b,iconCls:c}),this.statusEl.show());
-return this},setText:function(a){this.activeThreadId++;this.text=a||"";this.rendered&&this.statusEl.setText(this.text);return this},getText:function(){return this.text},setIcon:function(a){this.activeThreadId++;a=a||"";this.rendered?(this.currIconCls&&(this.statusEl.removeClass(this.currIconCls),this.currIconCls=null),0<a.length&&(this.statusEl.addClass(a),this.currIconCls=a)):this.currIconCls=a;return this},showBusy:function(a){"string"==typeof a&&(a={text:a});a=Ext.applyIf(a||{},{text:this.busyText,
-iconCls:this.busyIconCls});return this.setStatus(a)}});Ext.reg("statusbar",Ext.ux.StatusBar);
diff --git a/deluge/ui/web/js/gettext.js b/deluge/ui/web/js/gettext.js
deleted file mode 100644
index 559577a..0000000
--- a/deluge/ui/web/js/gettext.js
+++ /dev/null
@@ -1,326 +0,0 @@
-GetText={maps:{},add:function(string,translation){this.maps[string]=translation},get:function(string){if (this.maps[string]){string=this.maps[string]} return string}};function _(string){return GetText.get(string)}GetText.add('10 KiB/s','${escape(_("10 KiB/s"))}')
-GetText.add('30 KiB/s','${escape(_("30 KiB/s"))}')
-GetText.add('300 KiB/s','${escape(_("300 KiB/s"))}')
-GetText.add('5 KiB/s','${escape(_("5 KiB/s"))}')
-GetText.add('80 KiB/s','${escape(_("80 KiB/s"))}')
-GetText.add('<b>IP</b> {0}','${escape(_("<b>IP</b> {0}"))}')
-GetText.add('About Deluge','${escape(_("About Deluge"))}')
-GetText.add('Active','${escape(_("Active"))}')
-GetText.add('Active Torrents','${escape(_("Active Torrents"))}')
-GetText.add('Add','${escape(_("Add"))}')
-GetText.add('Add Connection','${escape(_("Add Connection"))}')
-GetText.add('Add In Paused State','${escape(_("Add In Paused State"))}')
-GetText.add('Add Torrents','${escape(_("Add Torrents"))}')
-GetText.add('Add Tracker','${escape(_("Add Tracker"))}')
-GetText.add('Add from Url','${escape(_("Add from Url"))}')
-GetText.add('Add torrents in Paused state','${escape(_("Add torrents in Paused state"))}')
-GetText.add('Added','${escape(_("Added"))}')
-GetText.add('Address','${escape(_("Address"))}')
-GetText.add('All','${escape(_("All"))}')
-GetText.add('Allocating','${escape(_("Allocating"))}')
-GetText.add('Allow Remote Connections','${escape(_("Allow Remote Connections"))}')
-GetText.add('Allow the use of multiple filters at once','${escape(_("Allow the use of multiple filters at once"))}')
-GetText.add('Announce OK','${escape(_("Announce OK"))}')
-GetText.add('Announce Sent','${escape(_("Announce Sent"))}')
-GetText.add('Apply','${escape(_("Apply"))}')
-GetText.add('Author Email:','${escape(_("Author Email:"))}')
-GetText.add('Author:','${escape(_("Author:"))}')
-GetText.add('Auto Managed','${escape(_("Auto Managed"))}')
-GetText.add('Avail','${escape(_("Avail"))}')
-GetText.add('Back','${escape(_("Back"))}')
-GetText.add('Bandwidth','${escape(_("Bandwidth"))}')
-GetText.add('Be alerted about new releases','${escape(_("Be alerted about new releases"))}')
-GetText.add('Bottom','${escape(_("Bottom"))}')
-GetText.add('Browse','${escape(_("Browse"))}')
-GetText.add('Browse...','${escape(_("Browse..."))}')
-GetText.add('Cache','${escape(_("Cache"))}')
-GetText.add('Cache Expiry (seconds):','${escape(_("Cache Expiry (seconds):"))}')
-GetText.add('Cache Size (16 KiB Blocks):','${escape(_("Cache Size (16 KiB Blocks):"))}')
-GetText.add('Cancel','${escape(_("Cancel"))}')
-GetText.add('Certificate:','${escape(_("Certificate:"))}')
-GetText.add('Change Default Password','${escape(_("Change Default Password"))}')
-GetText.add('Change Successful','${escape(_("Change Successful"))}')
-GetText.add('Checking','${escape(_("Checking"))}')
-GetText.add('Client','${escape(_("Client"))}')
-GetText.add('Client:','${escape(_("Client:"))}')
-GetText.add('Close','${escape(_("Close"))}')
-GetText.add('Comment:','${escape(_("Comment:"))}')
-GetText.add('Complete Seen','${escape(_("Complete Seen"))}')
-GetText.add('Completed','${escape(_("Completed"))}')
-GetText.add('Confirm:','${escape(_("Confirm:"))}')
-GetText.add('Connect','${escape(_("Connect"))}')
-GetText.add('Connected','${escape(_("Connected"))}')
-GetText.add('Connection Limit','${escape(_("Connection Limit"))}')
-GetText.add('Connection Manager','${escape(_("Connection Manager"))}')
-GetText.add('Connection restored','${escape(_("Connection restored"))}')
-GetText.add('Connections','${escape(_("Connections"))}')
-GetText.add('Cookies','${escape(_("Cookies"))}')
-GetText.add('Copy','${escape(_("Copy"))}')
-GetText.add('Copy Magnet URI','${escape(_("Copy Magnet URI"))}')
-GetText.add('Copy of .torrent files to:','${escape(_("Copy of .torrent files to:"))}')
-GetText.add('Copyright 2007-2018 Deluge Team','${escape(_("Copyright 2007-2018 Deluge Team"))}')
-GetText.add('Create','${escape(_("Create"))}')
-GetText.add('Created By:','${escape(_("Created By:"))}')
-GetText.add('D/L Speed Limit','${escape(_("D/L Speed Limit"))}')
-GetText.add('DHT','${escape(_("DHT"))}')
-GetText.add('DHT Nodes','${escape(_("DHT Nodes"))}')
-GetText.add('Daemon','${escape(_("Daemon"))}')
-GetText.add('Daemon port:','${escape(_("Daemon port:"))}')
-GetText.add('Deluge','${escape(_("Deluge"))}')
-GetText.add('Details','${escape(_("Details"))}')
-GetText.add('Details:','${escape(_("Details:"))}')
-GetText.add('Disabled','${escape(_("Disabled"))}')
-GetText.add('Disconnect','${escape(_("Disconnect"))}')
-GetText.add('Down','${escape(_("Down"))}')
-GetText.add('Down Limit','${escape(_("Down Limit"))}')
-GetText.add('Down Speed','${escape(_("Down Speed"))}')
-GetText.add('Download','${escape(_("Download"))}')
-GetText.add('Download Folder','${escape(_("Download Folder"))}')
-GetText.add('Download Folder:','${escape(_("Download Folder:"))}')
-GetText.add('Download Speed','${escape(_("Download Speed"))}')
-GetText.add('Download to:','${escape(_("Download to:"))}')
-GetText.add('Downloaded','${escape(_("Downloaded"))}')
-GetText.add('Downloading','${escape(_("Downloading"))}')
-GetText.add('Downloading:','${escape(_("Downloading:"))}')
-GetText.add('Downloads','${escape(_("Downloads"))}')
-GetText.add('ETA','${escape(_("ETA"))}')
-GetText.add('Edit','${escape(_("Edit"))}')
-GetText.add('Edit Connection','${escape(_("Edit Connection"))}')
-GetText.add('Edit Tracker','${escape(_("Edit Tracker"))}')
-GetText.add('Edit Trackers','${escape(_("Edit Trackers"))}')
-GetText.add('Either','${escape(_("Either"))}')
-GetText.add('Enabled','${escape(_("Enabled"))}')
-GetText.add('Encryption','${escape(_("Encryption"))}')
-GetText.add('Error','${escape(_("Error"))}')
-GetText.add('Expand All','${escape(_("Expand All"))}')
-GetText.add('External IP Address','${escape(_("External IP Address"))}')
-GetText.add('Failed to download torrent','${escape(_("Failed to download torrent"))}')
-GetText.add('Failed to upload torrent','${escape(_("Failed to upload torrent"))}')
-GetText.add('File','${escape(_("File"))}')
-GetText.add('File Browser','${escape(_("File Browser"))}')
-GetText.add('Filename','${escape(_("Filename"))}')
-GetText.add('Files','${escape(_("Files"))}')
-GetText.add('Filters','${escape(_("Filters"))}')
-GetText.add('Find More','${escape(_("Find More"))}')
-GetText.add('Folders','${escape(_("Folders"))}')
-GetText.add('Force Proxy','${escape(_("Force Proxy"))}')
-GetText.add('Force Recheck','${escape(_("Force Recheck"))}')
-GetText.add('Force Use of Proxy','${escape(_("Force Use of Proxy"))}')
-GetText.add('Forced','${escape(_("Forced"))}')
-GetText.add('Forward','${escape(_("Forward"))}')
-GetText.add('Freespace in download folder','${escape(_("Freespace in download folder"))}')
-GetText.add('From:','${escape(_("From:"))}')
-GetText.add('Full Stream','${escape(_("Full Stream"))}')
-GetText.add('General','${escape(_("General"))}')
-GetText.add('GeoIP Database','${escape(_("GeoIP Database"))}')
-GetText.add('Global Bandwidth Usage','${escape(_("Global Bandwidth Usage"))}')
-GetText.add('HTTP','${escape(_("HTTP"))}')
-GetText.add('HTTP Auth','${escape(_("HTTP Auth"))}')
-GetText.add('Handshake','${escape(_("Handshake"))}')
-GetText.add('Hash:','${escape(_("Hash:"))}')
-GetText.add('Help','${escape(_("Help"))}')
-GetText.add('Hide Client Identity','${escape(_("Hide Client Identity"))}')
-GetText.add('High','${escape(_("High"))}')
-GetText.add('Home','${escape(_("Home"))}')
-GetText.add('Homepage:','${escape(_("Homepage:"))}')
-GetText.add('Host','${escape(_("Host"))}')
-GetText.add('Host:','${escape(_("Host:"))}')
-GetText.add('I2P','${escape(_("I2P"))}')
-GetText.add('Ignore limits on local network','${escape(_("Ignore limits on local network"))}')
-GetText.add('Ignore slow torrents','${escape(_("Ignore slow torrents"))}')
-GetText.add('Incoming Address','${escape(_("Incoming Address"))}')
-GetText.add('Incoming Port','${escape(_("Incoming Port"))}')
-GetText.add('Incoming:','${escape(_("Incoming:"))}')
-GetText.add('Infohash','${escape(_("Infohash"))}')
-GetText.add('Install','${escape(_("Install"))}')
-GetText.add('Install Plugin','${escape(_("Install Plugin"))}')
-GetText.add('Interface','${escape(_("Interface"))}')
-GetText.add('Invalid Password','${escape(_("Invalid Password"))}')
-GetText.add('KiB/s','${escape(_("KiB/s"))}')
-GetText.add('LSD','${escape(_("LSD"))}')
-GetText.add('Labels','${escape(_("Labels"))}')
-GetText.add('Language','${escape(_("Language"))}')
-GetText.add('Last Transfer','${escape(_("Last Transfer"))}')
-GetText.add('Level:','${escape(_("Level:"))}')
-GetText.add('Loading','${escape(_("Loading"))}')
-GetText.add('Login','${escape(_("Login"))}')
-GetText.add('Login Failed','${escape(_("Login Failed"))}')
-GetText.add('Logout','${escape(_("Logout"))}')
-GetText.add('Lost Connection','${escape(_("Lost Connection"))}')
-GetText.add('Lost connection to webserver','${escape(_("Lost connection to webserver"))}')
-GetText.add('Low','${escape(_("Low"))}')
-GetText.add('Max Connections','${escape(_("Max Connections"))}')
-GetText.add('Max Connections:','${escape(_("Max Connections:"))}')
-GetText.add('Max Down Speed','${escape(_("Max Down Speed"))}')
-GetText.add('Max Download Speed:','${escape(_("Max Download Speed:"))}')
-GetText.add('Max Up Speed','${escape(_("Max Up Speed"))}')
-GetText.add('Max Upload Slots','${escape(_("Max Upload Slots"))}')
-GetText.add('Max Upload Slots:','${escape(_("Max Upload Slots:"))}')
-GetText.add('Max Upload Speed:','${escape(_("Max Upload Speed:"))}')
-GetText.add('Maximum Connection Attempts per Second:','${escape(_("Maximum Connection Attempts per Second:"))}')
-GetText.add('Maximum Connections:','${escape(_("Maximum Connections:"))}')
-GetText.add('Maximum Download Speed (KiB/s):','${escape(_("Maximum Download Speed (KiB/s):"))}')
-GetText.add('Maximum Half-Open Connections:','${escape(_("Maximum Half-Open Connections:"))}')
-GetText.add('Maximum Upload Slots','${escape(_("Maximum Upload Slots"))}')
-GetText.add('Maximum Upload Slots:','${escape(_("Maximum Upload Slots:"))}')
-GetText.add('Maximum Upload Speed (KiB/s):','${escape(_("Maximum Upload Speed (KiB/s):"))}')
-GetText.add('Mixed','${escape(_("Mixed"))}')
-GetText.add('Move','${escape(_("Move"))}')
-GetText.add('Move Completed Folder','${escape(_("Move Completed Folder"))}')
-GetText.add('Move Completed:','${escape(_("Move Completed:"))}')
-GetText.add('Move Download Folder','${escape(_("Move Download Folder"))}')
-GetText.add('Move completed to:','${escape(_("Move completed to:"))}')
-GetText.add('NAT-PMP','${escape(_("NAT-PMP"))}')
-GetText.add('Name','${escape(_("Name"))}')
-GetText.add('Name:','${escape(_("Name:"))}')
-GetText.add('Network','${escape(_("Network"))}')
-GetText.add('Network Extras','${escape(_("Network Extras"))}')
-GetText.add('Never','${escape(_("Never"))}')
-GetText.add('New Torrents','${escape(_("New Torrents"))}')
-GetText.add('New:','${escape(_("New:"))}')
-GetText.add('None','${escape(_("None"))}')
-GetText.add('Normal','${escape(_("Normal"))}')
-GetText.add('Not Connected','${escape(_("Not Connected"))}')
-GetText.add('Not a valid torrent','${escape(_("Not a valid torrent"))}')
-GetText.add('OK','${escape(_("OK"))}')
-GetText.add('Off','${escape(_("Off"))}')
-GetText.add('Offline','${escape(_("Offline"))}')
-GetText.add('Old:','${escape(_("Old:"))}')
-GetText.add('On','${escape(_("On"))}')
-GetText.add('Online','${escape(_("Online"))}')
-GetText.add('Options','${escape(_("Options"))}')
-GetText.add('Other','${escape(_("Other"))}')
-GetText.add('Outgoing Interface','${escape(_("Outgoing Interface"))}')
-GetText.add('Outgoing Ports','${escape(_("Outgoing Ports"))}')
-GetText.add('Outgoing:','${escape(_("Outgoing:"))}')
-GetText.add('Owner','${escape(_("Owner"))}')
-GetText.add('Password','${escape(_("Password"))}')
-GetText.add('Password:','${escape(_("Password:"))}')
-GetText.add('Path:','${escape(_("Path:"))}')
-GetText.add('Pause','${escape(_("Pause"))}')
-GetText.add('Pause torrent','${escape(_("Pause torrent"))}')
-GetText.add('Paused','${escape(_("Paused"))}')
-GetText.add('Peer Exchange','${escape(_("Peer Exchange"))}')
-GetText.add('Peer TOS Byte:','${escape(_("Peer TOS Byte:"))}')
-GetText.add('Peers','${escape(_("Peers"))}')
-GetText.add('Per Torrent Bandwidth Usage','${escape(_("Per Torrent Bandwidth Usage"))}')
-GetText.add('Periodically check the website for new releases','${escape(_("Periodically check the website for new releases"))}')
-GetText.add('Plugin','${escape(_("Plugin"))}')
-GetText.add('Plugin Egg','${escape(_("Plugin Egg"))}')
-GetText.add('Plugins','${escape(_("Plugins"))}')
-GetText.add('Port','${escape(_("Port"))}')
-GetText.add('Port:','${escape(_("Port:"))}')
-GetText.add('Pre-allocate disk space','${escape(_("Pre-allocate disk space"))}')
-GetText.add('Preallocate Disk Space','${escape(_("Preallocate Disk Space"))}')
-GetText.add('Prefer seeding torrents','${escape(_("Prefer seeding torrents"))}')
-GetText.add('Preferences','${escape(_("Preferences"))}')
-GetText.add('Prioritize First/Last','${escape(_("Prioritize First/Last"))}')
-GetText.add('Prioritize First/Last Pieces','${escape(_("Prioritize First/Last Pieces"))}')
-GetText.add('Prioritize first and last pieces of torrent','${escape(_("Prioritize first and last pieces of torrent"))}')
-GetText.add('Priority','${escape(_("Priority"))}')
-GetText.add('Private','${escape(_("Private"))}')
-GetText.add('Private Key:','${escape(_("Private Key:"))}')
-GetText.add('Progress','${escape(_("Progress"))}')
-GetText.add('Protocol Traffic Download/Upload','${escape(_("Protocol Traffic Download/Upload"))}')
-GetText.add('Proxy','${escape(_("Proxy"))}')
-GetText.add('Proxy Hostnames','${escape(_("Proxy Hostnames"))}')
-GetText.add('Proxy Peers','${escape(_("Proxy Peers"))}')
-GetText.add('Proxy Trackers','${escape(_("Proxy Trackers"))}')
-GetText.add('Public','${escape(_("Public"))}')
-GetText.add('Queue','${escape(_("Queue"))}')
-GetText.add('Queue to top','${escape(_("Queue to top"))}')
-GetText.add('Queued','${escape(_("Queued"))}')
-GetText.add('Rate limit IP overhead','${escape(_("Rate limit IP overhead"))}')
-GetText.add('Ratio','${escape(_("Ratio"))}')
-GetText.add('Refresh','${escape(_("Refresh"))}')
-GetText.add('Remaining','${escape(_("Remaining"))}')
-GetText.add('Remove','${escape(_("Remove"))}')
-GetText.add('Remove Torrent','${escape(_("Remove Torrent"))}')
-GetText.add('Remove With Data','${escape(_("Remove With Data"))}')
-GetText.add('Remove at ratio','${escape(_("Remove at ratio"))}')
-GetText.add('Remove torrent','${escape(_("Remove torrent"))}')
-GetText.add('Resume','${escape(_("Resume"))}')
-GetText.add('Save','${escape(_("Save"))}')
-GetText.add('Seeding','${escape(_("Seeding"))}')
-GetText.add('Seeding Rotation','${escape(_("Seeding Rotation"))}')
-GetText.add('Seeding:','${escape(_("Seeding:"))}')
-GetText.add('Seeds','${escape(_("Seeds"))}')
-GetText.add('Seeds:Peers','${escape(_("Seeds:Peers"))}')
-GetText.add('Select an egg','${escape(_("Select an egg"))}')
-GetText.add('Sequential Download','${escape(_("Sequential Download"))}')
-GetText.add('Sequential download','${escape(_("Sequential download"))}')
-GetText.add('Server','${escape(_("Server"))}')
-GetText.add('Server:','${escape(_("Server:"))}')
-GetText.add('Session Timeout:','${escape(_("Session Timeout:"))}')
-GetText.add('Set Maximum Connections','${escape(_("Set Maximum Connections"))}')
-GetText.add('Set Maximum Download Speed','${escape(_("Set Maximum Download Speed"))}')
-GetText.add('Set Maximum Upload Speed','${escape(_("Set Maximum Upload Speed"))}')
-GetText.add('Settings','${escape(_("Settings"))}')
-GetText.add('Share Ratio Reached','${escape(_("Share Ratio Reached"))}')
-GetText.add('Share Ratio:','${escape(_("Share Ratio:"))}')
-GetText.add('Shared','${escape(_("Shared"))}')
-GetText.add('Show filters with zero torrents','${escape(_("Show filters with zero torrents"))}')
-GetText.add('Show session speed in titlebar','${escape(_("Show session speed in titlebar"))}')
-GetText.add('Size','${escape(_("Size"))}')
-GetText.add('Skip','${escape(_("Skip"))}')
-GetText.add('Skip File Hash Check','${escape(_("Skip File Hash Check"))}')
-GetText.add('Socks4','${escape(_("Socks4"))}')
-GetText.add('Socks5','${escape(_("Socks5"))}')
-GetText.add('Socks5 Auth','${escape(_("Socks5 Auth"))}')
-GetText.add('Start Daemon','${escape(_("Start Daemon"))}')
-GetText.add('State','${escape(_("State"))}')
-GetText.add('States','${escape(_("States"))}')
-GetText.add('Status','${escape(_("Status"))}')
-GetText.add('Status:','${escape(_("Status:"))}')
-GetText.add('Stop Daemon','${escape(_("Stop Daemon"))}')
-GetText.add('Stop seed at ratio:','${escape(_("Stop seed at ratio:"))}')
-GetText.add('Super Seed','${escape(_("Super Seed"))}')
-GetText.add('Super Seeding','${escape(_("Super Seeding"))}')
-GetText.add('System Default','${escape(_("System Default"))}')
-GetText.add('System Information','${escape(_("System Information"))}')
-GetText.add('The connection to the webserver has been lost!','${escape(_("The connection to the webserver has been lost!"))}')
-GetText.add('Tier','${escape(_("Tier"))}')
-GetText.add('Time (m):','${escape(_("Time (m):"))}')
-GetText.add('Time Ratio:','${escape(_("Time Ratio:"))}')
-GetText.add('To:','${escape(_("To:"))}')
-GetText.add('Top','${escape(_("Top"))}')
-GetText.add('Total Files:','${escape(_("Total Files:"))}')
-GetText.add('Total Size:','${escape(_("Total Size:"))}')
-GetText.add('Total:','${escape(_("Total:"))}')
-GetText.add('Tracker','${escape(_("Tracker"))}')
-GetText.add('Tracker Host','${escape(_("Tracker Host"))}')
-GetText.add('Tracker:','${escape(_("Tracker:"))}')
-GetText.add('Trackers','${escape(_("Trackers"))}')
-GetText.add('Trackers:','${escape(_("Trackers:"))}')
-GetText.add('Type Of Service','${escape(_("Type Of Service"))}')
-GetText.add('Type:','${escape(_("Type:"))}')
-GetText.add('U/L Speed Limit','${escape(_("U/L Speed Limit"))}')
-GetText.add('UPnP','${escape(_("UPnP"))}')
-GetText.add('Unable to add host: {0}','${escape(_("Unable to add host: {0}"))}')
-GetText.add('Unable to edit host','${escape(_("Unable to edit host"))}')
-GetText.add('Unlimited','${escape(_("Unlimited"))}')
-GetText.add('Up','${escape(_("Up"))}')
-GetText.add('Up Limit','${escape(_("Up Limit"))}')
-GetText.add('Up Speed','${escape(_("Up Speed"))}')
-GetText.add('Update Tracker','${escape(_("Update Tracker"))}')
-GetText.add('Updates','${escape(_("Updates"))}')
-GetText.add('Upload Slot Limit','${escape(_("Upload Slot Limit"))}')
-GetText.add('Upload Speed','${escape(_("Upload Speed"))}')
-GetText.add('Uploaded','${escape(_("Uploaded"))}')
-GetText.add('Uploading your plugin...','${escape(_("Uploading your plugin..."))}')
-GetText.add('Uploading your torrent...','${escape(_("Uploading your torrent..."))}')
-GetText.add('Url','${escape(_("Url"))}')
-GetText.add('Use Random Port','${escape(_("Use Random Port"))}')
-GetText.add('Use Random Ports','${escape(_("Use Random Ports"))}')
-GetText.add('Username:','${escape(_("Username:"))}')
-GetText.add('Version','${escape(_("Version"))}')
-GetText.add('Version:','${escape(_("Version:"))}')
-GetText.add('Warning','${escape(_("Warning"))}')
-GetText.add('WebUI Language Changed','${escape(_("WebUI Language Changed"))}')
-GetText.add('WebUI Password','${escape(_("WebUI Password"))}')
-GetText.add('Yes, please send anonymous statistics','${escape(_("Yes, please send anonymous statistics"))}')
-GetText.add('You entered an incorrect password','${escape(_("You entered an incorrect password"))}')
-GetText.add('Your old password was incorrect!','${escape(_("Your old password was incorrect!"))}')
-GetText.add('Your password was successfully changed!','${escape(_("Your password was successfully changed!"))}')
-GetText.add('libtorrent:','${escape(_("libtorrent:"))}')
-GetText.add('n/a','${escape(_("n/a"))}')