mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-23 21:14:33 +00:00
Merge pull request #4661 from buinsky/WebUI_labels_menu
WebUI: Implement labels filter context menu
This commit is contained in:
commit
2a20855c17
@ -115,6 +115,8 @@ QMap<QString, QMap<QString, WebApplication::Action> > WebApplication::initialize
|
|||||||
ADD_ACTION(command, bottomPrio);
|
ADD_ACTION(command, bottomPrio);
|
||||||
ADD_ACTION(command, recheck);
|
ADD_ACTION(command, recheck);
|
||||||
ADD_ACTION(command, setCategory);
|
ADD_ACTION(command, setCategory);
|
||||||
|
ADD_ACTION(command, addCategory);
|
||||||
|
ADD_ACTION(command, removeCategories);
|
||||||
ADD_ACTION(command, getSavePath);
|
ADD_ACTION(command, getSavePath);
|
||||||
ADD_ACTION(version, api);
|
ADD_ACTION(version, api);
|
||||||
ADD_ACTION(version, api_min);
|
ADD_ACTION(version, api_min);
|
||||||
@ -728,6 +730,31 @@ void WebApplication::action_command_setCategory()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebApplication::action_command_addCategory()
|
||||||
|
{
|
||||||
|
CHECK_URI(0);
|
||||||
|
CHECK_PARAMETERS("category");
|
||||||
|
|
||||||
|
QString category = request().posts["category"].trimmed();
|
||||||
|
|
||||||
|
if (!BitTorrent::Session::isValidCategoryName(category) && !category.isEmpty()) {
|
||||||
|
status(400, tr("Incorrect category name"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitTorrent::Session::instance()->addCategory(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebApplication::action_command_removeCategories()
|
||||||
|
{
|
||||||
|
CHECK_URI(0);
|
||||||
|
CHECK_PARAMETERS("categories");
|
||||||
|
|
||||||
|
QStringList categories = request().posts["categories"].split('\n');
|
||||||
|
foreach (const QString &category, categories)
|
||||||
|
BitTorrent::Session::instance()->removeCategory(category);
|
||||||
|
}
|
||||||
|
|
||||||
void WebApplication::action_command_getSavePath()
|
void WebApplication::action_command_getSavePath()
|
||||||
{
|
{
|
||||||
CHECK_URI(0);
|
CHECK_URI(0);
|
||||||
|
@ -88,6 +88,8 @@ private:
|
|||||||
void action_command_bottomPrio();
|
void action_command_bottomPrio();
|
||||||
void action_command_recheck();
|
void action_command_recheck();
|
||||||
void action_command_setCategory();
|
void action_command_setCategory();
|
||||||
|
void action_command_addCategory();
|
||||||
|
void action_command_removeCategories();
|
||||||
void action_command_getSavePath();
|
void action_command_getSavePath();
|
||||||
void action_version_api();
|
void action_version_api();
|
||||||
void action_version_api_min();
|
void action_version_api_min();
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
<div id="pageWrapper">
|
<div id="pageWrapper">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul id="contextmenu">
|
<ul id="torrentsTableMenu" class="contextMenu">
|
||||||
<li><a href="#Start"><img src="theme/media-playback-start" alt="QBT_TR(Resume)QBT_TR"/> QBT_TR(Resume)QBT_TR</a></li>
|
<li><a href="#Start"><img src="theme/media-playback-start" alt="QBT_TR(Resume)QBT_TR"/> QBT_TR(Resume)QBT_TR</a></li>
|
||||||
<li><a href="#Pause"><img src="theme/media-playback-pause" alt="QBT_TR(Pause)QBT_TR"/> QBT_TR(Pause)QBT_TR</a></li>
|
<li><a href="#Pause"><img src="theme/media-playback-pause" alt="QBT_TR(Pause)QBT_TR"/> QBT_TR(Pause)QBT_TR</a></li>
|
||||||
<li><a href="#ForceStart"><img src="theme/media-seek-forward" alt="QBT_TR(Force Resume)QBT_TR"/> QBT_TR(Force Resume)QBT_TR</a></li>
|
<li><a href="#ForceStart"><img src="theme/media-seek-forward" alt="QBT_TR(Force Resume)QBT_TR"/> QBT_TR(Force Resume)QBT_TR</a></li>
|
||||||
@ -125,6 +125,14 @@
|
|||||||
<li><a href="#FirstLastPiecePrio"><img src="theme/checked" alt="QBT_TR(Download first and last pieces first)QBT_TR"/> QBT_TR(Download first and last pieces first)QBT_TR</a></li>
|
<li><a href="#FirstLastPiecePrio"><img src="theme/checked" alt="QBT_TR(Download first and last pieces first)QBT_TR"/> QBT_TR(Download first and last pieces first)QBT_TR</a></li>
|
||||||
<li class="separator"><a href="#ForceRecheck"><img src="theme/document-edit-verify" alt="QBT_TR(Force recheck)QBT_TR"/> QBT_TR(Force recheck)QBT_TR</a></li>
|
<li class="separator"><a href="#ForceRecheck"><img src="theme/document-edit-verify" alt="QBT_TR(Force recheck)QBT_TR"/> QBT_TR(Force recheck)QBT_TR</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<ul id="categoriesFilterMenu" class="contextMenu">
|
||||||
|
<li><a href="#CreateCategory"><img src="theme/list-add" alt="QBT_TR(Add category...)QBT_TR"/> QBT_TR(Add category...)QBT_TR</a></li>
|
||||||
|
<li><a href="#DeleteCategory"><img src="theme/list-remove" alt="QBT_TR(Remove category)QBT_TR"/> QBT_TR(Remove category)QBT_TR</a></li>
|
||||||
|
<li><a href="#DeleteUnusedCategories"><img src="theme/list-remove" alt="QBT_TR(Remove unused categories)QBT_TR"/> QBT_TR(Remove unused categories)QBT_TR</a></li>
|
||||||
|
<li class="separator"><a href="#StartTorrentsByCategory"><img src="theme/media-playback-start" alt="QBT_TR(Resume torrents)QBT_TR"/> QBT_TR(Resume torrents)QBT_TR</a></li>
|
||||||
|
<li><a href="#PauseTorrentsByCategory"><img src="theme/media-playback-pause" alt="QBT_TR(Pause torrents)QBT_TR"/> QBT_TR(Pause torrents)QBT_TR</a></li>
|
||||||
|
<li><a href="#DeleteTorrentsByCategory"><img src="theme/edit-delete" alt="QBT_TR(Delete torrents)QBT_TR"/> QBT_TR(Delete torrents)QBT_TR</a></li>
|
||||||
|
</ul>
|
||||||
<div id="desktopFooterWrapper">
|
<div id="desktopFooterWrapper">
|
||||||
<div id="desktopFooter">
|
<div id="desktopFooter">
|
||||||
<span id="error_div"></span>
|
<span id="error_div"></span>
|
||||||
|
@ -167,14 +167,14 @@ a.propButton img {
|
|||||||
|
|
||||||
/* context menu specific */
|
/* context menu specific */
|
||||||
|
|
||||||
#contextmenu { border:1px solid #999; padding:0; background:#eee; list-style-type:none; display:none;}
|
.contextMenu { border:1px solid #999; padding:0; background:#eee; list-style-type:none; display:none;}
|
||||||
#contextmenu .separator { border-top:1px solid #999; }
|
.contextMenu .separator { border-top:1px solid #999; }
|
||||||
#contextmenu li { margin:0; padding:0;}
|
.contextMenu li { margin:0; padding:0;}
|
||||||
#contextmenu li a { display:block; padding:5px 10px 5px 5px; font-size:12px; text-decoration:none; font-family:tahoma,arial,sans-serif; color:#000; }
|
.contextMenu li a { display:block; padding:5px 10px 5px 5px; font-size:12px; text-decoration:none; font-family:tahoma,arial,sans-serif; color:#000; }
|
||||||
#contextmenu li a:hover { background-color:#ddd; }
|
.contextMenu li a:hover { background-color:#ddd; }
|
||||||
#contextmenu li a.disabled { color:#ccc; font-style:italic; }
|
.contextMenu li a.disabled { color:#ccc; font-style:italic; }
|
||||||
#contextmenu li a.disabled:hover { background-color:#eee; }
|
.contextMenu li a.disabled:hover { background-color:#eee; }
|
||||||
#contextmenu li ul {
|
.contextMenu li ul {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border:1px solid #999; padding:0; background:#eee;
|
border:1px solid #999; padding:0; background:#eee;
|
||||||
list-style-type:none;
|
list-style-type:none;
|
||||||
@ -184,24 +184,24 @@ a.propButton img {
|
|||||||
margin: -29px 0 0 100%;
|
margin: -29px 0 0 100%;
|
||||||
width: 164px;
|
width: 164px;
|
||||||
}
|
}
|
||||||
#contextmenu li ul li a {
|
.contextMenu li ul li a {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
#contextmenu li a.arrow-right, #contextmenu li a:hover.arrow-right {
|
.contextMenu li a.arrow-right, .contextMenu li a:hover.arrow-right {
|
||||||
background-image: url(../images/skin/arrow-right.gif);
|
background-image: url(../images/skin/arrow-right.gif);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: right center;
|
background-position: right center;
|
||||||
}
|
}
|
||||||
#contextmenu li:hover ul,
|
.contextMenu li:hover ul,
|
||||||
#contextmenu li.ieHover ul,
|
.contextMenu li.ieHover ul,
|
||||||
#contextmenu li li.ieHover ul,
|
.contextMenu li li.ieHover ul,
|
||||||
#contextmenu li li li.ieHover ul,
|
.contextMenu li li li.ieHover ul,
|
||||||
#contextmenu li li:hover ul,
|
.contextMenu li li:hover ul,
|
||||||
#contextmenu li li li:hover ul { /* lists nested under hovered list items */
|
.contextMenu li li li:hover ul { /* lists nested under hovered list items */
|
||||||
left: auto;
|
left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#contextmenu li img {
|
.contextMenu li img {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
margin-bottom: -4px;
|
margin-bottom: -4px;
|
||||||
|
@ -14,3 +14,37 @@
|
|||||||
<span class="filterTitle">QBT_TR(Categories)QBT_TR</span>
|
<span class="filterTitle">QBT_TR(Categories)QBT_TR</span>
|
||||||
<ul id="filterCategoryList" class="filterList">
|
<ul id="filterCategoryList" class="filterList">
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var categoriesFilterContextMenu = new CategoriesFilterContextMenu({
|
||||||
|
targets : '.categoriesFilterContextMenuTarget',
|
||||||
|
menu : 'categoriesFilterMenu',
|
||||||
|
actions : {
|
||||||
|
CreateCategory : function (element, ref) {
|
||||||
|
createCategoryFN();
|
||||||
|
},
|
||||||
|
DeleteCategory : function (element, ref) {
|
||||||
|
removeCategoryFN(element.id);
|
||||||
|
},
|
||||||
|
DeleteUnusedCategories : function (element, ref) {
|
||||||
|
deleteUnusedCategoriesFN();
|
||||||
|
},
|
||||||
|
StartTorrentsByCategory : function (element, ref) {
|
||||||
|
startTorrentsByCategoryFN(element.id);
|
||||||
|
},
|
||||||
|
PauseTorrentsByCategory : function (element, ref) {
|
||||||
|
pauseTorrentsByCategoryFN(element.id);
|
||||||
|
},
|
||||||
|
DeleteTorrentsByCategory : function (element, ref) {
|
||||||
|
deleteTorrentsByCategoryFN(element.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
offsets : {
|
||||||
|
x : -15,
|
||||||
|
y : 2
|
||||||
|
},
|
||||||
|
onShow: function () {
|
||||||
|
this.options.element.firstChild.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -31,17 +31,32 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var hashesList = new URI().getData('hashes');
|
var hashesList = new URI().getData('hashes');
|
||||||
new Request({
|
if (!hashesList) {
|
||||||
url: 'command/setCategory',
|
new Request({
|
||||||
method: 'post',
|
url: 'command/addCategory',
|
||||||
data: {
|
method: 'post',
|
||||||
hashes: hashesList,
|
data: {
|
||||||
category: categoryName
|
category: categoryName
|
||||||
},
|
},
|
||||||
onComplete: function() {
|
onComplete: function () {
|
||||||
window.parent.closeWindows();
|
window.parent.closeWindows();
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new Request({
|
||||||
|
url: 'command/setCategory',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: hashesList,
|
||||||
|
category: categoryName
|
||||||
|
},
|
||||||
|
onComplete: function () {
|
||||||
|
window.parent.closeWindows();
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -202,32 +202,8 @@ window.addEvent('load', function () {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateContextMenu = function () {
|
|
||||||
var categoryList = $('contextCategoryList');
|
|
||||||
categoryList.empty();
|
|
||||||
categoryList.appendChild(new Element('li', {html: '<a href="javascript:newCategoryFN();"><img src="theme/list-add" alt="QBT_TR(New...)QBT_TR"/> QBT_TR(New...)QBT_TR</a>'}));
|
|
||||||
categoryList.appendChild(new Element('li', {html: '<a href="javascript:updateCategoryFN(0);"><img src="theme/edit-clear" alt="QBT_TR(Reset)QBT_TR"/> QBT_TR(Reset)QBT_TR</a>'}));
|
|
||||||
|
|
||||||
var sortedCategories = []
|
|
||||||
Object.each(category_list, function(category) {
|
|
||||||
sortedCategories.push(category.name);
|
|
||||||
});
|
|
||||||
sortedCategories.sort();
|
|
||||||
|
|
||||||
var first = true;
|
|
||||||
Object.each(sortedCategories, function(categoryName) {
|
|
||||||
var categoryHash = genHash(categoryName);
|
|
||||||
var el = new Element('li', {html: '<a href="javascript:updateCategoryFN(\'' + categoryHash + '\');"><img src="theme/inode-directory"/> ' + categoryName + '</a>'});
|
|
||||||
if (first) {
|
|
||||||
el.addClass('separator');
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
categoryList.appendChild(el);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var updateFilter = function(filter, filterTitle) {
|
var updateFilter = function(filter, filterTitle) {
|
||||||
$(filter + '_filter').firstChild.childNodes[1].nodeValue = filterTitle.replace('%1', torrentsTable.getFilteredTorrentsNumber(filter));
|
$(filter + '_filter').firstChild.childNodes[1].nodeValue = filterTitle.replace('%1', torrentsTable.getFilteredTorrentsNumber(filter, CATEGORIES_ALL));
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateFiltersList = function() {
|
var updateFiltersList = function() {
|
||||||
@ -251,8 +227,10 @@ window.addEvent('load', function () {
|
|||||||
var create_link = function(hash, text, count) {
|
var create_link = function(hash, text, count) {
|
||||||
var html = '<a href="#" onclick="setCategoryFilter(' + hash + ');return false;">' +
|
var html = '<a href="#" onclick="setCategoryFilter(' + hash + ');return false;">' +
|
||||||
'<img src="theme/inode-directory"/>' +
|
'<img src="theme/inode-directory"/>' +
|
||||||
text + ' (' + count + ')' + '</a>';
|
escapeHtml(text) + ' (' + count + ')' + '</a>';
|
||||||
return new Element('li', {id: hash, html: html});
|
var el = new Element('li', {id: hash, html: html});
|
||||||
|
categoriesFilterContextMenu.addTarget(el);
|
||||||
|
return el;
|
||||||
};
|
};
|
||||||
|
|
||||||
var all = torrentsTable.getRowIds().length;
|
var all = torrentsTable.getRowIds().length;
|
||||||
@ -357,7 +335,7 @@ window.addEvent('load', function () {
|
|||||||
updateFiltersList();
|
updateFiltersList();
|
||||||
if (update_categories) {
|
if (update_categories) {
|
||||||
updateCategoryList();
|
updateCategoryList();
|
||||||
updateContextMenu();
|
torrentsTableContextMenu.updateCategoriesSubMenu(category_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearTimeout(syncMainDataTimer);
|
clearTimeout(syncMainDataTimer);
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
var lastShownContexMenu = null;
|
||||||
var ContextMenu = new Class({
|
var ContextMenu = new Class({
|
||||||
|
|
||||||
//implements
|
//implements
|
||||||
Implements: [Options, Events],
|
Implements: [Options, Events],
|
||||||
|
|
||||||
//options
|
//options
|
||||||
options: {
|
options: {
|
||||||
actions: {},
|
actions: {},
|
||||||
menu: 'contextmenu',
|
menu: 'menu_id',
|
||||||
stopEvent: true,
|
stopEvent: true,
|
||||||
targets: 'body',
|
targets: 'body',
|
||||||
trigger: 'contextmenu',
|
trigger: 'contextmenu',
|
||||||
@ -54,6 +54,57 @@ var ContextMenu = new Class({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
adjustMenuPosition: function(e) {
|
||||||
|
this.updateMenuItems();
|
||||||
|
|
||||||
|
// draw the menu off-screen to know the menu dimentions
|
||||||
|
this.menu.setStyles({
|
||||||
|
left: '-999em',
|
||||||
|
top: '-999em'
|
||||||
|
});
|
||||||
|
|
||||||
|
// position the menu
|
||||||
|
var xPos = e.page.x + this.options.offsets.x;
|
||||||
|
var yPos = e.page.y + this.options.offsets.y;
|
||||||
|
if (xPos + this.menu.offsetWidth > document.documentElement.clientWidth)
|
||||||
|
xPos -= this.menu.offsetWidth;
|
||||||
|
if (yPos + this.menu.offsetHeight > document.documentElement.clientHeight)
|
||||||
|
yPos -= this.menu.offsetHeight;
|
||||||
|
if (xPos < 0)
|
||||||
|
xPos = 0;
|
||||||
|
if (yPos < 0)
|
||||||
|
yPos = 0;
|
||||||
|
this.menu.setStyles({
|
||||||
|
left: xPos,
|
||||||
|
top: yPos,
|
||||||
|
position: 'absolute',
|
||||||
|
'z-index': '2000'
|
||||||
|
});
|
||||||
|
|
||||||
|
// position the sub-menu
|
||||||
|
var uls = this.menu.getElementsByTagName('ul');
|
||||||
|
for (var i = 0; i < uls.length; i++) {
|
||||||
|
var ul = uls[i];
|
||||||
|
var rectParent = ul.parentNode.getBoundingClientRect();
|
||||||
|
var xPosOrigin = rectParent.left;
|
||||||
|
var yPosOrigin = rectParent.bottom;
|
||||||
|
var xPos = xPosOrigin + rectParent.width - 1;
|
||||||
|
var yPos = yPosOrigin - rectParent.height - 1;
|
||||||
|
if (xPos + ul.offsetWidth > document.documentElement.clientWidth)
|
||||||
|
xPos -= (ul.offsetWidth + rectParent.width - 2);
|
||||||
|
if (yPos + ul.offsetHeight > document.documentElement.clientHeight)
|
||||||
|
yPos -= (ul.offsetHeight - rectParent.height - 2);
|
||||||
|
if (xPos < 0)
|
||||||
|
xPos = 0;
|
||||||
|
if (yPos < 0)
|
||||||
|
yPos = 0;
|
||||||
|
ul.setStyles({
|
||||||
|
'margin-left': xPos - xPosOrigin,
|
||||||
|
'margin-top': yPos - yPosOrigin
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addTarget: function(t) {
|
addTarget: function(t) {
|
||||||
this.targets[this.targets.length] = t;
|
this.targets[this.targets.length] = t;
|
||||||
t.addEvent(this.options.trigger, function(e) {
|
t.addEvent(this.options.trigger, function(e) {
|
||||||
@ -65,13 +116,7 @@ var ContextMenu = new Class({
|
|||||||
}
|
}
|
||||||
//record this as the trigger
|
//record this as the trigger
|
||||||
this.options.element = $(t);
|
this.options.element = $(t);
|
||||||
//position the menu
|
this.adjustMenuPosition(e);
|
||||||
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
|
//show the menu
|
||||||
this.show();
|
this.show();
|
||||||
}
|
}
|
||||||
@ -95,13 +140,7 @@ var ContextMenu = new Class({
|
|||||||
}
|
}
|
||||||
//record this as the trigger
|
//record this as the trigger
|
||||||
this.options.element = $(el);
|
this.options.element = $(el);
|
||||||
//position the menu
|
this.adjustMenuPosition(e);
|
||||||
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
|
//show the menu
|
||||||
this.show();
|
this.show();
|
||||||
}
|
}
|
||||||
@ -128,6 +167,76 @@ var ContextMenu = new Class({
|
|||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateMenuItems: function () {},
|
||||||
|
|
||||||
|
//show menu
|
||||||
|
show: function (trigger) {
|
||||||
|
if (lastShownContexMenu && lastShownContexMenu != this)
|
||||||
|
lastShownContexMenu.hide();
|
||||||
|
this.fx.start(1);
|
||||||
|
this.fireEvent('show');
|
||||||
|
this.shown = true;
|
||||||
|
lastShownContexMenu = this;
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
|
||||||
|
setItemChecked: function (item, checked) {
|
||||||
|
this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity =
|
||||||
|
checked ? '1' : '0';
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
getItemChecked: function (item) {
|
||||||
|
return '0' != this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity;
|
||||||
|
},
|
||||||
|
|
||||||
|
//hide an item
|
||||||
|
hideItem: function (item) {
|
||||||
|
this.menu.getElement('a[href$=' + item + ']').parentNode.addClass('invisible');
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
//show an item
|
||||||
|
showItem: function (item) {
|
||||||
|
this.menu.getElement('a[href$=' + item + ']').parentNode.removeClass('invisible');
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
//disable 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var TorrentsTableContextMenu = new Class({
|
||||||
|
Extends: ContextMenu,
|
||||||
|
|
||||||
updateMenuItems: function () {
|
updateMenuItems: function () {
|
||||||
all_are_seq_dl = true;
|
all_are_seq_dl = true;
|
||||||
there_are_seq_dl = false;
|
there_are_seq_dl = false;
|
||||||
@ -220,69 +329,40 @@ var ContextMenu = new Class({
|
|||||||
this.hideItem('ForceStart');
|
this.hideItem('ForceStart');
|
||||||
else if (!there_are_paused && !there_are_force_start)
|
else if (!there_are_paused && !there_are_force_start)
|
||||||
this.hideItem('Start');
|
this.hideItem('Start');
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//show menu
|
updateCategoriesSubMenu : function (category_list) {
|
||||||
show: function(trigger) {
|
var categoryList = $('contextCategoryList');
|
||||||
this.updateMenuItems();
|
categoryList.empty();
|
||||||
this.fx.start(1);
|
categoryList.appendChild(new Element('li', {html: '<a href="javascript:torrentNewCategoryFN();"><img src="theme/list-add" alt="QBT_TR(New...)QBT_TR"/> QBT_TR(New...)QBT_TR</a>'}));
|
||||||
this.fireEvent('show');
|
categoryList.appendChild(new Element('li', {html: '<a href="javascript:torrentSetCategoryFN(0);"><img src="theme/edit-clear" alt="QBT_TR(Reset)QBT_TR"/> QBT_TR(Reset)QBT_TR</a>'}));
|
||||||
this.shown = true;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
//hide the menu
|
var sortedCategories = []
|
||||||
hide: function(trigger) {
|
Object.each(category_list, function (category) {
|
||||||
if (this.shown) {
|
sortedCategories.push(category.name);
|
||||||
this.fx.start(0);
|
});
|
||||||
//this.menu.fade('out');
|
sortedCategories.sort();
|
||||||
this.fireEvent('hide');
|
|
||||||
this.shown = false;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
setItemChecked: function(item, checked) {
|
var first = true;
|
||||||
this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity =
|
Object.each(sortedCategories, function (categoryName) {
|
||||||
checked ? '1' : '0';
|
var categoryHash = genHash(categoryName);
|
||||||
return this;
|
var el = new Element('li', {html: '<a href="javascript:torrentSetCategoryFN(\'' + categoryHash + '\');"><img src="theme/inode-directory"/> ' + escapeHtml(categoryName) + '</a>'});
|
||||||
},
|
if (first) {
|
||||||
|
el.addClass('separator');
|
||||||
getItemChecked: function(item) {
|
first = false;
|
||||||
return '0' != this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity;
|
}
|
||||||
},
|
categoryList.appendChild(el);
|
||||||
|
});
|
||||||
//hide an item
|
}
|
||||||
hideItem: function(item) {
|
});
|
||||||
this.menu.getElement('a[href$=' + item + ']').parentNode.addClass('invisible');
|
|
||||||
return this;
|
var CategoriesFilterContextMenu = new Class({
|
||||||
},
|
Extends: ContextMenu,
|
||||||
|
updateMenuItems: function () {
|
||||||
//show an item
|
var id = this.options.element.id;
|
||||||
showItem: function(item) {
|
if (id != CATEGORIES_ALL && id != CATEGORIES_UNCATEGORIZED)
|
||||||
this.menu.getElement('a[href$=' + item + ']').parentNode.removeClass('invisible');
|
this.showItem('DeleteCategory');
|
||||||
return this;
|
else
|
||||||
},
|
this.hideItem('DeleteCategory');
|
||||||
|
|
||||||
//disable 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -300,7 +300,6 @@ var DynamicTable = new Class({
|
|||||||
else { // else create a new row in the table
|
else { // else create a new row in the table
|
||||||
var tr = new Element('tr');
|
var tr = new Element('tr');
|
||||||
|
|
||||||
tr.addClass("menu-target");
|
|
||||||
tr['rowId'] = rows[rowPos]['rowId'];
|
tr['rowId'] = rows[rowPos]['rowId'];
|
||||||
|
|
||||||
tr._this = this;
|
tr._this = this;
|
||||||
@ -358,7 +357,7 @@ var DynamicTable = new Class({
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setupTrEvents(tr);
|
this.setupTr(tr);
|
||||||
|
|
||||||
for (var j = 0 ; j < this.columns.length; j++) {
|
for (var j = 0 ; j < this.columns.length; j++) {
|
||||||
var td = new Element('td');
|
var td = new Element('td');
|
||||||
@ -393,7 +392,7 @@ var DynamicTable = new Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setupTrEvents : function (tr) {},
|
setupTr : function (tr) {},
|
||||||
|
|
||||||
updateRow : function (tr, fullUpdate) {
|
updateRow : function (tr, fullUpdate) {
|
||||||
var row = this.rows.get(tr.rowId);
|
var row = this.rows.get(tr.rowId);
|
||||||
@ -524,11 +523,12 @@ var TorrentsTable = new Class({
|
|||||||
else return 0;
|
else return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// name
|
// name, category
|
||||||
|
|
||||||
this.columns['name'].updateTd = function (td, row) {
|
this.columns['name'].updateTd = function (td, row) {
|
||||||
td.set('html', escapeHtml(this.getRowValue(row)));
|
td.set('html', escapeHtml(this.getRowValue(row)));
|
||||||
};
|
};
|
||||||
|
this.columns['category'].updateTd = this.columns['name'].updateTd;
|
||||||
|
|
||||||
// size
|
// size
|
||||||
|
|
||||||
@ -620,7 +620,7 @@ var TorrentsTable = new Class({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
applyFilter : function (row, filterName, categoryName) {
|
applyFilter : function (row, filterName, categoryHash) {
|
||||||
var state = row['full_data'].state;
|
var state = row['full_data'].state;
|
||||||
var inactive = false;
|
var inactive = false;
|
||||||
var r;
|
var r;
|
||||||
@ -662,28 +662,38 @@ var TorrentsTable = new Class({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (categoryName == CATEGORIES_ALL)
|
if (categoryHash == CATEGORIES_ALL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (categoryName == CATEGORIES_UNCATEGORIZED && row['full_data'].category.length === 0)
|
if (categoryHash == CATEGORIES_UNCATEGORIZED && row['full_data'].category.length === 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (categoryName != genHash(row['full_data'].category))
|
if (categoryHash != genHash(row['full_data'].category))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
getFilteredTorrentsNumber : function (filterName) {
|
getFilteredTorrentsNumber : function (filterName, categoryHash) {
|
||||||
var cnt = 0;
|
var cnt = 0;
|
||||||
var rows = this.rows.getValues();
|
var rows = this.rows.getValues();
|
||||||
|
|
||||||
for (i = 0; i < rows.length; i++)
|
for (i = 0; i < rows.length; i++)
|
||||||
if (this.applyFilter(rows[i], filterName, CATEGORIES_ALL)) cnt++;
|
if (this.applyFilter(rows[i], filterName, categoryHash)) cnt++;
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getFilteredTorrentsHashes : function (filterName, categoryHash) {
|
||||||
|
var rowsHashes = [];
|
||||||
|
var rows = this.rows.getValues();
|
||||||
|
|
||||||
|
for (i = 0; i < rows.length; i++)
|
||||||
|
if (this.applyFilter(rows[i], filterName, categoryHash))
|
||||||
|
rowsHashes.push(rows[i]['rowId']);
|
||||||
|
|
||||||
|
return rowsHashes;
|
||||||
|
},
|
||||||
|
|
||||||
getFilteredAndSortedRows : function () {
|
getFilteredAndSortedRows : function () {
|
||||||
var filteredRows = new Array();
|
var filteredRows = new Array();
|
||||||
|
|
||||||
@ -706,7 +716,7 @@ var TorrentsTable = new Class({
|
|||||||
return filteredRows;
|
return filteredRows;
|
||||||
},
|
},
|
||||||
|
|
||||||
setupTrEvents : function (tr) {
|
setupTr : function (tr) {
|
||||||
tr.addEvent('dblclick', function (e) {
|
tr.addEvent('dblclick', function (e) {
|
||||||
e.stop();
|
e.stop();
|
||||||
this._this.selectRow(this.rowId);
|
this._this.selectRow(this.rowId);
|
||||||
@ -718,6 +728,7 @@ var TorrentsTable = new Class({
|
|||||||
pauseFN();
|
pauseFN();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
tr.addClass("torrentsTableContextMenuTarget");
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrentTorrentHash : function () {
|
getCurrentTorrentHash : function () {
|
||||||
|
@ -304,7 +304,7 @@ initializeWindows = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
newCategoryFN = function () {
|
torrentNewCategoryFN = function () {
|
||||||
var h = torrentsTable.selectedRowsIds();
|
var h = torrentsTable.selectedRowsIds();
|
||||||
if (h.length) {
|
if (h.length) {
|
||||||
new MochaUI.Window({
|
new MochaUI.Window({
|
||||||
@ -323,7 +323,7 @@ initializeWindows = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCategoryFN = function (categoryHash) {
|
torrentSetCategoryFN = function (categoryHash) {
|
||||||
var categoryName = '';
|
var categoryName = '';
|
||||||
if (categoryHash != 0)
|
if (categoryHash != 0)
|
||||||
var categoryName = category_list[categoryHash].name;
|
var categoryName = category_list[categoryHash].name;
|
||||||
@ -340,6 +340,102 @@ initializeWindows = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
createCategoryFN = function () {
|
||||||
|
new MochaUI.Window({
|
||||||
|
id: 'newCategoryPage',
|
||||||
|
title: "QBT_TR(New Category)QBT_TR",
|
||||||
|
loadMethod: 'iframe',
|
||||||
|
contentURL: 'newcategory.html',
|
||||||
|
scrollbars: false,
|
||||||
|
resizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
paddingVertical: 0,
|
||||||
|
paddingHorizontal: 0,
|
||||||
|
width: 250,
|
||||||
|
height: 100
|
||||||
|
});
|
||||||
|
updateMainData();
|
||||||
|
};
|
||||||
|
|
||||||
|
removeCategoryFN = function (categoryHash) {
|
||||||
|
var categoryName = category_list[categoryHash].name;
|
||||||
|
new Request({
|
||||||
|
url: 'command/removeCategories',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
categories: categoryName
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
setCategoryFilter(CATEGORIES_ALL);
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteUnusedCategoriesFN = function () {
|
||||||
|
var categories = [];
|
||||||
|
for (var hash in category_list) {
|
||||||
|
if (torrentsTable.getFilteredTorrentsNumber('all', hash) == 0)
|
||||||
|
categories.push(category_list[hash].name);
|
||||||
|
}
|
||||||
|
new Request({
|
||||||
|
url: 'command/removeCategories',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
categories: categories.join('\n')
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
setCategoryFilter(CATEGORIES_ALL);
|
||||||
|
};
|
||||||
|
|
||||||
|
startTorrentsByCategoryFN = function (categoryHash) {
|
||||||
|
var h = torrentsTable.getFilteredTorrentsHashes('all', categoryHash);
|
||||||
|
if (h.length) {
|
||||||
|
h.each(function (hash, index) {
|
||||||
|
new Request({
|
||||||
|
url: 'command/resume',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hash: hash
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
});
|
||||||
|
updateMainData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pauseTorrentsByCategoryFN = function (categoryHash) {
|
||||||
|
var h = torrentsTable.getFilteredTorrentsHashes('all', categoryHash);
|
||||||
|
if (h.length) {
|
||||||
|
h.each(function (hash, index) {
|
||||||
|
new Request({
|
||||||
|
url: 'command/pause',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hash: hash
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
});
|
||||||
|
updateMainData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteTorrentsByCategoryFN = function (categoryHash) {
|
||||||
|
var h = torrentsTable.getFilteredTorrentsHashes('all', categoryHash);
|
||||||
|
if (h.length) {
|
||||||
|
new MochaUI.Window({
|
||||||
|
id: 'confirmDeletionPage',
|
||||||
|
title: "QBT_TR(Deletion confirmation)QBT_TR",
|
||||||
|
loadMethod: 'iframe',
|
||||||
|
contentURL: 'confirmdeletion.html?hashes=' + h.join("|"),
|
||||||
|
scrollbars: false,
|
||||||
|
resizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
padding: 10,
|
||||||
|
width: 424,
|
||||||
|
height: 140
|
||||||
|
});
|
||||||
|
updateMainData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
['pauseAll', 'resumeAll'].each(function(item) {
|
['pauseAll', 'resumeAll'].each(function(item) {
|
||||||
addClickEvent(item, function(e) {
|
addClickEvent(item, function(e) {
|
||||||
new Event(e).stop();
|
new Event(e).stop();
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
//create a context menu
|
//create a context menu
|
||||||
var torrents_table_context_menu = new ContextMenu({
|
var torrentsTableContextMenu = new TorrentsTableContextMenu({
|
||||||
targets : '.menu-target',
|
targets : '.torrentsTableContextMenuTarget',
|
||||||
menu : 'contextmenu',
|
menu : 'torrentsTableMenu',
|
||||||
actions : {
|
actions : {
|
||||||
Delete : function (element, ref) {
|
Delete : function (element, ref) {
|
||||||
deleteFN();
|
deleteFN();
|
||||||
@ -62,5 +62,5 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
torrentsTable.setup('torrentsTable', 'torrentsTableHeader', torrents_table_context_menu);
|
torrentsTable.setup('torrentsTable', 'torrentsTableHeader', torrentsTableContextMenu);
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user