      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 })();