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