2
Script: deluge-details.js
3
Contains the tabs for the torrent details.
6
* Copyright (C) Damien Churchill 2008 <damoxc@gmail.com>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 3, or (at your option)
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, write to:
20
* The Free Software Foundation, Inc.,
21
* 51 Franklin Street, Fifth Floor
22
* Boston, MA 02110-1301, USA.
24
# In addition, as a special exception, the copyright holders give
25
# permission to link the code of portions of this program with the OpenSSL
27
# You must obey the GNU General Public License in all respects for all of
28
# the code used other than OpenSSL. If you modify file(s) with this
29
# exception, you may extend this exception to your version of the file(s),
30
# but you are not obligated to do so. If you do not wish to do so, delete
31
# this exception statement from your version. If you delete this exception
32
# statement from all source files in the program, then also delete it here.
38
Deluge.Widgets.Details = new Class({
39
Extends: Widgets.Tabs,
41
initialize: function() {
42
this.parent($$('#details .mooui-tabs')[0]);
44
this.statistics = new Deluge.Widgets.StatisticsPage();
45
this.details = new Deluge.Widgets.DetailsPage();
46
this.files = new Deluge.Widgets.FilesPage();
47
this.peers = new Deluge.Widgets.PeersPage();
48
this.options = new Deluge.Widgets.OptionsPage();
50
this.addPage(this.statistics);
51
this.addPage(this.details);
52
this.addPage(this.files);
53
this.addPage(this.peers);
54
this.addPage(this.options);
55
this.addEvent('pageChanged', function(e) {
56
this.update(this.torrentId);
57
}.bindWithEvent(this));
58
this.addEvent('resize', this.resized.bindWithEvent(this));
60
this.files.addEvent('menuAction', function(e) {
62
this.files.grid.getSelected().each(function(file) {
63
files.push(file.fileIndex);
66
this.fireEvent('filesAction', e);
67
}.bindWithEvent(this));
71
0: Deluge.Keys.Statistics,
72
1: Deluge.Keys.Details,
75
4: Deluge.Keys.Options
79
this.pages.each(function(page) {
80
page.element.getChildren().each(function(el) {
81
el.set('opacity', 0.5);
83
if (page.clear) page.clear();
87
update: function(torrentId) {
88
this.torrentId = torrentId;
89
if (!this.torrentId) {
93
var keys = this.keys[this.currentPage], page = this.pages[this.currentPage];
94
Deluge.Client.get_torrent_status(torrentId, keys, {
95
onSuccess: function(torrent) {
96
torrent.id = torrentId;
97
if (page.update) page.update(torrent);
98
page.element.getChildren().each(function(el) {
101
}.bindWithEvent(this)
105
resized: function(event) {
106
this.pages.each(function(page) {
107
page.getSizeModifiers();
109
width: event.width - page.element.modifiers.x,
110
height: event.height - page.element.modifiers.y - 28
116
Deluge.Widgets.StatisticsPage = new Class({
117
Extends: Widgets.TabPage,
120
url: '/template/render/html/tab_statistics.html'
123
initialize: function() {
124
this.parent(_('Statistics'));
125
this.addEvent('loaded', this.onLoad.bindWithEvent(this));
128
onLoad: function(e) {
129
this.element.id = 'statistics';
130
this.bar = new Widgets.ProgressBar();
131
this.bar.element.inject(this.element, 'top');
132
this.bar.set('width', this.getWidth() - 12);
133
this.bar.update('', 0);
134
this.addEvent('resize', this.onResize.bindWithEvent(this));
137
onResize: function(e) {
138
if (!$defined(this.bar)) return;
139
this.bar.set('width', this.getWidth() - 12);
143
if (this.bar) this.bar.update('', 0);
144
this.element.getElements('dd').each(function(item) {
145
item.set('text', '');
149
update: function(torrent) {
151
downloaded: torrent.total_done.toBytes()+' ('+torrent.total_payload_download.toBytes()+')',
152
uploaded: torrent.total_uploaded.toBytes()+' ('+torrent.total_payload_upload.toBytes()+')',
153
share: torrent.ratio.toFixed(3),
154
announce: torrent.next_announce.toTime(),
155
tracker_status: torrent.tracker_status,
156
downspeed: torrent.download_payload_rate.toSpeed(),
157
upspeed: torrent.upload_payload_rate.toSpeed(),
158
eta: torrent.eta.toTime(),
159
pieces: torrent.num_pieces + ' (' + torrent.piece_length.toBytes() + ')',
160
seeders: torrent.num_seeds + ' (' + torrent.total_seeds + ')',
161
peers: torrent.num_peers + ' (' + torrent.total_peers + ')',
162
avail: torrent.distributed_copies.toFixed(3),
163
active_time: torrent.active_time.toTime(),
164
seeding_time: torrent.seeding_time.toTime(),
165
seed_rank: torrent.seed_rank
167
var text = torrent.state + ' ' + torrent.progress.toFixed(2) + '%';
168
this.bar.update(text, torrent.progress);
170
if (torrent.is_auto_managed) {data.auto_managed = 'True'}
171
else {data.auto_managed = 'False'};
173
this.element.getElements('dd').each(function(item) {
174
item.set('text', data[item.getProperty('class')]);
179
Deluge.Widgets.DetailsPage = new Class({
180
Extends: Widgets.TabPage,
183
url: '/template/render/html/tab_details.html'
186
initialize: function() {
187
this.parent(_('Details'));
191
this.element.getElements('dd').each(function(item) {
192
item.set('text', '');
196
update: function(torrent) {
198
torrent_name: torrent.name,
200
path: torrent.save_path,
201
size: torrent.total_size.toBytes(),
202
files: torrent.num_files,
203
status: torrent.tracker_status,
204
tracker: torrent.tracker
206
this.element.getElements('dd').each(function(item) {
207
item.set('text', data[item.getProperty('class')])
212
Deluge.Widgets.FilesGrid = new Class({
213
Extends: Widgets.DataGrid,
217
{name: 'filename',text: 'Filename',type:'text',width: 350},
218
{name: 'size',text: 'Size',type:'bytes',width: 80},
219
{name: 'progress',text: 'Progress',type:'progress',width: 180},
220
{name: 'priority',text: 'Priority',type:'icon',width: 150}
225
0: 'Do Not Download',
226
1: 'Normal Priority',
228
5: 'Highest Priority'
232
0: '/static/images/16/process-stop.png',
233
1: '/template/static/icons/16/gtk-yes.png',
234
2: '/static/images/16/queue-down.png',
235
5: '/static/images/16/go-bottom.png'
238
initialize: function(element, options) {
239
this.parent(element, options);
240
var menu = new Widgets.PopupMenu();
241
$A([0,1,2,5]).each(function(index) {
245
text: this.priority_texts[index],
246
icon: this.priority_icons[index]
250
menu.addEvent('action', function(e) {
253
torrentId: menu.row.torrentId
255
this.fireEvent('menuAction', e);
258
this.addEvent('rowMenu', function(e) {
271
updateFiles: function(torrent) {
272
torrent.files.each(function(file) {
273
var p = torrent.file_priorities[file.index];
275
text:this.priority_texts[p],
276
icon:this.priority_icons[p]
279
var percent = torrent.file_progress[file.index]*100.0;
281
id: torrent.id + '-' + file.index,
285
progress: {percent: percent, text: percent.toFixed(2) + '%'},
288
fileIndex: file.index,
289
torrentId: torrent.id
292
if (this.has(row.id)) {
293
this.updateRow(row, true);
295
this.addRow(row, true);
302
Deluge.Widgets.FilesPage = new Class({
303
Extends: Widgets.TabPage,
306
url: '/template/render/html/tab_files.html'
309
initialize: function(el) {
310
this.parent(_('Files'));
312
this.addEvent('loaded', this.loaded.bindWithEvent(this));
313
this.addEvent('resize', this.resized.bindWithEvent(this));
316
loaded: function(event) {
317
this.grid = new Deluge.Widgets.FilesGrid('files');
318
this.grid.addEvent('menuAction', this.menuAction.bindWithEvent(this));
320
if (this.beenResized) {
321
this.resized(this.beenResized);
322
delete this.beenResized;
327
if (this.grid) this.grid.clear();
330
resized: function(e) {
332
this.beenResized = e;
336
this.element.getPadding();
338
width: e.width - this.element.padding.x,
339
height: e.height - this.element.padding.y
343
menuAction: function(e) {
344
this.fireEvent('menuAction', e);
347
update: function(torrent) {
348
if (this.torrentId != torrent.id) {
349
this.torrentId = torrent.id;
350
this.grid.rows.empty();
351
this.grid.body.empty();
353
this.grid.updateFiles(torrent);
357
Deluge.Widgets.PeersPage = new Class({
358
Extends: Widgets.TabPage,
361
url: '/template/render/html/tab_peers.html'
364
initialize: function(el) {
365
this.parent(_('Peers'));
366
this.addEvent('resize', this.resized.bindWithEvent(this));
367
this.addEvent('loaded', this.loaded.bindWithEvent(this));
370
loaded: function(event) {
371
this.grid = new Widgets.DataGrid($('peers'), {
373
{name: 'country',type:'image',width: 20},
374
{name: 'address',text: 'Address',type:'text',width: 80},
375
{name: 'client',text: 'Client',type:'text',width: 180},
376
{name: 'downspeed',text: 'Down Speed',type:'speed',width: 100},
377
{name: 'upspeed',text: 'Up Speed',type:'speed',width: 100},
380
if (this.been_resized) {
381
this.resized(this.been_resized);
382
delete this.been_resized;
386
resized: function(e) {
388
this.been_resized = e;
392
this.element.getPadding();
394
width: e.width - this.element.padding.x,
395
height: e.height - this.element.padding.y
400
if (!this.grid) return;
401
this.grid.rows.empty();
402
this.grid.body.empty();
405
update: function(torrent) {
406
if (this.torrentId != torrent.id) {
407
this.torrentId = torrent.id;
408
this.grid.rows.empty();
409
this.grid.body.empty();
412
torrent.peers.each(function(peer) {
413
if (peer.country.strip() != '') {
414
peer.country = '/pixmaps/flags/' + peer.country.toLowerCase() + '.png'
416
peer.country = '/templates/static/images/spacer.gif'
421
country: peer.country,
424
downspeed: peer.down_speed,
425
upspeed: peer.up_speed
428
if (this.grid.has(row.id)) {
429
this.grid.updateRow(row, true);
431
this.grid.addRow(row, true);
433
peers.include(peer.ip);
436
this.grid.rows.each(function(row) {
437
if (!peers.contains(row.id)) {
438
row.element.destroy();
439
this.grid.rows.erase(row);
446
Deluge.Widgets.OptionsPage = new Class({
447
Extends: Widgets.TabPage,
450
url: '/template/render/html/tab_options.html'
453
initialize: function() {
455
this.parent(_('Options'));
456
this.addEvent('loaded', function(event) {
458
}.bindWithEvent(this));
461
loaded: function(event) {
463
apply: this.apply.bindWithEvent(this),
464
reset: this.reset.bindWithEvent(this)
466
this.form = this.element.getElement('form');
467
this.changed = new Hash();
468
this.form.getElements('input').each(function(el) {
469
if (el.type == 'button') return;
471
el.addEvent('change', function(e) {
472
if (!this.changed[this.torrentId])
473
this.changed[this.torrentId] = {};
474
if (el.type == 'checkbox')
475
this.changed[this.torrentId][el.name] = el.checked;
477
this.changed[this.torrentId][el.name] = el.value;
478
}.bindWithEvent(this));
479
el.addEvent('focus', function(e) {
482
el.addEvent('blur', function(e) {
487
new Widgets.Spinner(this.form.max_download_speed, {
495
new Widgets.Spinner(this.form.max_upload_speed, {
503
new Widgets.Spinner(this.form.max_connections, {
511
new Widgets.Spinner(this.form.max_upload_slots, {
519
new Widgets.Spinner(this.form.stop_ratio, {
528
this.form.apply_options.addEvent('click', this.bound.apply);
529
this.form.reset_options.addEvent('click', this.bound.reset);
532
apply: function(event) {
533
if (!this.torrentId) return;
534
var changed = this.changed[this.torrentId];
535
if ($defined(changed['is_auto_managed'])) {
536
changed['auto_managed'] = changed['is_auto_managed'];
537
delete changed['is_auto_managed'];
539
Deluge.Client.set_torrent_options(this.torrentId, changed, {
540
onSuccess: function(event) {
541
delete this.changed[this.torrentId];
542
}.bindWithEvent(this)
547
if (!this.form) return;
548
$$W(this.form.max_download_speed).setValue(0);
549
$$W(this.form.max_upload_speed).setValue(0);
550
$$W(this.form.max_connections).setValue(0);
551
$$W(this.form.max_upload_slots).setValue(0);
552
$$W(this.form.stop_ratio).setValue(2);
553
this.form.is_auto_managed.checked = false;
554
this.form.stop_at_ratio.checked = false;
555
this.form.remove_at_ratio.checked = false;
556
this.form.private.checked = false;
557
this.form.private.disabled = false;
558
this.form.prioritize_first_last.checked = false;
561
reset: function(event) {
562
if (this.torrentId) {
563
delete this.changed[this.torrentId];
565
Deluge.Client.get_torrent_status(this.torrentId, Deluge.Keys.Options, {
566
onSuccess: function(torrent) {
567
torrent.id = this.torrentId;
568
this.update(torrent);
569
}.bindWithEvent(this)
573
update: function(torrent) {
574
this.torrentId = torrent.id;
575
$each(torrent, function(value, key) {
576
var changed = this.changed[this.torrentId];
577
if (changed && $defined(changed[key])) return;
578
var type = $type(value);
579
if (type == 'boolean') {
580
this.form[key].checked = value;
582
if (!this.form[key].focused) {
583
widget = $$W(this.form[key]);
585
widget.setValue(value);
587
this.form[key].value = value;
591
if (key == 'private' && value == 0) {
592
this.form[key].disabled = true;
593
this.form[key].getParent().addClass('opt-disabled');