diff --git a/deluge/ui/webui/templates/ajax/index.html b/deluge/ui/webui/templates/ajax/index.html index e5c623be9..daad6ae8b 100644 --- a/deluge/ui/webui/templates/ajax/index.html +++ b/deluge/ui/webui/templates/ajax/index.html @@ -1,7 +1,7 @@ - Deluge: AJAX UI (alpha) + Deluge: AJAX UI (alpha) $version @@ -10,8 +10,15 @@ - + + + + + + + +
diff --git a/deluge/ui/webui/templates/ajax/render/js/deluge-strings.js b/deluge/ui/webui/templates/ajax/render/js/deluge-strings.js new file mode 100644 index 000000000..76012cc3a --- /dev/null +++ b/deluge/ui/webui/templates/ajax/render/js/deluge-strings.js @@ -0,0 +1,26 @@ +/* + * Script: deluge-strings.js + * A script file that is run through the template renderer in order for + * translated strings to be retrieved. + * + * Copyright: + * Damien Churchill (c) 2008 + */ + +Deluge.Strings = { + maps: {}, + add: function(string, translation) { + this.maps[string] = translation; + }, + get: function(string) { + if (this.maps[string]) { + return this.maps[string]; + } else { + return string; + } + } +} +Deluge.Strings.add('Pause', '$_('Pause')'); +Deluge.Strings.add('Resume', '$_('Resume')'); +Deluge.Strings.add('Options', '$_('Options')'); +Deluge.Strings.add('Torrents Window', '$_('Torrents Window')'); diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge-add.js b/deluge/ui/webui/templates/ajax/static/js/deluge-add.js new file mode 100644 index 000000000..34a5de1ea --- /dev/null +++ b/deluge/ui/webui/templates/ajax/static/js/deluge-add.js @@ -0,0 +1,32 @@ +/* + * Script: deluge-add.js + * Contains the add torrent window and (eventually) the torrent creator + * + * Copyright: + * Damien Churchill (c) 2008 + */ + +Deluge.Widgets.AddWindow = new Class({ + Extends: Widgets.Window, + options: { + width: 400, + height: 200, + title: 'Add Torrents', + url: '/template/render/html/window_add_torrent.html' + }, + + initialize: function() { + this.parent(); + this.addEvent('loaded', this.loaded.bindWithEvent(this)); + }, + + loaded: function(event) { + this.formfile = this.content.getChildren()[0]; + this.formurl = this.content.getChildren()[1]; + this.formurl.addEvent('submit', function(e) { + e.stop(); + Deluge.Client.add_torrent_url(this.formurl.url.value, {}); + this.hide(); + }.bindWithEvent(this)) + } +}); diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge-bars.js b/deluge/ui/webui/templates/ajax/static/js/deluge-bars.js new file mode 100644 index 000000000..d9ed8ee3a --- /dev/null +++ b/deluge/ui/webui/templates/ajax/static/js/deluge-bars.js @@ -0,0 +1,122 @@ +/* + * Script: deluge-bars.js + * Contains the various bars (Sidebar, Toolbar, Statusbar) used within deluge + * + * Copyright: + * Damien Churchill (c) 2008 + */ + +Deluge.Widgets.Toolbar = new Class({ + Implements: Events, + Extends: Widgets.Base, + + initialize: function() { + this.parent($('toolbar')) + this.buttons = this.element.getFirst() + this.info = this.element.getLast() + this.buttons.getElements('li').each(function(el) { + el.addEvent('click', function(e) { + e.action = el.id + this.fireEvent('buttonClick', e) + }.bind(this)) + }, this) + } +}); + +Deluge.Widgets.StatusBar = new Class({ + Extends: Widgets.Base, + + initialize: function() { + this.parent($('status')); + this.element.getElements('li').each(function(el) { + this[el.id] = el; + }, this); + }, + + update: function(stats) { + this.connections.set('text', stats.num_connections); + this.downspeed.set('text', stats.download_rate.toSpeed()); + this.upspeed.set('text', stats.upload_rate.toSpeed()); + this.dht.set('text', stats.dht_nodes); + } +}); + + +Deluge.Widgets.Labels = new Class({ + + Extends: Widgets.Base, + + regex: /([\w]+)\s\((\d)\)/, + + initialize: function() { + this.parent($('labels')) + this.bound = { + resized: this.resized.bindWithEvent(this), + clickedState: this.clickedState.bindWithEvent(this) + } + + this.list = new Element('ul') + this.element.grab(this.list) + this.addStates() + this.state = 'All' + this.islabels = false; + this.addEvent('resize', this.resized) + }, + + addStates: function() { + this.list.grab(new Element('li').set('text', 'All').addClass('all').addClass('activestate')) + this.list.grab(new Element('li').set('text', 'Downloading').addClass('downloading')) + this.list.grab(new Element('li').set('text', 'Seeding').addClass('seeding')) + this.list.grab(new Element('li').set('text', 'Queued').addClass('queued')) + this.list.grab(new Element('li').set('text', 'Paused').addClass('paused')) + this.list.grab(new Element('li').set('text', 'Error').addClass('error')) + this.list.grab(new Element('li').set('text', 'Checking').addClass('checking')) + this.list.grab(new Element('hr')) + }, + + addLabel: function(name) { + + }, + + clickedState: function(e) { + if (this.islabels) { + var old = this.list.getElement('.' + this.state.toLowerCase()) + old.removeClass('activestate') + this.state = e.target.get('text').match(/^(\w+)/)[1] + e.target.addClass('activestate') + this.fireEvent('stateChanged', this.state) + } else { + + } + }, + + update: function(filters) { + if (filters.state.length == 1) + this.updateNoLabels(filters); + else + this.updateLabels(filters) + }, + + updateNoLabels: function(filters) { + this.islabels = false; + }, + + updateLabels: function(filters) { + this.islabels = true; + $each(filters.state, function(state) { + var el = this.list.getElement('.' + state[0].toLowerCase()) + if (!el) return + + el.set('text', state[0] + ' (' + state[1] + ')') + el.removeEvent('click', this.bound.clickedState) + el.addEvent('click', this.bound.clickedState) + }, this) + }, + + resized: function(event) { + var height = this.element.getInnerSize().y; + this.list.getSizeModifiers(); + height -= this.list.modifiers.y; + this.list.setStyle('height', height) + } +}); diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge-details.js b/deluge/ui/webui/templates/ajax/static/js/deluge-details.js new file mode 100644 index 000000000..6e13d8220 --- /dev/null +++ b/deluge/ui/webui/templates/ajax/static/js/deluge-details.js @@ -0,0 +1,448 @@ +/* + * Script: deluge-details.js + * Contains the tabs for the torrent details + * + * Copyright: + * Damien Churchill (c) 2008 + */ + +Deluge.Widgets.Details = new Class({ + Extends: Widgets.Tabs, + + initialize: function() { + this.parent($$('#details .mooui-tabs')[0]) + + this.statistics = new Deluge.Widgets.StatisticsPage() + this.details = new Deluge.Widgets.DetailsPage() + this.files = new Deluge.Widgets.FilesPage() + this.peers = new Deluge.Widgets.PeersPage() + this.options = new Deluge.Widgets.OptionsPage() + + this.addPage(this.statistics) + this.addPage(this.details) + this.addPage(this.files) + this.addPage(this.peers) + this.addPage(this.options) + this.addEvent('pageChanged', function(e) { + this.update(this.torrentId); + }.bindWithEvent(this)); + this.addEvent('resize', this.resized.bindWithEvent(this)) + + this.files.addEvent('menuAction', function(e) { + files = [] + this.files.grid.get_selected().each(function(file) { + files.push(file.fileIndex) + }) + e.files = files + this.fireEvent('filesAction', e) + }.bindWithEvent(this)) + }, + + keys: { + 0: Deluge.Keys.Statistics, + 1: Deluge.Keys.Details, + 2: Deluge.Keys.Files, + 3: Deluge.Keys.Peers, + 4: Deluge.Keys.Options + }, + + update: function(torrentId) { + this.torrentId = torrentId + if (!this.torrentId) return + var keys = this.keys[this.currentPage], page = this.pages[this.currentPage]; + Deluge.Client.get_torrent_status(torrentId, keys, { + onSuccess: function(torrent) { + torrent.id = torrentId + if (page.update) page.update(torrent) + }.bindWithEvent(this) + }) + }, + + resized: function(event) { + this.pages.each(function(page) { + page.getSizeModifiers() + page.sets({ + width: event.width - page.element.modifiers.x, + height: event.height - page.element.modifiers.y - 28 + }) + }) + } +}); + +Deluge.Widgets.StatisticsPage = new Class({ + Extends: Widgets.TabPage, + + options: { + url: '/template/render/html/tab_statistics.html' + }, + + initialize: function() { + this.parent('Statistics') + }, + + update: function(torrent) { + var data = { + downloaded: torrent.total_done.toBytes()+' ('+torrent.total_payload_download.toBytes()+')', + uploaded: torrent.total_uploaded.toBytes()+' ('+torrent.total_payload_upload.toBytes()+')', + share: torrent.ratio.toFixed(3), + announce: torrent.next_announce.toTime(), + tracker_status: torrent.tracker_status, + downspeed: torrent.download_payload_rate.toSpeed(), + upspeed: torrent.upload_payload_rate.toSpeed(), + eta: torrent.eta.toTime(), + pieces: torrent.num_pieces + ' (' + torrent.piece_length.toBytes() + ')', + seeders: torrent.num_seeds + ' (' + torrent.total_seeds + ')', + peers: torrent.num_peers + ' (' + torrent.total_peers + ')', + avail: torrent.distributed_copies.toFixed(3), + active_time: torrent.active_time.toTime(), + seeding_time: torrent.seeding_time.toTime(), + seed_rank: torrent.seed_rank + } + + if (torrent.is_auto_managed) {data.auto_managed = 'True'} + else {data.auto_managed = 'False'} + + this.element.getElements('dd').each(function(item) { + item.set('text', data[item.getProperty('class')]) + }, this) + } +}) + +Deluge.Widgets.DetailsPage = new Class({ + Extends: Widgets.TabPage, + + options: { + url: '/template/render/html/tab_details.html' + }, + + initialize: function() { + this.parent('Details') + }, + + update: function(torrent) { + var data = { + torrent_name: torrent.name, + hash: torrent.id, + path: torrent.save_path, + size: torrent.total_size.toBytes(), + files: torrent.num_files, + status: torrent.tracker_status, + tracker: torrent.tracker + } + this.element.getElements('dd').each(function(item) { + item.set('text', data[item.getProperty('class')]) + }, this) + } +}) + +Deluge.Widgets.FilesGrid = new Class({ + Extends: Widgets.DataGrid, + + options: { + columns: [ + {name: 'filename',text: 'Filename',type:'text',width: 350}, + {name: 'size',text: 'Size',type:'bytes',width: 80}, + {name: 'progress',text: 'Progress',type:'progress',width: 180}, + {name: 'priority',text: 'Priority',type:'icon',width: 150} + ] + }, + + priority_texts: { + 0: 'Do Not Download', + 1: 'Normal Priority', + 2: 'High Priority', + 5: 'Highest Priority' + }, + + priority_icons: { + 0: '/static/images/tango/process-stop.png', + 1: '/template/static/icons/16/gtk-yes.png', + 2: '/static/images/tango/queue-down.png', + 5: '/static/images/tango/go-bottom.png' + }, + + initialize: function(element, options) { + this.parent(element, options) + var menu = new Widgets.PopupMenu() + $A([0,1,2,5]).each(function(index) { + menu.add({ + type:'text', + action: index, + text: this.priority_texts[index], + icon: this.priority_icons[index] + }) + }, this) + + menu.addEvent('action', function(e) { + e = { + action: e.action, + torrentId: menu.row.torrentId + } + this.fireEvent('menuAction', e) + }.bind(this)) + + this.addEvent('row_menu', function(e) { + e.stop() + menu.row = e.row + menu.show(e) + }) + }, + + clear: function() { + this.rows.empty() + this.body.empty() + this.render() + }, + + update_files: function(torrent) { + torrent.files.each(function(file) { + var p = torrent.file_priorities[file.index] + var priority = {text:this.priority_texts[p], icon:this.priority_icons[p]} + + var percent = torrent.file_progress[file.index]*100.0; + row = { + id: torrent.id + '-' + file.index, + data: { + filename: file.path, + size: file.size, + progress: {percent: percent, text: percent.toFixed(2) + '%'}, + priority: priority + }, + fileIndex: file.index, + torrentId: torrent.id + + } + if (this.has(row.id)) { + this.updateRow(row, true) + } else { + this.addRow(row, true) + } + }, this) + this.render() + } +}); + +Deluge.Widgets.FilesPage = new Class({ + Extends: Widgets.TabPage, + + options: { + url: '/template/render/html/tab_files.html' + }, + + initialize: function(el) { + this.parent('Files') + this.torrentId = -1 + this.addEvent('loaded', this.loaded.bindWithEvent(this)) + this.addEvent('resize', this.resized.bindWithEvent(this)) + }, + + loaded: function(event) { + this.grid = new Deluge.Widgets.FilesGrid('files') + this.grid.addEvent('menuAction', this.menuAction.bindWithEvent(this)) + + if (this.beenResized) { + this.resized(this.beenResized) + delete this.beenResized + } + }, + + resized: function(e) { + if (!this.grid) { + this.beenResized = e; + return + } + + this.element.getPadding() + this.grid.sets({ + width: e.width - this.element.padding.x, + height: e.height - this.element.padding.y + }) + }, + + menuAction: function(e) { + this.fireEvent('menuAction', e) + }, + + update: function(torrent) { + if (this.torrentId != torrent.id) { + this.torrentId = torrent.id + this.grid.rows.empty() + this.grid.body.empty() + } + this.grid.update_files(torrent) + } +}) + +Deluge.Widgets.PeersPage = new Class({ + Extends: Widgets.TabPage, + + options: { + url: '/template/render/html/tab_peers.html' + }, + + initialize: function(el) { + this.parent('Peers') + this.addEvent('resize', this.resized.bindWithEvent(this)) + this.addEvent('loaded', this.loaded.bindWithEvent(this)) + }, + + loaded: function(event) { + this.grid = new Widgets.DataGrid($('peers'), { + columns: [ + {name: 'country',type:'image',width: 20}, + {name: 'address',text: 'Address',type:'text',width: 80}, + {name: 'client',text: 'Client',type:'text',width: 180}, + {name: 'downspeed',text: 'Down Speed',type:'speed',width: 100}, + {name: 'upspeed',text: 'Up Speed',type:'speed',width: 100}, + ]}) + this.torrentId = -1 + if (this.been_resized) { + this.resized(this.been_resized) + delete this.been_resized + } + }, + + resized: function(e) { + if (!this.grid) { + this.been_resized = e; + return + } + + this.element.getPadding() + this.grid.sets({ + width: e.width - this.element.padding.x, + height: e.height - this.element.padding.y + }) + }, + + update: function(torrent) { + if (this.torrentId != torrent.id) { + this.torrentId = torrent.id + this.grid.rows.empty() + this.grid.body.empty() + } + var peers = [] + torrent.peers.each(function(peer) { + if (peer.country.strip() != '') { + peer.country = '/pixmaps/flags/' + peer.country.toLowerCase() + '.png' + } else { + peer.country = '/templates/static/images/spacer.gif' + } + row = { + id: peer.ip, + data: { + country: peer.country, + address: peer.ip, + client: peer.client, + downspeed: peer.down_speed, + upspeed: peer.up_speed + } + } + if (this.grid.has(row.id)) { + this.grid.updateRow(row, true) + } else { + this.grid.addRow(row, true) + } + peers.include(peer.ip) + }, this) + + this.grid.rows.each(function(row) { + if (!peers.contains(row.id)) { + row.element.destroy() + this.grid.rows.erase(row) + } + }, this) + this.grid.render() + } +}); + +Deluge.Widgets.OptionsPage = new Class({ + Extends: Widgets.TabPage, + + options: { + url: '/template/render/html/tab_options.html' + }, + + initialize: function() { + if (!this.element) + this.parent('Options'); + this.addEvent('loaded', function(event) { + this.loaded(event) + }.bindWithEvent(this)) + }, + + loaded: function(event) { + this.bound = { + apply: this.apply.bindWithEvent(this), + reset: this.reset.bindWithEvent(this) + } + this.form = this.element.getElement('form'); + this.changed = new Hash() + this.form.getElements('input').each(function(el) { + if (el.type == 'button') return; + el.focused = false + el.addEvent('change', function(e) { + if (!this.changed[this.torrentId]) + this.changed[this.torrentId] = {} + if (el.type == 'checkbox') + this.changed[this.torrentId][el.name] = el.checked; + else + this.changed[this.torrentId][el.name] = el.value; + }.bindWithEvent(this)); + el.addEvent('focus', function(e) { + el.focused = true; + }); + el.addEvent('blur', function(e) { + el.focused = false; + }); + }, this); + + this.form.apply.addEvent('click', this.bound.apply); + this.form.reset.addEvent('click', this.bound.reset); + }, + + apply: function(event) { + if (!this.torrentId) return + var changed = this.changed[this.torrentId] + if ($defined(changed['is_auto_managed'])) { + changed['auto_managed'] = changed['is_auto_managed'] + delete changed['is_auto_managed'] + } + Deluge.Client.set_torrent_options(this.torrentId, changed, { + onSuccess: function(event) { + delete this.changed[this.torrentId] + }.bindWithEvent(this) + }) + }, + + reset: function(event) { + if (this.torrentId) { + delete this.changed[this.torrentId] + } + Deluge.Client.get_torrent_status(this.torrentId, Deluge.Keys.Options, { + onSuccess: function(torrent) { + torrent.id = this.torrentId + this.update(torrent) + }.bindWithEvent(this) + }) + }, + + update: function(torrent) { + this.torrentId = torrent.id; + $each(torrent, function(value, key) { + var changed = this.changed[this.torrentId] + if (changed && $defined(changed[key])) return; + var type = $type(value); + if (type == 'boolean') { + this.form[key].checked = value; + } else { + if (!this.form[key].focused) + this.form[key].value = value; + }; + if (key == 'private' && value == 0) { + this.form[key].disabled = true + this.form[key].getParent().addClass('opt-disabled') + } + }, this); + } +}); diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge-menus.js b/deluge/ui/webui/templates/ajax/static/js/deluge-menus.js new file mode 100644 index 000000000..54de70d9a --- /dev/null +++ b/deluge/ui/webui/templates/ajax/static/js/deluge-menus.js @@ -0,0 +1,110 @@ +Deluge.Menus = { + Torrents: [ + { + type:'text', + action:'pause', + text: Deluge.Strings.get('Pause'), + icon:'/static/images/tango/pause.png' + }, + { + type: 'text', + action: 'resume', + text: Deluge.Strings.get('Resume'), + icon: '/static/images/tango/start.png' + }, + { type: 'seperator' }, + { + type:'submenu', + text: Deluge.Strings.get('Options'), + icon:'/static/images/tango/preferences-system.png', + items: [ + { + type:'submenu', + text:'D/L Speed Limit', + icon:'/pixmaps/downloading16.png', + items: [ + { + type:'text', + action:'max_download_speed', + value:5, + text:'5 KiB/s' + }, + { + type:'text', + action:'max_download_speed', + value:10, + text:'10 KiB/s' + }, + { + type:'text', + action:'max_download_speed', + value:30, + text:'30 KiB/s' + }, + { + type:'text', + action:'max_download_speed', + value:80, + text:'80 KiB/s' + }, + { + type:'text', + action:'max_download_speed', + value:300, + text:'300 KiB/s' + }, + { + type:'text', + action:'max_download_speed', + value:-1, + text:'Unlimited' + } + ]}, + {type:'submenu',text:'U/L Speed Limit',icon:'/pixmaps/seeding16.png',items: [ + {type:'text',action:'max_upload_speed',value:5,text:'5 KiB/s'}, + {type:'text',action:'max_upload_speed',value:10,text:'10 KiB/s'}, + {type:'text',action:'max_upload_speed',value:30,text:'30 KiB/s'}, + {type:'text',action:'max_upload_speed',value:80,text:'80 KiB/s'}, + {type:'text',action:'max_upload_speed',value:300,text:'300 KiB/s'}, + {type:'text',action:'max_upload_speed',value:-1,text:'Unlimited'} + ]}, + {type:'submenu',text:'Connection Limit',icon:'/static/images/tango/connections.png',items: [ + {type:'text',action:'max_connections',value:50,text:'50'}, + {type:'text',action:'max_connections',value:100,text:'100'}, + {type:'text',action:'max_connections',value:200,text:'200'}, + {type:'text',action:'max_connections',value:300,text:'300'}, + {type:'text',action:'max_connections',value:500,text:'500'}, + {type:'text',action:'max_connections',value:-1,text:'Unlimited'} + ]}, + {type:'submenu',text:'Upload Slot Limit',icon:'/template/static/icons/16/view-sort-ascending.png',items: [ + {type:'text',action:'max_upload_slots',value:0,text:'0'}, + {type:'text',action:'max_upload_slots',value:1,text:'1'}, + {type:'text',action:'max_upload_slots',value:2,text:'2'}, + {type:'text',action:'max_upload_slots',value:3,text:'3'}, + {type:'text',action:'max_upload_slots',value:5,text:'5'}, + {type:'text',action:'max_upload_slots',value:-1,text:'Unlimited'} + ]}, + {type:'toggle',action:'auto_managed',value:false,text:'Auto Managed'} + ]}, + {type:'seperator'}, + {type:'submenu',text:'Queue',icon:'/template/static/icons/16/view-sort-descending.png',items:[ + {type:'text',action:'top',text:'Top',icon:'/static/images/tango/go-top.png'}, + {type:'text',action:'up',text:'Up',icon:'/static/images/tango/queue-up.png'}, + {type:'text',action:'down',text:'Down',icon:'/static/images/tango/queue-down.png'}, + {type:'text',action:'bottom',text:'Bottom',icon:'/static/images/tango/go-bottom.png'} + ]}, + {type: 'seperator'}, + {type:'text',action:'update_tracker',text:'Update Tracker',icon:'/template/static/icons/16/view-refresh.png'}, + {type:'text',action:'edit_trackers',text:'Edit Trackers',icon:'/template/static/icons/16/gtk-edit.png'}, + {type:'seperator'}, + {type:'submenu',action:'remove',value:0,text:'Remove Torrent',icon:'/static/images/tango/list-remove.png', items:[ + {type:'text',action:'remove',value:0,text:'From Session'}, + {type:'text',action:'remove',value:1,text:'... and delete Torrent file'}, + {type:'text',action:'remove',value:2,text:'... and delete Downloaded files'}, + {type:'text',action:'remove',value:3,text:'... and delete All files'} + ]}, + {type:'seperator'}, + {type:'text',action:'force_recheck',text:'Force Recheck',icon:'/static/images/tango/edit-redo.png'}, + {type:'text',action:'move_storage',text:'Move Storage',icon:'/static/images/tango/move.png'} + ] +} diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge-preferences.js b/deluge/ui/webui/templates/ajax/static/js/deluge-preferences.js new file mode 100644 index 000000000..1e3003bdb --- /dev/null +++ b/deluge/ui/webui/templates/ajax/static/js/deluge-preferences.js @@ -0,0 +1,283 @@ +/* + * Script: deluge-preferences.js + * Contains the classes that provides the preferences window with + * functionality + * + * Copyright: + * Damien Churchill (c) 2008 + */ + + +Deluge.Widgets.PreferencesCategory = new Class({ + Extends: Widgets.TabPage, +}); + +Deluge.Widgets.PluginPreferencesCategory = new Class({ + Extends: Deluge.Widgets.PreferencesCategory +}); + +Deluge.Widgets.GenericPreferences = new Class({ + Extends: Deluge.Widgets.PreferencesCategory, + + initialize: function(name, options) { + this.parent(name, options) + this.core = true; + this.addEvent('loaded', function(e) { + this.form = this.element.getElement('form'); + }.bindWithEvent(this)); + }, + + update: function(config) { + this.fireEvent('beforeUpdate'); + this.original = config; + this.changed = new Hash(); + this.inputs = this.form.getElements('input, select'); + this.inputs.each(function(input) { + if (!input.name) return; + if (!$defined(config[input.name])) return; + if (input.tagName.toLowerCase() == 'select') { + var value = config[input.name].toString(); + input.getElements('option').each(function(option) { + if (option.value == value) { + option.selected = true; + } + }); + } else if (input.type == 'text') { + input.value = config[input.name]; + } else if (input.type == 'checkbox') { + input.checked = config[input.name]; + } else if (input.type == 'radio') { + var value = config[input.name].toString() + if (input.value == value) { + input.checked = true; + } + } + + input.addEvent('change', function(el) { + if (input.type == 'checkbox') { + if (this.original[input.name] == input.checked) { + if (this.changed[input.name]) + delete this.changed[input.name]; + } else { + this.changed[input.name] = input.checked + } + } else { + if (this.original[input.name] == input.value) { + if (this.changed[input.name]) + delete this.changed[input.name]; + } else { + this.changed[input.name] = input.value; + } + } + }.bindWithEvent(this)) + }, this); + this.fireEvent('update'); + }, + + getConfig: function() { + changed = {} + this.changed.each(function(value, key) { + var type = $type(this.original[key]); + if (type == 'number') { + changed[key] = Number(value); + } else if (type == 'string') { + changed[key] = String(value); + } else if (type == 'boolean') { + changed[key] = Boolean(value); + } + }, this); + return changed; + } +}); + +Deluge.Widgets.WebUIPreferences = new Class({ + Extends: Deluge.Widgets.GenericPreferences, + + options: { + url: '/template/render/html/preferences_webui.html' + }, + + initialize: function() { + this.parent('Web UI'); + this.core = false; + this.addEvent('beforeUpdate', this.beforeUpdate.bindWithEvent(this)); + this.addEvent('update', this.updated.bindWithEvent(this)); + }, + + beforeUpdate: function(event) { + var templates = Deluge.Client.get_webui_templates({async: false}); + this.form.template.empty(); + templates.each(function(template) { + var option = new Element('option'); + option.set('text', template); + this.form.template.grab(option); + }, this); + }, + + updated: function(event) { + if (this.form.template.value != 'ajax') + this.form.theme.disabled = true; + else + this.form.theme.disabled = false; + + var theme = this.form.theme.getElement('option[value="' + Cookie.read('theme') + '"]') + theme.selected = true + + this.form.template.addEvent('change', function(e) { + if (this.form.template.value != 'ajax') { + this.form.theme.disabled = true; + this.form.theme.addClass('disabled') + this.form.getElementById('lbl_theme').addClass('disabled') + } else { + this.form.theme.disabled = false; + this.form.getElementById('lbl_theme').removeClass('disabled') + this.form.theme.removeClass('disabled') + } + }.bindWithEvent(this)); + }, + + apply: function() { + Deluge.UI.setTheme(this.form.theme.value); + Deluge.Client.set_webui_config(this.changed, { + onSuccess: function(e) { + if (this.changed['template']) location.reload(true); + }.bindWithEvent(this) + }); + } +}); + +Deluge.Widgets.PreferencesWindow = new Class({ + Extends: Widgets.Window, + options: { + width: 500, + height: 430, + title: 'Preferences', + url: '/template/render/html/window_preferences.html' + }, + + initialize: function() { + this.parent(); + this.categories = []; + this.currentPage = -1; + this.addEvent('loaded', this.loaded.bindWithEvent(this)); + this.addEvent('beforeShow', this.beforeShown.bindWithEvent(this)); + }, + + loaded: function(event) { + this.catlist = this.content.getElement('.categories ul'); + this.pages = this.content.getElement('.pref_pages'); + this.title = this.pages.getElement('h3'); + + this.reset = this.content.getElement('.buttons .reset'); + this.apply = this.content.getElement('.buttons .apply'); + this.apply.addEvent('click', this.applied.bindWithEvent(this)); + + this.webui = new Deluge.Widgets.WebUIPreferences(); + + this.download = new Deluge.Widgets.GenericPreferences('Download', { + url: '/template/render/html/preferences_download.html' + }); + this.network = new Deluge.Widgets.GenericPreferences('Network', { + url: '/template/render/html/preferences_network.html' + }); + this.bandwidth = new Deluge.Widgets.GenericPreferences('Bandwidth', { + url: '/template/render/html/preferences_bandwidth.html' + }); + this.daemon = new Deluge.Widgets.GenericPreferences('Daemon', { + url: '/template/render/html/preferences_daemon.html' + }); + this.queue = new Deluge.Widgets.GenericPreferences('Queue', { + url: '/template/render/html/preferences_queue.html' + }); + + this.addCategory(this.webui); + this.addCategory(this.download); + this.addCategory(this.network); + this.addCategory(this.bandwidth); + this.addCategory(this.daemon); + this.addCategory(this.queue); + }, + + addCategory: function(category) { + this.categories.include(category); + var categoryIndex = this.categories.indexOf(category); + + var tab = new Element('li'); + tab.set('text', category.name); + tab.addEvent('click', function(e) { + this.select(categoryIndex); + }.bindWithEvent(this)); + category.tab = tab; + + this.catlist.grab(tab); + this.pages.grab(category.addClass('deluge-prefs-page')); + + + if (this.currentPage < 0) { + this.currentPage = categoryIndex; + this.select(categoryIndex); + }; + }, + + select: function(id) { + this.categories[this.currentPage].removeClass('deluge-prefs-page-active'); + this.categories[this.currentPage].tab.removeClass('deluge-prefs-active'); + this.categories[id].addClass('deluge-prefs-page-active'); + this.categories[id].tab.addClass('deluge-prefs-active'); + this.title.set('text', this.categories[id].name); + this.currentPage = id; + this.fireEvent('pageChanged'); + }, + + applied: function(event) { + var config = {}; + this.categories.each(function(category) { + config = $merge(config, category.getConfig()); + }); + + if ($defined(config['end_listen_port']) || $defined(config['start_listen_port'])) { + var startport = $pick(config['start_listen_port'], this.config['listen_ports'][0]); + var endport = $pick(config['end_listen_port'], this.config['listen_ports'][1]); + delete config['end_listen_port']; + delete config['start_listen_port']; + config['listen_ports'] = [startport, endport]; + } + + if ($defined(config['end_outgoing_port']) || $defined(config['start_outgoing_port'])) { + var startport = $pick(config['start_outgoing_port'], this.config['outgoing_ports'][0]); + var endport = $pick(config['end_outgoing_port'], this.config['outgoing_ports'][1]); + delete config['end_outgoing_port']; + delete config['start_outgoing_port']; + config['outgoing_ports'] = [startport, endport]; + } + + Deluge.Client.set_config(config, { + onSuccess: function(e) { + this.hide(); + }.bindWithEvent(this) + }); + this.webui.apply(); + }, + + beforeShown: function(event) { + // we want this to be blocking + this.config = Deluge.Client.get_config({async: false}); + + // Unfortunately we have to modify the listen ports preferences + // in order to not have to modify the generic preferences class. + this.config['start_listen_port'] = this.config['listen_ports'][0]; + this.config['end_listen_port'] = this.config['listen_ports'][1]; + + this.config['start_outgoing_port'] = this.config['outgoing_ports'][0]; + this.config['end_outgoing_port'] = this.config['outgoing_ports'][1]; + + // Iterate through the pages and set the fields + this.categories.each(function(category) { + if (category.update && category.core) category.update(this.config); + }, this); + + // Update the config for the webui pages. + var webconfig = Deluge.Client.get_webui_config({async: false}); + this.webui.update(webconfig); + } +}); diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge-torrent-grid.js b/deluge/ui/webui/templates/ajax/static/js/deluge-torrent-grid.js new file mode 100644 index 000000000..9ce8b650e --- /dev/null +++ b/deluge/ui/webui/templates/ajax/static/js/deluge-torrent-grid.js @@ -0,0 +1,92 @@ +/* + * Script: deluge-torrent-grid.js + * The class for controlling the main torrent grid. + * + * Copyright: + * Damien Churchill (c) 2008 + */ + +Deluge.Widgets.TorrentGrid = new Class({ + Extends: Widgets.DataGrid, + + options: { + columns: [ + {name: 'number',text: '#',type:'number',width: 20}, + {name: 'name',text: 'Name',type:'icon',width: 350}, + {name: 'size',text: 'Size',type:'bytes',width: 80}, + {name: 'progress',text: 'Progress',type:'progress',width: 180}, + {name: 'seeders',text: 'Seeders',type:'text',width: 80}, + {name: 'peers',text: 'Peers',type:'text',width: 80}, + {name: 'down',text: 'Down Speed',type:'speed',width: 100}, + {name: 'up',text: 'Up Speed',type:'speed',width: 100}, + {name: 'eta',text: 'ETA',type:'time',width: 80}, + {name: 'ratio',text: 'Ratio',type:'number',width: 60}, + {name: 'avail',text: 'Avail.',type:'number',width: 60} + ] + }, + + icons: { + 'Downloading': '/pixmaps/downloading16.png', + 'Seeding': '/pixmaps/seeding16.png', + 'Queued': '/pixmaps/queued16.png', + 'Paused': '/pixmaps/inactive16.png', + 'Error': '/pixmaps/alert16.png', + 'Checking': '/pixmaps/inactive16.png' + }, + + get_selected_torrents: function() { + var torrentIds = []; + this.get_selected().each(function(row) { + torrentIds.include(row.id); + }); + return torrentIds; + }, + + set_torrent_filter: function(state) { + state = state.replace(' ', ''); + this.filterer = function (r) { + if (r.torrent.state == state) { return true } else { return false }; + }; + this.render(); + }, + + update_torrents: function(torrents) { + torrents.getKeys().each(function(torrentId) { + var torrent = torrents[torrentId] + var torrentIds = torrents.getKeys() + if (torrent.queue == -1) {var queue = ''} + else {var queue = torrent.queue + 1} + var icon = this.icons[torrent.state] + row = { + id: torrentId, + data: { + number: queue, + name: {text: torrent.name, icon: icon}, + size: torrent.total_size, + progress: {percent: torrent.progress, text:torrent.state + ' ' + torrent.progress.toFixed(2) + '%'}, + seeders: torrent.num_seeds + ' (' + torrent.total_seeds + ')', + peers: torrent.num_peers + ' (' + torrent.total_peers + ')', + down: torrent.download_payload_rate, + up: torrent.upload_payload_rate, + eta: torrent.eta, + ratio: torrent.ratio.toFixed(3), + avail: torrent.distributed_copies.toFixed(3) + }, + torrent: torrent + } + if (this.has(row.id)) { + this.updateRow(row, true) + } else { + this.addRow(row, true) + } + + this.rows.each(function(row) { + if (!torrentIds.contains(row.id)) { + row.element.destroy() + this.rows.erase(row.id) + } + }, this) + }, this) + this.render() + } +}); diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge-ui.js b/deluge/ui/webui/templates/ajax/static/js/deluge-ui.js new file mode 100644 index 000000000..3a9ee2d84 --- /dev/null +++ b/deluge/ui/webui/templates/ajax/static/js/deluge-ui.js @@ -0,0 +1,275 @@ +/* + * Script: deluge-ui.js + * The main UI script. + * + * Copyright: + * Damien Churchill (c) 2008 + */ + +Deluge.UI = { + initialize: function() { + this.torrents = {}; + this.torrentIds = []; + Deluge.Client = new JSON.RPC('/json/rpc'); + + var theme = Cookie.read('theme'); + if (theme) this.setTheme(theme); + else this.setTheme('classic'); + + this.bound = { + updated: this.updated.bindWithEvent(this), + resized: this.resized.bindWithEvent(this), + toolbarClick: this.toolbarClick.bindWithEvent(this), + filePriorities: this.filePriorities.bindWithEvent(this), + labelsChanged: this.labelsChanged.bindWithEvent(this) + }; + this.loadUi.delay(100, this); + }, + + loadUi: function() { + this.vbox = new Widgets.VBox('page', {expand: true}); + + this.toolbar = new Deluge.Widgets.Toolbar(); + this.addWindow = new Deluge.Widgets.AddWindow(); + this.prefsWindow = new Deluge.Widgets.PreferencesWindow(); + + this.statusbar = new Deluge.Widgets.StatusBar(); + this.labels = new Deluge.Widgets.Labels() + this.details = new Deluge.Widgets.Details() + + this.initialize_grid() + + this.split_horz = new Widgets.SplitPane('top', this.labels, this.grid, { + pane1: {min: 150}, + pane2: {min: 100, expand: true} + }); + var details = $W('details') + this.split_vert = new Widgets.SplitPane('main', this.split_horz, details, { + direction: 'vertical', + pane1: {min: 100, expand: true}, + pane2: {min: 200} + }); + + this.vbox.addBox(this.toolbar, {fixed: true}); + this.vbox.addBox(this.split_vert); + this.vbox.addBox(this.statusbar, {fixed: true}); + this.vbox.calculatePositions(); + this.details.expand() + + this.toolbar.addEvent('buttonClick', this.bound.toolbarClick); + this.details.addEvent('filesAction', this.bound.filePriorities) + this.labels.addEvent('stateChanged', this.bound.labelsChanged) + details.addEvent('resize', function(e) { + this.details.expand() + }.bindWithEvent(this)) + + window.addEvent('resize', this.bound.resized); + Deluge.UI.update(); + this.overlay = $('overlay').dispose(); + }, + + initialize_grid: function() { + this.grid = new Deluge.Widgets.TorrentGrid('torrents') + + var menu = new Widgets.PopupMenu() + menu.add(Deluge.Menus.Torrents); + menu.addEvent('action', function(e) { + this.torrent_action(e.action, e.value) + }.bind(this)) + + this.grid.addEvent('row_menu', function(e) { + e.stop() + var value = this.grid.selectedRow.torrent.is_auto_managed; + menu.items[3].items[4].set(value) + menu.torrent_id = e.row_id + menu.show(e) + }.bindWithEvent(this)) + + this.grid.addEvent('selectedchanged', function(e) { + if ($chk(this.grid.selectedRow)) + this.details.update(this.grid.selectedRow.id); + else + this.details.update(null); + }.bindWithEvent(this)) + }, + + setTheme: function(name, fn) { + if (this.overlay) { + this.overlay.inject(document.body); + } + this.theme = name; + if (this.themecss) this.themecss.destroy(); + this.themecss = new Asset.css('/template/static/themes/' + name + '/style.css'); + Cookie.write('theme', name); + if (this.overlay) { + var refresh = function() { + this.vbox.refresh(); + this.vbox.calculatePositions(); + this.overlay.dispose(); + }.bind(this); + var check = function() { + if (document.styleSheets[2]) { + if (document.styleSheets[2].href == this.themecss.href) { + refresh(); + $clear(check); + } + } + }.periodical(50, this); + }; + }, + + run: function() { + if (!this.running) { + this.running = this.update.periodical(2000, this); + } + }, + + stop: function() { + if (this.running) { + $clear(this.running); + this.running = false; + } + }, + + update: function() { + filter = {} + if (this.labels.state != 'All') filter.state = this.labels.state + Deluge.Client.update_ui(Deluge.Keys.Grid, filter, { + onSuccess: this.bound.updated + }) + }, + + updated: function(data) { + this.torrents = new Hash(data.torrents); + this.stats = data.stats; + this.filters = data.filters + this.torrents.each(function(torrent, torrent_id) { + torrent.id = torrent_id; + }) + this.grid.update_torrents(this.torrents); + this.statusbar.update(this.stats); + + if ($chk(this.grid.selectedRow)) + this.details.update(this.grid.selectedRow.id); + else + this.details.update(null); + + this.labels.update(this.filters) + }, + + filePriorities: function(event) { + Deluge.Client.get_torrent_status(event.torrentId, ['file_priorities'], { + onSuccess: function(result) { + var priorities = result.file_priorities + priorities.each(function(priority, index) { + if (event.files.contains(index)) { + priorities[index] = event.action; + } + }) + Deluge.Client.set_torrent_file_priorities(event.torrentId, priorities, { + onSuccess: function(response) { + this.details.update(event.torrentId) + }.bindWithEvent(this) + }) + }.bindWithEvent(this) + }) + }, + + resized: function(event) { + this.vbox.calculatePositions(); + }, + + toolbarClick: function(event) { + this.torrent_action(event.action); + }, + + labelsChanged: function(event) { + this.update() + }, + + torrent_action: function(action, value) { + var torrentIds = this.grid.get_selected_torrents(); + var client = Deluge.Client; + switch (action) { + case 'resume': + client.resume_torrent(torrentIds); + break; + case 'pause': + client.pause_torrent(torrentIds); + break; + case 'top': + client.queue_top(torrentIds); + break; + case 'up': + client.queue_up(torrentIds); + break; + case 'down': + client.queue_down(torrentIds); + break; + case 'bottom': + client.queue_bottom(torrentIds); + break; + case 'force_recheck': + client.force_recheck(torrentIds); + break; + case 'update_tracker': + client.force_reannounce(torrentIds); + break; + case 'max_download_speed': + value = value.toInt(); + torrentIds.each(function(torrentId) { + client.set_torrent_max_download_speed(torrentId, value); + }); + break; + case 'max_upload_speed': + value = value.toInt(); + torrentIds.each(function(torrentId) { + client.set_torrent_max_upload_speed(torrentId, value); + }); + break; + case 'max_connections': + value = value.toInt(); + torrentIds.each(function(torrentId) { + client.set_torrent_max_connections(torrentId, value); + }); + break; + case 'max_upload_slots': + value = value.toInt(); + torrentIds.each(function(torrentId) { + client.set_torrent_max_upload_slots(torrentId, value); + }); + break; + case 'auto_managed': + torrentIds.each(function(torrentId) { + client.set_torrent_auto_managed(torrentId, value); + }); + break; + case 'add': + this.addWindow.show(); + break; + case 'remove': + var removeTorrent = false, removeFiles = false; + if (value == 1) removeTorrent = true; + else if (value == 2) removeFiles = true; + else if (value > 3) { + removeTorrent = true; + removeFiles = true; + } + client.remove_torrent(torrentIds, removeTorrent, removeFiles); + break; + case 'preferences': + this.prefsWindow.show(); + break; + default: + break; + } + this.update(); + } +}; + + + +window.addEvent('domready', function(e) { + Deluge.UI.initialize(); + Deluge.UI.run(); +}); diff --git a/deluge/ui/webui/templates/ajax/static/js/deluge.js b/deluge/ui/webui/templates/ajax/static/js/deluge.js index dd2f5d28f..83a3efed4 100644 --- a/deluge/ui/webui/templates/ajax/static/js/deluge.js +++ b/deluge/ui/webui/templates/ajax/static/js/deluge.js @@ -1,6 +1,6 @@ /* * Script: deluge.js - * Collection of widgets for use in the deluge web-ui + * The core script for the deluge ajax ui * * Copyright: * Damien Churchill (c) 2008 @@ -9,1291 +9,34 @@ var Deluge = $empty; Deluge.Keys = { - Grid: ['queue', 'name', 'total_size', 'state', 'progress', - 'num_seeds', 'total_seeds', 'num_peers', 'total_peers', - 'download_payload_rate', 'upload_payload_rate', 'eta', 'ratio', - 'distributed_copies' ,'is_auto_managed'], - - Statistics: ['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', 'seed_rank'], - - Files: ['files', 'file_progress', 'file_priorities'], - - Peers: ['peers', 'seeds'], - - Details: ['name', 'save_path', 'total_size', 'num_files', 'tracker_status', 'tracker'], - - 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'] + Grid: [ + 'queue', 'name', 'total_size', 'state', 'progress', 'num_seeds', + 'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate', + 'upload_payload_rate', 'eta', 'ratio', 'distributed_copies', + 'is_auto_managed' + ], + Statistics: [ + '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', + 'seed_rank' + ], + Files: [ + 'files', 'file_progress', 'file_priorities' + ], + Peers: [ + 'peers', 'seeds' + ], + Details: [ + 'name', 'save_path', 'total_size', 'num_files', 'tracker_status', + 'tracker' + ], + 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' + ] } - Deluge.Keys.Statistics.extend(Deluge.Keys.Grid) Deluge.Widgets = $empty; - -Deluge.Widgets.Details = new Class({ - Extends: Widgets.Tabs, - - initialize: function() { - this.parent($$('#details .mooui-tabs')[0]) - - this.statistics = new Deluge.Widgets.StatisticsPage() - this.details = new Deluge.Widgets.DetailsPage() - this.files = new Deluge.Widgets.FilesPage() - this.peers = new Deluge.Widgets.PeersPage() - this.options = new Deluge.Widgets.OptionsPage() - - this.addPage(this.statistics) - this.addPage(this.details) - this.addPage(this.files) - this.addPage(this.peers) - this.addPage(this.options) - this.addEvent('pageChanged', function(e) { - this.update(this.torrentId); - }.bindWithEvent(this)); - this.addEvent('resize', this.resized.bindWithEvent(this)) - - this.files.addEvent('menuAction', function(e) { - files = [] - this.files.grid.get_selected().each(function(file) { - files.push(file.fileIndex) - }) - e.files = files - this.fireEvent('filesAction', e) - }.bindWithEvent(this)) - }, - - keys: { - 0: Deluge.Keys.Statistics, - 1: Deluge.Keys.Details, - 2: Deluge.Keys.Files, - 3: Deluge.Keys.Peers, - 4: Deluge.Keys.Options - }, - - update: function(torrentId) { - this.torrentId = torrentId - if (!this.torrentId) return - var keys = this.keys[this.currentPage], page = this.pages[this.currentPage]; - Deluge.Client.get_torrent_status(torrentId, keys, { - onSuccess: function(torrent) { - torrent.id = torrentId - if (page.update) page.update(torrent) - }.bindWithEvent(this) - }) - }, - - resized: function(event) { - this.pages.each(function(page) { - page.getSizeModifiers() - page.sets({ - width: event.width - page.element.modifiers.x, - height: event.height - page.element.modifiers.y - 28 - }) - }) - } -}); - -Deluge.Widgets.StatisticsPage = new Class({ - Extends: Widgets.TabPage, - - options: { - url: '/template/render/html/tab_statistics.html' - }, - - initialize: function() { - this.parent('Statistics') - }, - - update: function(torrent) { - var data = { - downloaded: torrent.total_done.toBytes()+' ('+torrent.total_payload_download.toBytes()+')', - uploaded: torrent.total_uploaded.toBytes()+' ('+torrent.total_payload_upload.toBytes()+')', - share: torrent.ratio.toFixed(3), - announce: torrent.next_announce.toTime(), - tracker_status: torrent.tracker_status, - downspeed: torrent.download_payload_rate.toSpeed(), - upspeed: torrent.upload_payload_rate.toSpeed(), - eta: torrent.eta.toTime(), - pieces: torrent.num_pieces + ' (' + torrent.piece_length.toBytes() + ')', - seeders: torrent.num_seeds + ' (' + torrent.total_seeds + ')', - peers: torrent.num_peers + ' (' + torrent.total_peers + ')', - avail: torrent.distributed_copies.toFixed(3), - active_time: torrent.active_time.toTime(), - seeding_time: torrent.seeding_time.toTime(), - seed_rank: torrent.seed_rank - } - - if (torrent.is_auto_managed) {data.auto_managed = 'True'} - else {data.auto_managed = 'False'} - - this.element.getElements('dd').each(function(item) { - item.set('text', data[item.getProperty('class')]) - }, this) - } -}) - -Deluge.Widgets.DetailsPage = new Class({ - Extends: Widgets.TabPage, - - options: { - url: '/template/render/html/tab_details.html' - }, - - initialize: function() { - this.parent('Details') - }, - - update: function(torrent) { - var data = { - torrent_name: torrent.name, - hash: torrent.id, - path: torrent.save_path, - size: torrent.total_size.toBytes(), - files: torrent.num_files, - status: torrent.tracker_status, - tracker: torrent.tracker - } - this.element.getElements('dd').each(function(item) { - item.set('text', data[item.getProperty('class')]) - }, this) - } -}) - -Deluge.Widgets.FilesGrid = new Class({ - Extends: Widgets.DataGrid, - - options: { - columns: [ - {name: 'filename',text: 'Filename',type:'text',width: 350}, - {name: 'size',text: 'Size',type:'bytes',width: 80}, - {name: 'progress',text: 'Progress',type:'progress',width: 180}, - {name: 'priority',text: 'Priority',type:'icon',width: 150} - ] - }, - - priority_texts: { - 0: 'Do Not Download', - 1: 'Normal Priority', - 2: 'High Priority', - 5: 'Highest Priority' - }, - - priority_icons: { - 0: '/static/images/tango/process-stop.png', - 1: '/template/static/icons/16/gtk-yes.png', - 2: '/static/images/tango/queue-down.png', - 5: '/static/images/tango/go-bottom.png' - }, - - initialize: function(element, options) { - this.parent(element, options) - var menu = new Widgets.PopupMenu() - $A([0,1,2,5]).each(function(index) { - menu.add({ - type:'text', - action: index, - text: this.priority_texts[index], - icon: this.priority_icons[index] - }) - }, this) - - menu.addEvent('action', function(e) { - e = { - action: e.action, - torrentId: menu.row.torrentId - } - this.fireEvent('menuAction', e) - }.bind(this)) - - this.addEvent('row_menu', function(e) { - e.stop() - menu.row = e.row - menu.show(e) - }) - }, - - clear: function() { - this.rows.empty() - this.body.empty() - this.render() - }, - - update_files: function(torrent) { - torrent.files.each(function(file) { - var p = torrent.file_priorities[file.index] - var priority = {text:this.priority_texts[p], icon:this.priority_icons[p]} - - var percent = torrent.file_progress[file.index]*100.0; - row = { - id: torrent.id + '-' + file.index, - data: { - filename: file.path, - size: file.size, - progress: {percent: percent, text: percent.toFixed(2) + '%'}, - priority: priority - }, - fileIndex: file.index, - torrentId: torrent.id - - } - if (this.has(row.id)) { - this.updateRow(row, true) - } else { - this.addRow(row, true) - } - }, this) - this.render() - } -}); - -Deluge.Widgets.FilesPage = new Class({ - Extends: Widgets.TabPage, - - options: { - url: '/template/render/html/tab_files.html' - }, - - initialize: function(el) { - this.parent('Files') - this.torrentId = -1 - this.addEvent('loaded', this.loaded.bindWithEvent(this)) - this.addEvent('resize', this.resized.bindWithEvent(this)) - }, - - loaded: function(event) { - this.grid = new Deluge.Widgets.FilesGrid('files') - this.grid.addEvent('menuAction', this.menu_action.bindWithEvent(this)) - - if (this.been_resized) { - this.resized(this.been_resized) - delete this.been_resized - } - }, - - resize_check: function(event) { - - }, - - resized: function(e) { - if (!this.grid) { - this.been_resized = e; - return - } - - this.element.getPadding() - this.grid.sets({ - width: e.width - this.element.padding.x, - height: e.height - this.element.padding.y - }) - }, - - menu_action: function(e) { - this.fireEvent('menuAction', e) - }, - - update: function(torrent) { - if (this.torrentId != torrent.id) { - this.torrentId = torrent.id - this.grid.rows.empty() - this.grid.body.empty() - } - this.grid.update_files(torrent) - } -}) - -Deluge.Widgets.PeersPage = new Class({ - Extends: Widgets.TabPage, - - options: { - url: '/template/render/html/tab_peers.html' - }, - - initialize: function(el) { - this.parent('Peers') - this.addEvent('resize', this.resized.bindWithEvent(this)) - this.addEvent('loaded', this.loaded.bindWithEvent(this)) - }, - - loaded: function(event) { - this.grid = new Widgets.DataGrid($('peers'), { - columns: [ - {name: 'country',type:'image',width: 20}, - {name: 'address',text: 'Address',type:'text',width: 80}, - {name: 'client',text: 'Client',type:'text',width: 180}, - {name: 'downspeed',text: 'Down Speed',type:'speed',width: 100}, - {name: 'upspeed',text: 'Up Speed',type:'speed',width: 100}, - ]}) - this.torrentId = -1 - if (this.been_resized) { - this.resized(this.been_resized) - delete this.been_resized - } - }, - - resized: function(e) { - if (!this.grid) { - this.been_resized = e; - return - } - - this.element.getPadding() - this.grid.sets({ - width: e.width - this.element.padding.x, - height: e.height - this.element.padding.y - }) - }, - - update: function(torrent) { - if (this.torrentId != torrent.id) { - this.torrentId = torrent.id - this.grid.rows.empty() - this.grid.body.empty() - } - var peers = [] - torrent.peers.each(function(peer) { - if (peer.country.strip() != '') { - peer.country = '/pixmaps/flags/' + peer.country.toLowerCase() + '.png' - } else { - peer.country = '/templates/static/images/spacer.gif' - } - row = { - id: peer.ip, - data: { - country: peer.country, - address: peer.ip, - client: peer.client, - downspeed: peer.down_speed, - upspeed: peer.up_speed - } - } - if (this.grid.has(row.id)) { - this.grid.updateRow(row, true) - } else { - this.grid.addRow(row, true) - } - peers.include(peer.ip) - }, this) - - this.grid.rows.each(function(row) { - if (!peers.contains(row.id)) { - row.element.destroy() - this.grid.rows.erase(row) - } - }, this) - this.grid.render() - } -}); - -Deluge.Widgets.OptionsPage = new Class({ - Extends: Widgets.TabPage, - - options: { - url: '/template/render/html/tab_options.html' - }, - - initialize: function() { - if (!this.element) - this.parent('Options'); - this.addEvent('loaded', function(event) { - this.loaded(event) - }.bindWithEvent(this)) - }, - - loaded: function(event) { - this.bound = { - apply: this.apply.bindWithEvent(this), - reset: this.reset.bindWithEvent(this) - } - this.form = this.element.getElement('form'); - this.changed = new Hash() - this.form.getElements('input').each(function(el) { - if (el.type == 'button') return; - el.focused = false - el.addEvent('change', function(e) { - if (!this.changed[this.torrentId]) - this.changed[this.torrentId] = {} - if (el.type == 'checkbox') - this.changed[this.torrentId][el.name] = el.checked; - else - this.changed[this.torrentId][el.name] = el.value; - }.bindWithEvent(this)); - el.addEvent('focus', function(e) { - el.focused = true; - }); - el.addEvent('blur', function(e) { - el.focused = false; - }); - }, this); - - this.form.apply.addEvent('click', this.bound.apply); - this.form.reset.addEvent('click', this.bound.reset); - }, - - apply: function(event) { - if (!this.torrentId) return - var changed = this.changed[this.torrentId] - if ($defined(changed['is_auto_managed'])) { - changed['auto_managed'] = changed['is_auto_managed'] - delete changed['is_auto_managed'] - } - Deluge.Client.set_torrent_options(this.torrentId, changed, { - onSuccess: function(event) { - delete this.changed[this.torrentId] - }.bindWithEvent(this) - }) - }, - - reset: function(event) { - if (this.torrentId) { - delete this.changed[this.torrentId] - } - Deluge.Client.get_torrent_status(this.torrentId, Deluge.Keys.Options, { - onSuccess: function(torrent) { - torrent.id = this.torrentId - this.update(torrent) - }.bindWithEvent(this) - }) - }, - - update: function(torrent) { - this.torrentId = torrent.id; - $each(torrent, function(value, key) { - var changed = this.changed[this.torrentId] - if (changed && $defined(changed[key])) return; - var type = $type(value); - if (type == 'boolean') { - this.form[key].checked = value; - } else { - if (!this.form[key].focused) - this.form[key].value = value; - }; - if (key == 'private' && value == 0) { - this.form[key].disabled = true - this.form[key].getParent().addClass('opt-disabled') - } - }, this); - } -}); - -Deluge.Widgets.Toolbar = new Class({ - Implements: Events, - Extends: Widgets.Base, - - initialize: function() { - this.parent($('toolbar')) - this.buttons = this.element.getFirst() - this.info = this.element.getLast() - this.buttons.getElements('li').each(function(el) { - el.addEvent('click', function(e) { - e.action = el.id - this.fireEvent('button_click', e) - }.bind(this)) - }, this) - } -}); - -Deluge.Widgets.StatusBar = new Class({ - Extends: Widgets.Base, - - initialize: function() { - this.parent($('status')); - this.element.getElements('li').each(function(el) { - this[el.id] = el; - }, this); - }, - - update: function(stats) { - this.connections.set('text', stats.num_connections); - this.downspeed.set('text', stats.download_rate.toSpeed()); - this.upspeed.set('text', stats.upload_rate.toSpeed()); - this.dht.set('text', stats.dht_nodes); - } -}); - -Deluge.Widgets.TorrentGrid = new Class({ - Extends: Widgets.DataGrid, - - options: { - columns: [ - {name: 'number',text: '#',type:'number',width: 20}, - {name: 'name',text: 'Name',type:'icon',width: 350}, - {name: 'size',text: 'Size',type:'bytes',width: 80}, - {name: 'progress',text: 'Progress',type:'progress',width: 180}, - {name: 'seeders',text: 'Seeders',type:'text',width: 80}, - {name: 'peers',text: 'Peers',type:'text',width: 80}, - {name: 'down',text: 'Down Speed',type:'speed',width: 100}, - {name: 'up',text: 'Up Speed',type:'speed',width: 100}, - {name: 'eta',text: 'ETA',type:'time',width: 80}, - {name: 'ratio',text: 'Ratio',type:'number',width: 60}, - {name: 'avail',text: 'Avail.',type:'number',width: 60} - ] - }, - - icons: { - 'Downloading': '/pixmaps/downloading16.png', - 'Seeding': '/pixmaps/seeding16.png', - 'Queued': '/pixmaps/queued16.png', - 'Paused': '/pixmaps/inactive16.png', - 'Error': '/pixmaps/alert16.png', - 'Checking': '/pixmaps/inactive16.png' - }, - - get_selected_torrents: function() { - var torrentIds = []; - this.get_selected().each(function(row) { - torrentIds.include(row.id); - }); - return torrentIds; - }, - - set_torrent_filter: function(state) { - state = state.replace(' ', ''); - this.filterer = function (r) { - if (r.torrent.state == state) { return true } else { return false }; - }; - this.render(); - }, - - update_torrents: function(torrents) { - torrents.getKeys().each(function(torrentId) { - var torrent = torrents[torrentId] - var torrentIds = torrents.getKeys() - if (torrent.queue == -1) {var queue = ''} - else {var queue = torrent.queue + 1} - var icon = this.icons[torrent.state] - row = { - id: torrentId, - data: { - number: queue, - name: {text: torrent.name, icon: icon}, - size: torrent.total_size, - progress: {percent: torrent.progress, text:torrent.state + ' ' + torrent.progress.toFixed(2) + '%'}, - seeders: torrent.num_seeds + ' (' + torrent.total_seeds + ')', - peers: torrent.num_peers + ' (' + torrent.total_peers + ')', - down: torrent.download_payload_rate, - up: torrent.upload_payload_rate, - eta: torrent.eta, - ratio: torrent.ratio.toFixed(3), - avail: torrent.distributed_copies.toFixed(3) - }, - torrent: torrent - } - if (this.has(row.id)) { - this.updateRow(row, true) - } else { - this.addRow(row, true) - } - - this.rows.each(function(row) { - if (!torrentIds.contains(row.id)) { - row.element.destroy() - this.rows.erase(row.id) - } - }, this) - }, this) - this.render() - } -}) - -Deluge.Widgets.Labels = new Class({ - - Extends: Widgets.Base, - - regex: /([\w]+)\s\((\d)\)/, - - initialize: function() { - this.parent($('labels')) - this.bound = { - resized: this.resized.bindWithEvent(this), - clickedState: this.clickedState.bindWithEvent(this) - } - - this.list = new Element('ul') - this.element.grab(this.list) - this.addStates() - this.state = 'All' - this.islabels = false; - this.addEvent('resize', this.resized) - }, - - addStates: function() { - this.list.grab(new Element('li').set('text', 'All').addClass('all').addClass('activestate')) - this.list.grab(new Element('li').set('text', 'Downloading').addClass('downloading')) - this.list.grab(new Element('li').set('text', 'Seeding').addClass('seeding')) - this.list.grab(new Element('li').set('text', 'Queued').addClass('queued')) - this.list.grab(new Element('li').set('text', 'Paused').addClass('paused')) - this.list.grab(new Element('li').set('text', 'Error').addClass('error')) - this.list.grab(new Element('li').set('text', 'Checking').addClass('checking')) - this.list.grab(new Element('hr')) - }, - - addLabel: function(name) { - - }, - - clickedState: function(e) { - if (this.islabels) { - var old = this.list.getElement('.' + this.state.toLowerCase()) - old.removeClass('activestate') - this.state = e.target.get('text').match(/^(\w+)/)[1] - e.target.addClass('activestate') - this.fireEvent('stateChanged', this.state) - } else { - - } - }, - - update: function(filters) { - if (filters.state.length == 1) - this.updateNoLabels(filters); - else - this.updateLabels(filters) - }, - - updateNoLabels: function(filters) { - this.islabels = false; - }, - - updateLabels: function(filters) { - this.islabels = true; - $each(filters.state, function(state) { - var el = this.list.getElement('.' + state[0].toLowerCase()) - if (!el) return - - el.set('text', state[0] + ' (' + state[1] + ')') - el.removeEvent('click', this.bound.clickedState) - el.addEvent('click', this.bound.clickedState) - }, this) - }, - - resized: function(event) { - var height = this.element.getInnerSize().y; - this.list.getSizeModifiers(); - height -= this.list.modifiers.y; - this.list.setStyle('height', height) - } -}); - -Deluge.Widgets.AddWindow = new Class({ - Extends: Widgets.Window, - options: { - width: 400, - height: 200, - title: 'Add Torrent', - url: '/template/render/html/window_add_torrent.html' - }, - - initialize: function() { - this.parent() - this.addEvent('loaded', this.loaded.bindWithEvent(this)) - }, - - loaded: function(event) { - this.formfile = this.content.getChildren()[0]; - this.formurl = this.content.getChildren()[1]; - this.formurl.addEvent('submit', function(e) { - e.stop(); - Deluge.Client.add_torrent_url(this.formurl.url.value, '', {}) - this.hide() - }.bindWithEvent(this)) - } -}); - -Deluge.Widgets.PreferencesCategory = new Class({ - Extends: Widgets.TabPage, -}); - -Deluge.Widgets.PluginPreferencesCategory = new Class({ - Extends: Deluge.Widgets.PreferencesCategory -}); - -Deluge.Widgets.GenericPreferences = new Class({ - Extends: Deluge.Widgets.PreferencesCategory, - - initialize: function(name, options) { - this.parent(name, options) - this.core = true; - this.addEvent('loaded', function(e) { - this.form = this.element.getElement('form'); - }.bindWithEvent(this)); - }, - - update: function(config) { - this.fireEvent('beforeUpdate'); - this.original = config; - this.changed = new Hash(); - this.inputs = this.form.getElements('input, select'); - this.inputs.each(function(input) { - if (!input.name) return; - if (!$defined(config[input.name])) return; - if (input.tagName.toLowerCase() == 'select') { - var value = config[input.name].toString(); - input.getElements('option').each(function(option) { - if (option.value == value) { - option.selected = true; - } - }); - } else if (input.type == 'text') { - input.value = config[input.name]; - } else if (input.type == 'checkbox') { - input.checked = config[input.name]; - } else if (input.type == 'radio') { - var value = config[input.name].toString() - if (input.value == value) { - input.checked = true; - } - } - - input.addEvent('change', function(el) { - if (input.type == 'checkbox') { - if (this.original[input.name] == input.checked) { - if (this.changed[input.name]) - delete this.changed[input.name]; - } else { - this.changed[input.name] = input.checked - } - } else { - if (this.original[input.name] == input.value) { - if (this.changed[input.name]) - delete this.changed[input.name]; - } else { - this.changed[input.name] = input.value; - } - } - }.bindWithEvent(this)) - }, this); - this.fireEvent('update'); - }, - - getConfig: function() { - changed = {} - this.changed.each(function(value, key) { - var type = $type(this.original[key]); - if (type == 'number') { - changed[key] = Number(value); - } else if (type == 'string') { - changed[key] = String(value); - } else if (type == 'boolean') { - changed[key] = Boolean(value); - } - }, this); - return changed; - } -}); - -Deluge.Widgets.WebUIPreferences = new Class({ - Extends: Deluge.Widgets.GenericPreferences, - - options: { - url: '/template/render/html/preferences_webui.html' - }, - - initialize: function() { - this.parent('Web UI'); - this.core = false; - this.addEvent('beforeUpdate', this.beforeUpdate.bindWithEvent(this)); - this.addEvent('update', this.updated.bindWithEvent(this)); - }, - - beforeUpdate: function(event) { - var templates = Deluge.Client.get_webui_templates({async: false}); - this.form.template.empty(); - templates.each(function(template) { - var option = new Element('option'); - option.set('text', template); - this.form.template.grab(option); - }, this); - }, - - updated: function(event) { - if (this.form.template.value != 'ajax') - this.form.theme.disabled = true; - else - this.form.theme.disabled = false; - - var theme = this.form.theme.getElement('option[value="' + Cookie.read('theme') + '"]') - theme.selected = true - - this.form.template.addEvent('change', function(e) { - if (this.form.template.value != 'ajax') { - this.form.theme.disabled = true; - this.form.theme.addClass('disabled') - this.form.getElementById('lbl_theme').addClass('disabled') - } else { - this.form.theme.disabled = false; - this.form.getElementById('lbl_theme').removeClass('disabled') - this.form.theme.removeClass('disabled') - } - }.bindWithEvent(this)); - }, - - apply: function() { - Deluge.UI.setTheme(this.form.theme.value); - Deluge.Client.set_webui_config(this.changed, { - onSuccess: function(e) { - if (this.changed['template']) location.reload(true); - }.bindWithEvent(this) - }); - } -}); - -Deluge.Widgets.PreferencesWindow = new Class({ - Extends: Widgets.Window, - options: { - width: 500, - height: 430, - title: 'Preferences', - url: '/template/render/html/window_preferences.html' - }, - - initialize: function() { - this.parent(); - this.categories = []; - this.currentPage = -1; - this.addEvent('loaded', this.loaded.bindWithEvent(this)); - this.addEvent('beforeShow', this.beforeShown.bindWithEvent(this)); - }, - - loaded: function(event) { - this.catlist = this.content.getElement('.categories ul'); - this.pages = this.content.getElement('.pref_pages'); - this.title = this.pages.getElement('h3'); - - this.reset = this.content.getElement('.buttons .reset'); - this.apply = this.content.getElement('.buttons .apply'); - this.apply.addEvent('click', this.applied.bindWithEvent(this)); - - this.webui = new Deluge.Widgets.WebUIPreferences(); - - this.download = new Deluge.Widgets.GenericPreferences('Download', { - url: '/template/render/html/preferences_download.html' - }); - this.network = new Deluge.Widgets.GenericPreferences('Network', { - url: '/template/render/html/preferences_network.html' - }); - this.bandwidth = new Deluge.Widgets.GenericPreferences('Bandwidth', { - url: '/template/render/html/preferences_bandwidth.html' - }); - this.daemon = new Deluge.Widgets.GenericPreferences('Daemon', { - url: '/template/render/html/preferences_daemon.html' - }); - this.queue = new Deluge.Widgets.GenericPreferences('Queue', { - url: '/template/render/html/preferences_queue.html' - }); - - this.addCategory(this.webui); - this.addCategory(this.download); - this.addCategory(this.network); - this.addCategory(this.bandwidth); - this.addCategory(this.daemon); - this.addCategory(this.queue); - }, - - addCategory: function(category) { - this.categories.include(category); - var categoryIndex = this.categories.indexOf(category); - - var tab = new Element('li'); - tab.set('text', category.name); - tab.addEvent('click', function(e) { - this.select(categoryIndex); - }.bindWithEvent(this)); - category.tab = tab; - - this.catlist.grab(tab); - this.pages.grab(category.addClass('deluge-prefs-page')); - - - if (this.currentPage < 0) { - this.currentPage = categoryIndex; - this.select(categoryIndex); - }; - }, - - select: function(id) { - this.categories[this.currentPage].removeClass('deluge-prefs-page-active'); - this.categories[this.currentPage].tab.removeClass('deluge-prefs-active'); - this.categories[id].addClass('deluge-prefs-page-active'); - this.categories[id].tab.addClass('deluge-prefs-active'); - this.title.set('text', this.categories[id].name); - this.currentPage = id; - this.fireEvent('pageChanged'); - }, - - applied: function(event) { - var config = {}; - this.categories.each(function(category) { - config = $merge(config, category.getConfig()); - }); - - if ($defined(config['end_listen_port']) || $defined(config['start_listen_port'])) { - var startport = $pick(config['start_listen_port'], this.config['listen_ports'][0]); - var endport = $pick(config['end_listen_port'], this.config['listen_ports'][1]); - delete config['end_listen_port']; - delete config['start_listen_port']; - config['listen_ports'] = [startport, endport]; - } - - if ($defined(config['end_outgoing_port']) || $defined(config['start_outgoing_port'])) { - var startport = $pick(config['start_outgoing_port'], this.config['outgoing_ports'][0]); - var endport = $pick(config['end_outgoing_port'], this.config['outgoing_ports'][1]); - delete config['end_outgoing_port']; - delete config['start_outgoing_port']; - config['outgoing_ports'] = [startport, endport]; - } - - Deluge.Client.set_config(config, { - onSuccess: function(e) { - this.hide(); - }.bindWithEvent(this) - }); - this.webui.apply(); - }, - - beforeShown: function(event) { - // we want this to be blocking - this.config = Deluge.Client.get_config({async: false}); - - // Unfortunately we have to modify the listen ports preferences - // in order to not have to modify the generic preferences class. - this.config['start_listen_port'] = this.config['listen_ports'][0]; - this.config['end_listen_port'] = this.config['listen_ports'][1]; - - this.config['start_outgoing_port'] = this.config['outgoing_ports'][0]; - this.config['end_outgoing_port'] = this.config['outgoing_ports'][1]; - - // Iterate through the pages and set the fields - this.categories.each(function(category) { - if (category.update && category.core) category.update(this.config); - }, this); - - // Update the config for the webui pages. - var webconfig = Deluge.Client.get_webui_config({async: false}); - this.webui.update(webconfig); - } -}); - -Deluge.UI = { - initialize: function() { - this.torrents = {}; - this.torrentIds = []; - Deluge.Client = new JSON.RPC('/json/rpc'); - - var theme = Cookie.read('theme'); - if (theme) this.setTheme(theme); - else this.setTheme('classic'); - - this.bound = { - updated: this.updated.bindWithEvent(this), - resized: this.resized.bindWithEvent(this), - toolbar_click: this.toolbar_click.bindWithEvent(this), - file_priorities: this.file_priorities.bindWithEvent(this), - labelsChanged: this.labelsChanged.bindWithEvent(this) - }; - this.loadUi.delay(100, this); - }, - - loadUi: function() { - this.vbox = new Widgets.VBox('page', {expand: true}); - - this.toolbar = new Deluge.Widgets.Toolbar(); - this.addWindow = new Deluge.Widgets.AddWindow(); - this.prefsWindow = new Deluge.Widgets.PreferencesWindow(); - - this.statusbar = new Deluge.Widgets.StatusBar(); - this.labels = new Deluge.Widgets.Labels() - this.details = new Deluge.Widgets.Details() - - this.initialize_grid() - - this.split_horz = new Widgets.SplitPane('top', this.labels, this.grid, { - pane1: {min: 150}, - pane2: {min: 100, expand: true} - }); - var details = $W('details') - this.split_vert = new Widgets.SplitPane('main', this.split_horz, details, { - direction: 'vertical', - pane1: {min: 100, expand: true}, - pane2: {min: 200} - }); - - this.vbox.addBox(this.toolbar, {fixed: true}); - this.vbox.addBox(this.split_vert); - this.vbox.addBox(this.statusbar, {fixed: true}); - this.vbox.calculatePositions(); - this.details.expand() - - this.toolbar.addEvent('button_click', this.bound.toolbar_click); - this.details.addEvent('filesAction', this.bound.file_priorities) - this.labels.addEvent('stateChanged', this.bound.labelsChanged) - details.addEvent('resize', function(e) { - this.details.expand() - }.bindWithEvent(this)) - - window.addEvent('resize', this.bound.resized); - Deluge.UI.update(); - this.overlay = $('overlay').dispose(); - }, - - initialize_grid: function() { - this.grid = new Deluge.Widgets.TorrentGrid('torrents') - - var menu = new Widgets.PopupMenu() - menu.add([ - {type:'text',action:'pause',text:'Pause',icon:'/static/images/tango/pause.png'}, - {type:'text',action:'resume',text:'Resume',icon:'/static/images/tango/start.png'}, - {type:'seperator'}, - {type:'submenu',text:'Options',icon:'/static/images/tango/preferences-system.png',items: [ - {type:'submenu',text:'D/L Speed Limit',icon:'/pixmaps/downloading16.png',items: [ - {type:'text',action:'max_download_speed',value:5,text:'5 KiB/s'}, - {type:'text',action:'max_download_speed',value:10,text:'10 KiB/s'}, - {type:'text',action:'max_download_speed',value:30,text:'30 KiB/s'}, - {type:'text',action:'max_download_speed',value:80,text:'80 KiB/s'}, - {type:'text',action:'max_download_speed',value:300,text:'300 KiB/s'}, - {type:'text',action:'max_download_speed',value:-1,text:'Unlimited'} - ]}, - {type:'submenu',text:'U/L Speed Limit',icon:'/pixmaps/seeding16.png',items: [ - {type:'text',action:'max_upload_speed',value:5,text:'5 KiB/s'}, - {type:'text',action:'max_upload_speed',value:10,text:'10 KiB/s'}, - {type:'text',action:'max_upload_speed',value:30,text:'30 KiB/s'}, - {type:'text',action:'max_upload_speed',value:80,text:'80 KiB/s'}, - {type:'text',action:'max_upload_speed',value:300,text:'300 KiB/s'}, - {type:'text',action:'max_upload_speed',value:-1,text:'Unlimited'} - ]}, - {type:'submenu',text:'Connection Limit',icon:'/static/images/tango/connections.png',items: [ - {type:'text',action:'max_connections',value:50,text:'50'}, - {type:'text',action:'max_connections',value:100,text:'100'}, - {type:'text',action:'max_connections',value:200,text:'200'}, - {type:'text',action:'max_connections',value:300,text:'300'}, - {type:'text',action:'max_connections',value:500,text:'500'}, - {type:'text',action:'max_connections',value:-1,text:'Unlimited'} - ]}, - {type:'submenu',text:'Upload Slot Limit',icon:'/template/static/icons/16/view-sort-ascending.png',items: [ - {type:'text',action:'max_upload_slots',value:0,text:'0'}, - {type:'text',action:'max_upload_slots',value:1,text:'1'}, - {type:'text',action:'max_upload_slots',value:2,text:'2'}, - {type:'text',action:'max_upload_slots',value:3,text:'3'}, - {type:'text',action:'max_upload_slots',value:5,text:'5'}, - {type:'text',action:'max_upload_slots',value:-1,text:'Unlimited'} - ]}, - {type:'toggle',action:'auto_managed',value:false,text:'Auto Managed'} - ]}, - {type:'seperator'}, - {type:'submenu',text:'Queue',icon:'/template/static/icons/16/view-sort-descending.png',items:[ - {type:'text',action:'top',text:'Top',icon:'/static/images/tango/go-top.png'}, - {type:'text',action:'up',text:'Up',icon:'/static/images/tango/queue-up.png'}, - {type:'text',action:'down',text:'Down',icon:'/static/images/tango/queue-down.png'}, - {type:'text',action:'bottom',text:'Bottom',icon:'/static/images/tango/go-bottom.png'} - ]}, - {type: 'seperator'}, - {type:'text',action:'update_tracker',text:'Update Tracker',icon:'/template/static/icons/16/view-refresh.png'}, - {type:'text',action:'edit_trackers',text:'Edit Trackers',icon:'/template/static/icons/16/gtk-edit.png'}, - {type:'seperator'}, - {type:'submenu',action:'remove',value:0,text:'Remove Torrent',icon:'/static/images/tango/list-remove.png', items:[ - {type:'text',action:'remove',value:0,text:'From Session'}, - {type:'text',action:'remove',value:1,text:'... and delete Torrent file'}, - {type:'text',action:'remove',value:2,text:'... and delete Downloaded files'}, - {type:'text',action:'remove',value:3,text:'... and delete All files'} - ]}, - {type:'seperator'}, - {type:'text',action:'force_recheck',text:'Force Recheck',icon:'/static/images/tango/edit-redo.png'}, - {type:'text',action:'move_storage',text:'Move Storage',icon:'/static/images/tango/move.png'} - ]); - - menu.addEvent('action', function(e) { - this.torrent_action(e.action, e.value) - }.bind(this)) - - this.grid.addEvent('row_menu', function(e) { - e.stop() - var value = this.grid.selectedRow.torrent.is_auto_managed; - menu.items[3].items[4].set(value) - menu.torrent_id = e.row_id - menu.show(e) - }.bindWithEvent(this)) - - this.grid.addEvent('selectedchanged', function(e) { - if ($chk(this.grid.selectedRow)) - this.details.update(this.grid.selectedRow.id); - else - this.details.update(null); - }.bindWithEvent(this)) - }, - - setTheme: function(name, fn) { - if (this.overlay) { - this.overlay.inject(document.body); - } - this.theme = name; - if (this.themecss) this.themecss.destroy(); - this.themecss = new Asset.css('/template/static/themes/' + name + '/style.css'); - Cookie.write('theme', name); - if (this.overlay) { - var refresh = function() { - this.vbox.refresh(); - this.vbox.calculatePositions(); - this.overlay.dispose(); - }.bind(this); - var check = function() { - if (document.styleSheets[2]) { - if (document.styleSheets[2].href == this.themecss.href) { - refresh(); - $clear(check); - } - } - }.periodical(50, this); - }; - }, - - run: function() { - if (!this.running) { - this.running = this.update.periodical(2000, this); - } - }, - - stop: function() { - if (this.running) { - $clear(this.running); - this.running = false; - } - }, - - update: function() { - filter = {} - if (this.labels.state != 'All') filter.state = this.labels.state - Deluge.Client.update_ui(Deluge.Keys.Grid, filter, { - onSuccess: this.bound.updated - }) - }, - - updated: function(data) { - this.torrents = new Hash(data.torrents); - this.stats = data.stats; - this.filters = data.filters - this.torrents.each(function(torrent, torrent_id) { - torrent.id = torrent_id; - }) - this.grid.update_torrents(this.torrents); - this.statusbar.update(this.stats); - - if ($chk(this.grid.selectedRow)) - this.details.update(this.grid.selectedRow.id); - else - this.details.update(null); - - this.labels.update(this.filters) - }, - - file_priorities: function(event) { - Deluge.Client.get_torrent_status(event.torrentId, ['file_priorities'], { - onSuccess: function(result) { - var priorities = result.file_priorities - priorities.each(function(priority, index) { - if (event.files.contains(index)) priorities[index] = event.action - }) - Deluge.Client.set_torrent_file_priorities(event.torrentId, priorities, { - onSuccess: function(response) { - this.details.update(event.torrentId) - }.bindWithEvent(this) - }) - }.bindWithEvent(this) - }) - }, - - resized: function(event) { - this.vbox.calculatePositions(); - }, - - toolbar_click: function(event) { - this.torrent_action(event.action); - }, - - labelsChanged: function(event) { - this.update() - }, - - torrent_action: function(action, value) { - var torrentIds = this.grid.get_selected_torrents() - switch (action) { - case 'resume': - Deluge.Client.resume_torrent(torrentIds) - break; - case 'pause': - Deluge.Client.pause_torrent(torrentIds) - break; - case 'top': - Deluge.Client.queue_top(torrentIds) - break; - case 'up': - Deluge.Client.queue_up(torrentIds) - break; - case 'down': - Deluge.Client.queue_down(torrentIds) - break; - case 'bottom': - Deluge.Client.queue_bottom(torrentIds) - break; - case 'force_recheck': - Deluge.Client.force_recheck(torrentIds) - break; - case 'update_tracker': - Deluge.Client.force_reannounce(torrentIds) - break; - case 'max_download_speed': - torrentIds.each(function(torrentId) { - Deluge.Client.set_torrent_max_download_speed(torrentId, value.toInt()) - }) - break; - case 'max_upload_speed': - torrentIds.each(function(torrentId) { - Deluge.Client.set_torrent_max_upload_speed(torrentId, value.toInt()) - }) - break; - case 'max_connections': - torrentIds.each(function(torrentId) { - Deluge.Client.set_torrent_max_connections(torrentId, value.toInt()) - }) - break; - case 'max_upload_slots': - torrentIds.each(function(torrentId) { - Deluge.Client.set_torrent_max_upload_slots(torrentId, value.toInt()) - }) - break; - case 'auto_managed': - torrentIds.each(function(torrentId) { - Deluge.Client.set_torrent_auto_managed(torrentId, value) - }) - break; - case 'add': - this.addWindow.show() - break; - case 'remove': - var removeTorrent = false, removeFiles = false; - if (value == 1) removeTorrent = true; - else if (value == 2) removeFiles = true; - else if (value > 3) { - removeTorrent = true; - removeFiles = true; - } - Deluge.Client.remove_torrent(torrentIds, removeTorrent, removeFiles); - break; - case 'preferences': - this.prefsWindow.show() - break; - default: - break; - } - this.update() - } -}; - -window.addEvent('domready', function(e) { - Deluge.UI.initialize(); - Deluge.UI.run(); -}); - - diff --git a/deluge/ui/webui/templates/ajax/static/js/mooui.js b/deluge/ui/webui/templates/ajax/static/js/mooui.js index 0c2773dc8..5802a0fe7 100644 --- a/deluge/ui/webui/templates/ajax/static/js/mooui.js +++ b/deluge/ui/webui/templates/ajax/static/js/mooui.js @@ -128,7 +128,7 @@ Array.implement({ Element.implement({ getInnerSize: function() { this.getPadding() - if ((/^(?:body|html)$/i).test(this.tagName)) return this.getWindow().getSize(); + if ((/^(?:body|html)$/i).test(this.tagName)) return window.getSize(); return {x: this.clientWidth - this.padding.x, y: this.clientHeight - this.padding.y}; }, @@ -1479,4 +1479,4 @@ Widgets.DataGrid = new Class({ this.getById(row.id).update(row) if (!noRender) this.render() } -}) \ No newline at end of file +})