diff --git a/src/Icons/skin/delete22.png b/src/Icons/skin/delete22.png new file mode 100644 index 000000000..bb8442533 Binary files /dev/null and b/src/Icons/skin/delete22.png differ diff --git a/src/Icons/skin/delete_perm22.png b/src/Icons/skin/delete_perm22.png new file mode 100644 index 000000000..336be3803 Binary files /dev/null and b/src/Icons/skin/delete_perm22.png differ diff --git a/src/Icons/skin/pause22.png b/src/Icons/skin/pause22.png new file mode 100644 index 000000000..642d1dcba Binary files /dev/null and b/src/Icons/skin/pause22.png differ diff --git a/src/Icons/skin/play22.png b/src/Icons/skin/play22.png new file mode 100644 index 000000000..5516f87a2 Binary files /dev/null and b/src/Icons/skin/play22.png differ diff --git a/src/icons.qrc b/src/icons.qrc index 6cb0c83fa..1cee22384 100644 --- a/src/icons.qrc +++ b/src/icons.qrc @@ -24,6 +24,7 @@ Icons/skin/handle-icon.gif Icons/skin/url.png Icons/skin/stalledUP.png + Icons/skin/delete_perm22.png Icons/skin/filteractive.png Icons/skin/connected.png Icons/skin/pausedDL.png @@ -37,10 +38,13 @@ Icons/skin/qb_question.png Icons/skin/download.png Icons/skin/open.png + Icons/skin/play22.png Icons/skin/qbittorrent16.png Icons/skin/downloading.png Icons/skin/filterinactive.png + Icons/skin/pause22.png Icons/skin/pause_all.png + Icons/skin/delete22.png Icons/skin/play_all.png Icons/skin/pause.png Icons/skin/firewalled.png diff --git a/src/torrentpersistentdata.h b/src/torrentpersistentdata.h index a9a88cdd3..bdb1ae352 100644 --- a/src/torrentpersistentdata.h +++ b/src/torrentpersistentdata.h @@ -222,7 +222,7 @@ public: QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); QHash all_data = settings.value("torrents", QHash()).toHash(); QHash data = all_data[hash].toHash(); - qDebug("TorrentPersistentData: getSavePath %s", data["save_path"].toString().toLocal8Bit().data()); + //qDebug("TorrentPersistentData: getSavePath %s", data["save_path"].toString().toLocal8Bit().data()); return data["save_path"].toString(); } diff --git a/src/webui.qrc b/src/webui.qrc index fb1c22824..6af00ad25 100644 --- a/src/webui.qrc +++ b/src/webui.qrc @@ -14,7 +14,6 @@ webui/css/mocha.css webui/css/dynamicTable.css webui/css/style.css - webui/css/mootabs1.2.css webui/scripts/excanvas-compressed.js webui/scripts/mocha.js webui/scripts/mocha-init.js @@ -23,7 +22,7 @@ webui/scripts/dynamicTable.js webui/scripts/client.js webui/scripts/download.js - webui/scripts/mootabs1.2.js webui/scripts/progressbar.js + webui/scripts/contextmenu.js diff --git a/src/webui/css/mootabs1.2.css b/src/webui/css/mootabs1.2.css deleted file mode 100644 index 029e1cff9..000000000 --- a/src/webui/css/mootabs1.2.css +++ /dev/null @@ -1,92 +0,0 @@ -/* - * MIT License - * Copyright (c) 2008 Christophe Dumez - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* - * Original code from http://www.silverscripting.com/mootabs/ - * Edited by Christophe Dumez - */ - -.toolbarTabs { - padding: 0 5px 2px 2px; - background: url(../images/skin/tabs.gif) repeat-x; - background-position: left -70px; - overflow: visible; -} - -.mootabs_title { - padding-top: 1px; - list-style: none; - margin: 0; - padding: 0; - line-height: 16px; - font-size: 11px; -} - -.mootabs_title li { - display: block; - float: left; - margin: 0 0 5px 0; - cursor: pointer; - background: url(../images/skin/tabs.gif) repeat-x; - background-position: left -35px; - -} - -.mootabs_title li.active { - background: url(../images/skin/tabs.gif) repeat-x; - background-position: left 0; -} - -.mootabs_title li a { - display: block; - margin-left: 8px; - padding: 6px 16px 5px 10px; - text-align: center; - font-weight: normal; - color: #141414; - background: url(../images/skin/tabs.gif) repeat-x; - background-position: right -35px; -} - -.mootabs_title li.active a { - color: #141414; - font-weight: bold; - background: url(../images/skin/tabs.gif) repeat-x; - background-position: right 0; -} - -.mootabs_panel { - display: none; - background-color: #ddd; - position: relative; - width: 100%; - top: -1px; - clear: both; - overflow: auto; - -} - -.mootabs_panel.active { - background-color: #e6e6e6; - display: block; -} \ No newline at end of file diff --git a/src/webui/css/style.css b/src/webui/css/style.css index 8b3d9f82a..ae798abb3 100644 --- a/src/webui/css/style.css +++ b/src/webui/css/style.css @@ -154,3 +154,19 @@ a.propButton { a.propButton img { margin-bottom: -4px; } + +/* context menu specific */ +#contextmenu { border:1px solid #999; padding:0; background:#eee; width:200px; list-style-type:none; display:none; } +#contextmenu .separator { border-top:1px solid #999; } +#contextmenu li { margin:0; padding:0; } +#contextmenu li a { display:block; padding:5px 10px 5px 35px; width:155px; font-size:12px; text-decoration:none; font-family:tahoma,arial,sans-serif; color:#000; background-position:8px 2px; background-repeat:no-repeat; } +#contextmenu li a:hover { background-color:#ddd; } +#contextmenu li a.disabled { color:#ccc; font-style:italic; } +#contextmenu li a.disabled:hover { background-color:#eee; } + +/* context menu items */ +#contextmenu li a.pause { background-image:url(../images/skin/pause22.png); } +#contextmenu li a.start { background-image:url(../images/skin/play22.png); } +#contextmenu li a.recheck { background-image:url(../images/oxygen/gear.png); } +#contextmenu li a.delete { background-image:url(../images/skin/delete22.png); } +#contextmenu li a.deleteHD { background-image:url(../images/skin/delete_perm22.png); } diff --git a/src/webui/index.html b/src/webui/index.html index 2b9935dec..bd9e3e07a 100644 --- a/src/webui/index.html +++ b/src/webui/index.html @@ -16,6 +16,7 @@ +
@@ -75,5 +76,12 @@
+ diff --git a/src/webui/scripts/contextmenu.js b/src/webui/scripts/contextmenu.js new file mode 100644 index 000000000..0b7aeebb4 --- /dev/null +++ b/src/webui/scripts/contextmenu.js @@ -0,0 +1,155 @@ +var ContextMenu = new Class({ + + //implements + Implements: [Options,Events], + + //options + options: { + actions: {}, + menu: 'contextmenu', + stopEvent: true, + targets: 'body', + trigger: 'contextmenu', + offsets: { x:0, y:0 }, + onShow: $empty, + onHide: $empty, + onClick: $empty, + fadeSpeed: 200 + }, + + //initialization + initialize: function(options) { + //set options + this.setOptions(options) + + //option diffs menu + this.menu = $(this.options.menu); + this.targets = $$(this.options.targets); + + //fx + this.fx = new Fx.Tween(this.menu, { property: 'opacity', duration:this.options.fadeSpeed }); + + //hide and begin the listener + this.hide().startListener(); + + //hide the menu + this.menu.setStyles({ 'position':'absolute','top':'-900000px', 'display':'block' }); + }, + + addTarget: function(t) { + this.targets[this.targets.length] = t; + t.addEvent(this.options.trigger,function(e) { + //enabled? + if(!this.options.disabled) { + //prevent default, if told to + if(this.options.stopEvent) { e.stop(); } + //record this as the trigger + this.options.element = $(t); + //position the menu + this.menu.setStyles({ + top: (e.page.y + this.options.offsets.y), + left: (e.page.x + this.options.offsets.x), + position: 'absolute', + 'z-index': '2000' + }); + //show the menu + this.show(); + } + }.bind(this)); + }, + + //get things started + startListener: function() { + /* all elements */ + this.targets.each(function(el) { + /* show the menu */ + el.addEvent(this.options.trigger,function(e) { + //enabled? + if(!this.options.disabled) { + //prevent default, if told to + if(this.options.stopEvent) { e.stop(); } + //record this as the trigger + this.options.element = $(el); + //position the menu + this.menu.setStyles({ + top: (e.page.y + this.options.offsets.y), + left: (e.page.x + this.options.offsets.x), + position: 'absolute', + 'z-index': '2000' + }); + //show the menu + this.show(); + } + }.bind(this)); + },this); + + /* menu items */ + this.menu.getElements('a').each(function(item) { + item.addEvent('click',function(e) { + if(!item.hasClass('disabled')) { + this.execute(item.get('href').split('#')[1],$(this.options.element)); + this.fireEvent('click',[item,e]); + } + }.bind(this)); + },this); + + //hide on body click + $(document.body).addEvent('click', function() { + this.hide(); + }.bind(this)); + }, + + //show menu + show: function(trigger) { + //this.menu.fade('in'); + this.fx.start(1); + this.fireEvent('show'); + this.shown = true; + return this; + }, + + //hide the menu + hide: function(trigger) { + if(this.shown) + { + this.fx.start(0); + //this.menu.fade('out'); + this.fireEvent('hide'); + this.shown = false; + } + return this; + }, + + //disable an item + disableItem: function(item) { + this.menu.getElements('a[href$=' + item + ']').addClass('disabled'); + return this; + }, + + //enable an item + enableItem: function(item) { + this.menu.getElements('a[href$=' + item + ']').removeClass('disabled'); + return this; + }, + + //diable the entire menu + disable: function() { + this.options.disabled = true; + return this; + }, + + //enable the entire menu + enable: function() { + this.options.disabled = false; + return this; + }, + + //execute an action + execute: function(action,element) { + if(this.options.actions[action]) { + this.options.actions[action](element,this); + } + return this; + } + +}); \ No newline at end of file diff --git a/src/webui/scripts/dynamicTable.js b/src/webui/scripts/dynamicTable.js index a2e7995e9..8d3c6b49d 100644 --- a/src/webui/scripts/dynamicTable.js +++ b/src/webui/scripts/dynamicTable.js @@ -36,13 +36,14 @@ var dynamicTable = new Class ({ initialize: function(){ }, - setup: function(table, progressIndex){ + setup: function(table, progressIndex, context_menu){ this.table = $(table); this.rows = new Hash(); this.cur = new Array(); this.priority_hidden = false; this.progressIndex = progressIndex; this.filter = 'all'; + this.context_menu = context_menu; }, getCurrentTorrentHash: function() { @@ -130,6 +131,7 @@ var dynamicTable = new Class ({ return; } var tr = new Element('tr'); + tr.addClass("menu-target"); this.rows.set(id, tr); for(var i=0; i - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* - * Original code from http://www.silverscripting.com/mootabs/ - * Ported to Mootools 1.2 by Christophe Dumez - */ - -var mootabs = new Class({ - - Implements: [Options], - - options: { - width: '300px', - height: '200px', - changeTransition: Fx.Transitions.Bounce.easeOut, - duration: 1000, - mouseOverClass: 'over', - activateOnLoad: 'first', - useAjax: false, - ajaxUrl: '', - ajaxOptions: {method:'get', evalScripts: true}, - ajaxLoadingText: 'Loading...' - }, - - initialize: function(element, options) { - - if(options) this.setOptions(options); - - this.el = $(element); - this.elid = element; - - this.el.setStyles({ - height: this.options.height, - width: this.options.width - }); - - this.titles = $$('#' + this.elid + ' ul li'); - this.panelHeight = this.el.getSize().y - (this.titles[0].getSize().y + 4); - this.panels = $$('#' + this.elid + ' .mootabs_panel'); - - - this.panels.setStyle('height', this.panelHeight); - - this.titles.each(function(item) { - item.addEvent('click', function(){ - if(item != this.activeTitle) - { - item.removeClass(this.options.mouseOverClass); - this.activate(item); - } - - }.bind(this)); - - item.addEvent('mouseover', function() { - if(item != this.activeTitle) - { - item.addClass(this.options.mouseOverClass); - } - }.bind(this)); - - item.addEvent('mouseout', function() { - if(item != this.activeTitle) - { - item.removeClass(this.options.mouseOverClass); - } - }.bind(this)); - }.bind(this)); - - - if(this.options.activateOnLoad != 'none') - { - if(this.options.activateOnLoad == 'first') - { - this.activate(this.titles[0], true); - } - else - { - this.activate(this.options.activateOnLoad, true); - } - } - }, - - activate: function(tab, skipAnim){ - if(! $defined(skipAnim)) - { - skipAnim = false; - } - if($type(tab) == 'string') - { - myTab = $$('#' + this.elid + ' ul li').filter('[title=' + tab + ']')[0]; - tab = myTab; - } - - if($type(tab) == 'element') - { - var newTab = tab.getProperty('title'); - - this.panels.removeClass('active'); - - this.activePanel = this.panels.filter('#' + newTab)[0]; - - this.activePanel.addClass('active'); - - if(this.options.changeTransition != 'none' && skipAnim==false) - { - this.panels.filter('#' + newTab).setStyle('height', 0); - var changeEffect = new Fx.Elements(this.panels.filter('#' + newTab), {duration: this.options.duration, transition: this.options.changeTransition}); - changeEffect.start({ - '0': { - 'height': [0, this.panelHeight] - } - }); - } - - this.titles.removeClass('active'); - - tab.addClass('active'); - - this.activeTitle = tab; - - if(this.options.useAjax) - { - this._getContent(); - } - } - }, - - _getContent: function(){ - this.activePanel.setHTML(this.options.ajaxLoadingText); - var newOptions = { - url: this.options.ajaxUrl + '?tab=' + this.activeTitle.getProperty('title'), - update: this.activePanel.getProperty('id') - }; - this.options.ajaxOptions = $merge(this.options.ajaxOptions, newOptions); - var tabRequest = new Request.HTML(this.options.ajaxOptions); - tabRequest.send(); - }, - - addTab: function(title, label, content){ - //the new title - var newTitle = new Element('li', { - 'title': title - }); - newTitle.appendText(label); - this.titles.include(newTitle); - $$('#' + this.elid + ' ul').adopt(newTitle); - newTitle.addEvent('click', function() { - this.activate(newTitle); - }.bind(this)); - - newTitle.addEvent('mouseover', function() { - if(newTitle != this.activeTitle) - { - newTitle.addClass(this.options.mouseOverClass); - } - }.bind(this)); - newTitle.addEvent('mouseout', function() { - if(newTitle != this.activeTitle) - { - newTitle.removeClass(this.options.mouseOverClass); - } - }.bind(this)); - //the new panel - var newPanel = new Element('div', { - 'style': {'height': this.options.panelHeight}, - 'id': title, - 'class': 'mootabs_panel' - }); - if(!this.options.useAjax) - { - newPanel.setHTML(content); - } - this.panels.include(newPanel); - this.el.adopt(newPanel); - }, - - removeTab: function(title){ - if(this.activeTitle.title == title) - { - this.activate(this.titles[0]); - } - $$('#' + this.elid + ' ul li').filter('[title=' + title + ']')[0].remove(); - - $$('#' + this.elid + ' .mootabs_panel').filter('#' + title)[0].remove(); - }, - - next: function(){ - var nextTab = this.activeTitle.getNext(); - if(!nextTab) { - nextTab = this.titles[0]; - } - this.activate(nextTab); - }, - - previous: function(){ - var previousTab = this.activeTitle.getPrevious(); - if(!previousTab) { - previousTab = this.titles[this.titles.length - 1]; - } - this.activate(previousTab); - } -}); \ No newline at end of file diff --git a/src/webui/transferlist.html b/src/webui/transferlist.html index 281125a17..38ee5b2f5 100644 --- a/src/webui/transferlist.html +++ b/src/webui/transferlist.html @@ -17,6 +17,33 @@ - \ No newline at end of file + + \ No newline at end of file