      1 /*
      2 Script: Deluge.EditTrackers.js
      3     Contains the edit trackers window.
      4
      5 Copyright:
      6 	(C) Damien Churchill 2009 <damoxc@gmail.com>
      7 	This program is free software; you can redistribute it and/or modify
      8 	it under the terms of the GNU General Public License as published by
      9 	the Free Software Foundation; either version 3, or (at your option)
     10 	any later version.
     11
     12 	This program is distributed in the hope that it will be useful,
     13 	but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 	GNU General Public License for more details.
     16
     17 	You should have received a copy of the GNU General Public License
     18 	along with this program.  If not, write to:
     19 		The Free Software Foundation, Inc.,
     20 		51 Franklin Street, Fifth Floor
     21 		Boston, MA  02110-1301, USA.
     22 #
     23 #    In addition, as a special exception, the copyright holders give
     24 #    permission to link the code of portions of this program with the OpenSSL
     25 #    library.
     26 #    You must obey the GNU General Public License in all respects for all of
     27 #    the code used other than OpenSSL. If you modify file(s) with this
     28 #    exception, you may extend this exception to your version of the file(s),
     29 #    but you are not obligated to do so. If you do not wish to do so, delete
     30 #    this exception statement from your version. If you delete this exception
     31 #    statement from all source files in the program, then also delete it here.
     32 #
     33 */
     34
     35 (function() {
     36 	Ext.deluge.AddTracker = Ext.extend(Ext.Window, {
     37 		constructor: function(config) {
     38 			config = Ext.apply({
     39 				title: _('Add Tracker'),
     40 				width: 375,
     41 				height: 150,
     42 				bodyStyle: 'padding: 5px',
     43 				layout: 'fit',
     44 				buttonAlign: 'right',
     45 				closeAction: 'hide',
     46 				closable: true,
     47 				iconCls: 'x-deluge-edit-trackers',
     48 				plain: true,
     49 				resizable: false
     50 			}, config);
     51 			Ext.deluge.AddTracker.superclass.constructor.call(this, config);
     52 		},
     53
     54 		initComponent: function() {
     55 			Ext.deluge.AddTracker.superclass.initComponent.call(this);
     56
     57 			this.addButton(_('Cancel'), this.onCancel, this);
     58 			this.addButton(_('Add'), this.onAdd, this);
     59 			this.addEvents('add');
     60
     61 			this.form = this.add({
     62 				xtype: 'form',
     63 				defaultType: 'textarea',
     64 				baseCls: 'x-plain',
     65 				labelWidth: 55,
     66 				items: [{
     67 					fieldLabel: _('Trackers'),
     68 					name: 'trackers',
     69 					anchor: '100%'
     70 				}]
     71 			})
     72 		},
     73
     74 		onCancel: function() {
     75 			this.form.getForm().findField('trackers').setValue('');
     76 			this.hide();
     77 		},
     78
     79 		onAdd: function() {
     80 			var trackers = this.form.getForm().findField('trackers').getValue();
     81 			trackers = trackers.split('\n');
     82
     83 			var cleaned = [];
     84 			Ext.each(trackers, function(tracker) {
     85 				if (Ext.form.VTypes.url(tracker)) {
     86 					cleaned.push(tracker);
     87 				}
     88 			}, this);
     89 			this.fireEvent('add', cleaned);
     90 			this.hide();
     91 			this.form.getForm().findField('trackers').setValue('');
     92 		}
     93 	});
     94
     95 	Ext.deluge.EditTracker = Ext.extend(Ext.Window, {
     96 		constructor: function(config) {
     97 			config = Ext.apply({
     98 				title: _('Edit Tracker'),
     99 				width: 375,
    100 				height: 110,
    101 				bodyStyle: 'padding: 5px',
    102 				layout: 'fit',
    103 				buttonAlign: 'right',
    104 				closeAction: 'hide',
    105 				closable: true,
    106 				iconCls: 'x-deluge-edit-trackers',
    107 				plain: true,
    108 				resizable: false
    109 			}, config);
    110 			Ext.deluge.EditTracker.superclass.constructor.call(this, config);
    111 		},
    112
    113 		initComponent: function() {
    114 			Ext.deluge.EditTracker.superclass.initComponent.call(this);
    115
    116 			this.addButton(_('Cancel'), this.onCancel, this);
    117 			this.addButton(_('Save'), this.onSave, this);
    118 			this.on('hide', this.onHide, this);
    119
    120 			this.form = this.add({
    121 				xtype: 'form',
    122 				defaultType: 'textfield',
    123 				baseCls: 'x-plain',
    124 				labelWidth: 55,
    125 				items: [{
    126 					fieldLabel: _('Tracker'),
    127 					name: 'tracker',
    128 					anchor: '100%'
    129 				}]
    130 			});
    131 		},
    132
    133 		show: function(record) {
    134 			Ext.deluge.EditTracker.superclass.show.call(this);
    135
    136 			this.record = record;
    137 			this.form.getForm().findField('tracker').setValue(record.data['url']);
    138 		},
    139
    140 		onCancel: function() {
    141 			this.hide();
    142 		},
    143
    144 		onHide: function() {
    145 			this.form.getForm().findField('tracker').setValue('');
    146 		},
    147
    148 		onSave: function() {
    149 			var url = this.form.getForm().findField('tracker').getValue();
    150 			this.record.set('url', url);
    151 			this.record.commit();
    152 			this.hide();
    153 		}
    154 	});
    155
    156 	Ext.deluge.EditTrackers = Ext.extend(Ext.Window, {
    157
    158 		constructor: function(config) {
    159 			config = Ext.apply({
    160 				title: _('Edit Trackers'),
    161 				width: 350,
    162 				height: 220,
    163 				bodyStyle: 'padding: 5px',
    164 				layout: 'fit',
    165 				buttonAlign: 'right',
    166 				closeAction: 'hide',
    167 				closable: true,
    168 				iconCls: 'x-deluge-edit-trackers',
    169 				plain: true,
    170 				resizable: true
    171 			}, config);
    172 			Ext.deluge.EditTrackers.superclass.constructor.call(this, config);
    173 		},
    174
    175 		initComponent: function() {
    176 			Ext.deluge.EditTrackers.superclass.initComponent.call(this);
    177
    178 			this.addButton(_('Cancel'), this.onCancel, this);
    179 			this.addButton(_('Ok'), this.onOk, this);
    180 			this.addEvents('save');
    181
    182 			this.on('show', this.onShow, this);
    183 			this.on('save', this.onSave, this);
    184
    185 			this.addWindow = new Ext.deluge.AddTracker();
    186 			this.addWindow.on('add', this.onAddTrackers, this);
    187 			this.editWindow = new Ext.deluge.EditTracker();
    188
    189 			this.grid = this.add({
    190 				xtype: 'grid',
    191 				store: new Ext.data.SimpleStore({
    192 					fields: [
    193 						{name: 'tier', mapping: 0},
    194 						{name: 'url', mapping: 1}
    195 					]
    196 				}),
    197 				columns: [{
    198 					header: _('Tier'),
    199 					width: 50,
    200 					sortable: true,
    201 					renderer: fplain,
    202 					dataIndex: 'tier'
    203 				}, {
    204 					id:'tracker',
    205 					header: _('Tracker'),
    206 					sortable: true,
    207 					renderer: fplain,
    208 					dataIndex: 'url'
    209 				}],
    210 				stripeRows: true,
    211 				selModel: new Ext.grid.RowSelectionModel({
    212 					singleSelect: true,
    213 					listeners: {
    214 						'selectionchange': {fn: this.onSelect, scope: this}
    215 					}
    216 				}),
    217 				autoExpandColumn: 'tracker',
    218 				deferredRender:false,
    219 				autoScroll:true,
    220 				margins: '0 0 0 0',
    221 				bbar: new Ext.Toolbar({
    222 					items: [
    223 						{
    224 							cls: 'x-btn-text-icon',
    225 							text: _('Up'),
    226 							icon: '/icons/up.png',
    227 							handler: this.onUp,
    228 							scope: this
    229 						}, {
    230 							cls: 'x-btn-text-icon',
    231 							text: _('Down'),
    232 							icon: '/icons/down.png',
    233 							handler: this.onDown,
    234 							scope: this
    235 						}, '->', {
    236 							cls: 'x-btn-text-icon',
    237 							text: _('Add'),
    238 							icon: '/icons/add.png',
    239 							handler: this.onAdd,
    240 							scope: this
    241 						}, {
    242 							cls: 'x-btn-text-icon',
    243 							text: _('Edit'),
    244 							icon: '/icons/edit_trackers.png',
    245 							handler: this.onEdit,
    246 							scope: this
    247 						}, {
    248 							cls: 'x-btn-text-icon',
    249 							text: _('Remove'),
    250 							icon: '/icons/remove.png',
    251 							handler: this.onRemove,
    252 							scope: this
    253 						}
    254 					]
    255 				})
    256 			});
    257 		},
    258
    259 		onAdd: function() {
    260 			this.addWindow.show();
    261 		},
    262
    263 		onAddTrackers: function(trackers) {
    264 			var store = this.grid.getStore();
    265 			Ext.each(trackers, function(tracker) {
    266 				var duplicate = false, heightestTier = -1;
    267 				store.each(function(record) {
    268 					if (record.get('tier') > heightestTier) {
    269 						heightestTier = record.get('tier');
    270 					}
    271 					if (tracker == record.get('tracker')) {
    272 						duplicate = true;
    273 						return false;
    274 					}
    275 				}, this);
    276 				if (!duplicate) {
    277 					store.loadData([[heightestTier + 1, tracker]], true);
    278 				}
    279 			}, this);
    280 		},
    281
    282 		onCancel: function() {
    283 			this.hide();
    284 		},
    285
    286 		onEdit: function() {
    287 			var r = this.grid.getSelectionModel().getSelected();
    288 			this.editWindow.show(r);
    289 		},
    290
    291 		onHide: function() {
    292 			this.grid.getStore().removeAll();
    293 		},
    294
    295 		onOk: function() {
    296 			var trackers = [];
    297 			this.grid.getStore().each(function(record) {
    298 				trackers.push({
    299 					'tier': record.get('tier'),
    300 					'url': record.get('url')
    301 				})
    302 			}, this);
    303
    304 			Deluge.Client.core.set_torrent_trackers(this.torrentId, trackers, {
    305 				failure: this.onSaveFail,
    306 				scope: this
    307 			});
    308
    309 			this.hide();
    310 		},
    311
    312 		onRemove: function() {
    313 			// Remove from the grid
    314 			var r = this.grid.getSelectionModel().getSelected();
    315 			this.grid.getStore().remove(r);
    316 		},
    317
    318 		onRequestComplete: function(status) {
    319 			var trackers = [];
    320 			Ext.each(status['trackers'], function(tracker) {
    321 				trackers.push([tracker['tier'], tracker['url']]);
    322 			});
    323 			this.grid.getStore().loadData(trackers);
    324 		},
    325
    326 		onSaveFail: function() {
    327
    328 		},
    329
    330 		onSelect: function(sm) {
    331 			if (sm.hasSelection()) {
    332 				this.grid.getBottomToolbar().items.get(4).enable();
    333 			}
    334 		},
    335
    336 		onShow: function() {
    337 			this.grid.getBottomToolbar().items.get(4).disable();
    338 			var r = Deluge.Torrents.getSelected();
    339 			this.torrentId = r.id;
    340 			Deluge.Client.core.get_torrent_status(r.id, ['trackers'], {
    341 				success: this.onRequestComplete,
    342 				scope: this
    343 			});
    344 		}
    345 	});
    346 	Deluge.EditTrackers = new Ext.deluge.EditTrackers();
    347 })();