From dbc5ffee759c47cbce72d52587d5420a25e3ee34 Mon Sep 17 00:00:00 2001 From: buinsky Date: Sun, 7 Dec 2014 23:33:36 +0300 Subject: [PATCH 01/13] Follow project coding style. Issue #2192. --- src/webui/abstractrequesthandler.cpp | 122 +++++++++++++-------------- 1 file changed, 57 insertions(+), 65 deletions(-) diff --git a/src/webui/abstractrequesthandler.cpp b/src/webui/abstractrequesthandler.cpp index 3152532de..1eec6cdd8 100644 --- a/src/webui/abstractrequesthandler.cpp +++ b/src/webui/abstractrequesthandler.cpp @@ -36,145 +36,137 @@ #include "abstractrequesthandler.h" AbstractRequestHandler::AbstractRequestHandler(const HttpRequest &request, const HttpEnvironment &env, WebApplication *app) - : app_(app), session_(0), request_(request), env_(env) + : app_(app), session_(0), request_(request), env_(env) { - sessionInitialize(); - if (!sessionActive() && !isAuthNeeded()) - sessionStart(); + sessionInitialize(); + if (!sessionActive() && !isAuthNeeded()) + sessionStart(); } HttpResponse AbstractRequestHandler::run() { - response_ = HttpResponse(); + response_ = HttpResponse(); - if (isBanned()) - { - status(403, "Forbidden"); - print(QObject::tr("Your IP address has been banned after too many failed authentication attempts."), CONTENT_TYPE_TXT); - } - else - { - processRequest(); - } + if (isBanned()) { + status(403, "Forbidden"); + print(QObject::tr("Your IP address has been banned after too many failed authentication attempts."), CONTENT_TYPE_TXT); + } + else { + processRequest(); + } - return response_; + return response_; } bool AbstractRequestHandler::isAuthNeeded() { - return - ( + return + ( env_.clientAddress != QHostAddress::LocalHost && env_.clientAddress != QHostAddress::LocalHostIPv6 - ) || Preferences::instance()->isWebUiLocalAuthEnabled(); + ) || Preferences::instance()->isWebUiLocalAuthEnabled(); } void AbstractRequestHandler::status(uint code, const QString& text) { - response_.status = HttpResponseStatus(code, text); + response_.status = HttpResponseStatus(code, text); } void AbstractRequestHandler::header(const QString& name, const QString& value) { - response_.headers[name] = value; + response_.headers[name] = value; } void AbstractRequestHandler::print(const QString& text, const QString& type) { - print_impl(text.toUtf8(), type); + print_impl(text.toUtf8(), type); } void AbstractRequestHandler::print(const QByteArray& data, const QString& type) { - print_impl(data, type); + print_impl(data, type); } void AbstractRequestHandler::print_impl(const QByteArray& data, const QString& type) { - if (!response_.headers.contains(HEADER_CONTENT_TYPE)) - response_.headers[HEADER_CONTENT_TYPE] = type; + if (!response_.headers.contains(HEADER_CONTENT_TYPE)) + response_.headers[HEADER_CONTENT_TYPE] = type; - if (type.indexOf("image") > -1) - response_.headers[HEADER_CACHE_CONTROL] = "max-age=3000000"; + if (type.indexOf("image") > -1) + response_.headers[HEADER_CACHE_CONTROL] = "max-age=3000000"; - response_.content += data; + response_.content += data; } void AbstractRequestHandler::printFile(const QString& path) { - QByteArray data; - QString type; + QByteArray data; + QString type; - if (!app_->readFile(path, data, type)) - { - status(404, "Not Found"); - return; - } + if (!app_->readFile(path, data, type)) { + status(404, "Not Found"); + return; + } - print(data, type); + print(data, type); } void AbstractRequestHandler::sessionInitialize() { - app_->sessionInitialize(this); + app_->sessionInitialize(this); } void AbstractRequestHandler::sessionStart() { - if (app_->sessionStart(this)) - { - QNetworkCookie cookie(C_SID.toUtf8(), session_->id.toUtf8()); - cookie.setPath("/"); - header(HEADER_SET_COOKIE, cookie.toRawForm()); - } + if (app_->sessionStart(this)) { + QNetworkCookie cookie(C_SID.toUtf8(), session_->id.toUtf8()); + cookie.setPath("/"); + header(HEADER_SET_COOKIE, cookie.toRawForm()); + } } void AbstractRequestHandler::sessionEnd() { - if (sessionActive()) - { - QNetworkCookie cookie(C_SID.toUtf8(), session_->id.toUtf8()); - cookie.setPath("/"); - cookie.setExpirationDate(QDateTime::currentDateTime()); + if (sessionActive()) { + QNetworkCookie cookie(C_SID.toUtf8(), session_->id.toUtf8()); + cookie.setPath("/"); + cookie.setExpirationDate(QDateTime::currentDateTime()); - if (app_->sessionEnd(this)) - { - header(HEADER_SET_COOKIE, cookie.toRawForm()); + if (app_->sessionEnd(this)) + header(HEADER_SET_COOKIE, cookie.toRawForm()); } - } } bool AbstractRequestHandler::isBanned() const { - return app_->isBanned(this); + return app_->isBanned(this); } int AbstractRequestHandler::failedAttempts() const { - return app_->failedAttempts(this); + return app_->failedAttempts(this); } void AbstractRequestHandler::resetFailedAttempts() { - app_->resetFailedAttempts(this); + app_->resetFailedAttempts(this); } void AbstractRequestHandler::increaseFailedAttempts() { - app_->increaseFailedAttempts(this); + app_->increaseFailedAttempts(this); } QString AbstractRequestHandler::saveTmpFile(const QByteArray &data) { - QTemporaryFile tmpfile(QDir::temp().absoluteFilePath("qBT-XXXXXX.torrent")); - tmpfile.setAutoRemove(false); - if (tmpfile.open()) - { - tmpfile.write(data); - tmpfile.close(); - return tmpfile.fileName(); - } + QTemporaryFile tmpfile(QDir::temp().absoluteFilePath("qBT-XXXXXX.torrent")); + tmpfile.setAutoRemove(false); + if (tmpfile.open()) { + tmpfile.write(data); + tmpfile.close(); + return tmpfile.fileName(); + } - qWarning() << "I/O Error: Could not create temporary file"; - return QString(); + qWarning() << "I/O Error: Could not create temporary file"; + return QString(); } From ba40408c8d2368a0559f4bb5d66f675f978807c1 Mon Sep 17 00:00:00 2001 From: buinsky Date: Sun, 7 Dec 2014 23:50:06 +0300 Subject: [PATCH 02/13] Images cache control code edit --- src/webui/abstractrequesthandler.cpp | 3 --- src/webui/requesthandler.cpp | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/webui/abstractrequesthandler.cpp b/src/webui/abstractrequesthandler.cpp index 1eec6cdd8..6d6fa1c8b 100644 --- a/src/webui/abstractrequesthandler.cpp +++ b/src/webui/abstractrequesthandler.cpp @@ -92,9 +92,6 @@ void AbstractRequestHandler::print_impl(const QByteArray& data, const QString& t if (!response_.headers.contains(HEADER_CONTENT_TYPE)) response_.headers[HEADER_CONTENT_TYPE] = type; - if (type.indexOf("image") > -1) - response_.headers[HEADER_CACHE_CONTROL] = "max-age=3000000"; - response_.content += data; } diff --git a/src/webui/requesthandler.cpp b/src/webui/requesthandler.cpp index 092bd11e3..3b56c6daf 100644 --- a/src/webui/requesthandler.cpp +++ b/src/webui/requesthandler.cpp @@ -62,6 +62,7 @@ const QString SCOPE_THEME = "theme"; const QString DEFAULT_ACTION = "index"; const QString WEBUI_ACTION = "webui"; const QString VERSION_INFO = "version"; +const QString MAX_AGE_MONTH = "public, max-age=2592000"; #define ADD_ACTION(scope, action) actions[#scope][#action] = &RequestHandler::action_##scope##_##action @@ -178,12 +179,14 @@ void RequestHandler::action_public_theme() qDebug() << Q_FUNC_INFO << "There icon:" << url; printFile(url); + header(HEADER_CACHE_CONTROL, MAX_AGE_MONTH); } void RequestHandler::action_public_images() { const QString path = ":/Icons/" + args_.join("/"); printFile(path); + header(HEADER_CACHE_CONTROL, MAX_AGE_MONTH); } // GET params: From 69506ec50512162bb400fd4b4355f555200850a4 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 00:14:55 +0300 Subject: [PATCH 03/13] Follow project coding style. Issue #2192. --- src/webui/www/private/index.html | 226 +++++++++++++++---------------- 1 file changed, 113 insertions(+), 113 deletions(-) diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html index 7bb4d6d26..a906886f3 100644 --- a/src/webui/www/private/index.html +++ b/src/webui/www/private/index.html @@ -1,120 +1,120 @@ - - - qBittorrent web User Interface - - - - - - - - - - - - - - - - - + + + qBittorrent web User Interface + + + + + + + + + + + + + + + + + - - -
-
- - - -
-
-
+ + +
+
+ + + +
+
+
From 28fad54cc44b3e6f515693e1c415f093448f3d04 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 00:32:39 +0300 Subject: [PATCH 04/13] Add higest and lowest priority icons into toolbar --- src/webui/www/private/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html index a906886f3..de85d90f6 100644 --- a/src/webui/www/private/index.html +++ b/src/webui/www/private/index.html @@ -83,8 +83,10 @@ _(Resume) _(Pause) - _(Decrease priority) + _(Move to bottom) + _(Decrease priority) _(Increase priority) + _(Move to top) _(Options) From 57a4f3ed192edfbbaa2d5dd90a5bc3d8dcea3c61 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 00:46:07 +0300 Subject: [PATCH 05/13] Hide priority menu items when queueing is disabled --- src/webui/www/private/index.html | 15 ++++++++------- src/webui/www/public/scripts/client.js | 2 ++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html index de85d90f6..631cbddf2 100644 --- a/src/webui/www/private/index.html +++ b/src/webui/www/private/index.html @@ -98,13 +98,14 @@
  • _(Resume) _(Resume)
  • _(Pause) _(Pause)
  • _(Delete) _(Delete)
  • -
  • _(Priority) - +
  • + _(Priority) +
  • _(Limit download rate...) _(Limit download rate...)
  • _(Limit upload rate...) _(Limit upload rate...)
  • diff --git a/src/webui/www/public/scripts/client.js b/src/webui/www/public/scripts/client.js index 07b842486..0d13ab518 100644 --- a/src/webui/www/public/scripts/client.js +++ b/src/webui/www/public/scripts/client.js @@ -213,9 +213,11 @@ window.addEvent('load', function () { }); if (queueing_enabled) { $('queueingButtons').removeClass('invisible'); + $('queueingMenuItems').removeClass('invisible'); myTable.showPriority(); } else { $('queueingButtons').addClass('invisible'); + $('queueingMenuItems').addClass('invisible'); myTable.hidePriority(); } From e8ad465c5f0189555074be821e54c3f2adb76da9 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 00:52:29 +0300 Subject: [PATCH 06/13] Follow project coding style. Issue #2192. --- src/webui/www/public/scripts/mocha-init.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/webui/www/public/scripts/mocha-init.js b/src/webui/www/public/scripts/mocha-init.js index 25ef028c8..ea9fba72a 100644 --- a/src/webui/www/public/scripts/mocha-init.js +++ b/src/webui/www/public/scripts/mocha-init.js @@ -1,11 +1,11 @@ /* ----------------------------------------------------------------- - ATTACH MOCHA LINK EVENTS - Notes: Here is where you define your windows and the events that open them. - If you are not using links to run Mocha methods you can remove this function. + ATTACH MOCHA LINK EVENTS + Notes: Here is where you define your windows and the events that open them. + If you are not using links to run Mocha methods you can remove this function. - If you need to add link events to links within windows you are creating, do - it in the onContentLoaded function of the new window. + If you need to add link events to links within windows you are creating, do + it in the onContentLoaded function of the new window. ----------------------------------------------------------------- */ /* Define localStorage object for older browsers */ @@ -164,10 +164,10 @@ initializeWindows = function() { deleteFN = function() { var h = myTable.selectedIds(); /*if(h.length && confirm('_(Are you sure you want to delete the selected torrents from the transfer list?)')) { - h.each(function(item, index){ - new Request({url: 'command/delete', method: 'post', data: {hash: item}}).send(); - }); - }*/ + h.each(function(item, index){ + new Request({url: 'command/delete', method: 'post', data: {hash: item}}).send(); + }); + }*/ if (h.length) { new MochaUI.Window({ id: 'confirmDeletionPage', From b4f39add085e64271ea7939b366d4f12241f7cf5 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 02:15:31 +0300 Subject: [PATCH 07/13] Update torrent list after operations with torrents. Immediately update torrent list after some operations with torrents. Such as changing priority, adding torrent, pause/resume, etc. --- src/webui/www/public/scripts/client.js | 226 ++++++++++----------- src/webui/www/public/scripts/mocha-init.js | 7 + 2 files changed, 120 insertions(+), 113 deletions(-) diff --git a/src/webui/www/public/scripts/client.js b/src/webui/www/public/scripts/client.js index 0d13ab518..6495df18b 100644 --- a/src/webui/www/public/scripts/client.js +++ b/src/webui/www/public/scripts/client.js @@ -24,6 +24,119 @@ myTable = new dynamicTable(); +var stateToImg = function (state) { + if (state == "pausedUP" || state == "pausedDL") { + state = "paused"; + } else { + if (state == "queuedUP" || state == "queuedDL") { + state = "queued"; + } else { + if (state == "checkingUP" || state == "checkingDL") { + state = "checking"; + } + } + } + return 'images/skin/' + state + '.png'; +}; + +var loadTorrentsInfoTimer; +var loadTorrentsInfo = function () { + var queueing_enabled = false; + var url = new URI('json/torrents'); + url.setData('filter', filter); + url.setData('sort', myTable.table.sortedColumn); + url.setData('reverse', myTable.table.reverseSort); + var request = new Request.JSON({ + url : url, + noCache : true, + method : 'get', + onFailure : function () { + $('error_div').set('html', '_(qBittorrent client is not reachable)'); + loadTorrentsInfoTimer = loadTorrentsInfo.delay(2000); + }, + onSuccess : function (events) { + $('error_div').set('html', ''); + if (events) { + // Add new torrents or update them + torrent_hashes = myTable.getRowIds(); + events_hashes = new Array(); + pos = 0; + events.each(function (event) { + events_hashes[events_hashes.length] = event.hash; + var row = new Array(); + var data = new Array(); + row.length = 10; + row[0] = stateToImg(event.state); + row[1] = event.name; + row[2] = event.priority > -1 ? event.priority : null; + data[2] = event.priority; + row[3] = friendlyUnit(event.size, false); + data[3] = event.size; + row[4] = (event.progress * 100).round(1); + if (row[4] == 100.0 && event.progress != 1.0) + row[4] = 99.9; + data[4] = event.progress; + row[5] = event.num_seeds; + if (event.num_complete != -1) + row[5] += " (" + event.num_complete + ")"; + data[5] = event.num_seeds; + row[6] = event.num_leechs; + if (event.num_incomplete != -1) + row[6] += " (" + event.num_incomplete + ")"; + data[6] = event.num_leechs; + row[7] = friendlyUnit(event.dlspeed, true); + data[7] = event.dlspeed; + row[8] = friendlyUnit(event.upspeed, true); + data[8] = event.upspeed; + row[9] = friendlyDuration(event.eta); + data[9] = event.eta; + if (event.ratio == -1) + row[10] = "∞"; + else + row[10] = (Math.floor(100 * event.ratio) / 100).toFixed(2); //Don't round up + data[10] = event.ratio; + if (row[2] != null) + queueing_enabled = true; + if (!torrent_hashes.contains(event.hash)) { + // New unfinished torrent + torrent_hashes[torrent_hashes.length] = event.hash; + //alert("Inserting row"); + myTable.insertRow(event.hash, row, data, event.state, pos); + } else { + // Update torrent data + myTable.updateRow(event.hash, row, data, event.state, pos); + } + + pos++; + }); + // Remove deleted torrents + torrent_hashes.each(function (hash) { + if (!events_hashes.contains(hash)) { + myTable.removeRow(hash); + } + }); + if (queueing_enabled) { + $('queueingButtons').removeClass('invisible'); + $('queueingMenuItems').removeClass('invisible'); + myTable.showPriority(); + } else { + $('queueingButtons').addClass('invisible'); + $('queueingMenuItems').addClass('invisible'); + myTable.hidePriority(); + } + + myTable.altRow(); + } + loadTorrentsInfoTimer = loadTorrentsInfo.delay(1500); + } + }).send(); +}; + +var updateTransferList = function() { + clearTimeout(loadTorrentsInfoTimer); + loadTorrentsInfoTimer = loadTorrentsInfo(); +} + window.addEvent('load', function () { var saveColumnSizes = function () { @@ -80,21 +193,6 @@ window.addEvent('load', function () { if (!speedInTitle) $('speedInBrowserTitleBarLink').firstChild.style.opacity = '0'; - var stateToImg = function (state) { - if (state == "pausedUP" || state == "pausedDL") { - state = "paused"; - } else { - if (state == "queuedUP" || state == "queuedDL") { - state = "queued"; - } else { - if (state == "checkingUP" || state == "checkingDL") { - state = "checking"; - } - } - } - return 'images/skin/' + state + '.png'; - }; - var loadTransferInfoTimer; var loadTransferInfo = function () { var url = 'json/transferInfo'; @@ -135,104 +233,6 @@ window.addEvent('load', function () { $('DlInfos').addEvent('click', globalDownloadLimitFN); $('UpInfos').addEvent('click', globalUploadLimitFN); - var ajaxfnTimer; - var ajaxfn = function () { - var queueing_enabled = false; - var url = new URI('json/torrents'); - url.setData('filter', filter); - url.setData('sort', myTable.table.sortedColumn); - url.setData('reverse', myTable.table.reverseSort); - var request = new Request.JSON({ - url : url, - noCache : true, - method : 'get', - onFailure : function () { - $('error_div').set('html', '_(qBittorrent client is not reachable)'); - ajaxfnTimer = ajaxfn.delay(2000); - }, - onSuccess : function (events) { - $('error_div').set('html', ''); - if (events) { - // Add new torrents or update them - torrent_hashes = myTable.getRowIds(); - events_hashes = new Array(); - pos = 0; - events.each(function (event) { - events_hashes[events_hashes.length] = event.hash; - var row = new Array(); - var data = new Array(); - row.length = 10; - row[0] = stateToImg(event.state); - row[1] = event.name; - row[2] = event.priority > -1 ? event.priority : null; - data[2] = event.priority; - row[3] = friendlyUnit(event.size, false); - data[3] = event.size; - row[4] = (event.progress * 100).round(1); - if (row[4] == 100.0 && event.progress != 1.0) - row[4] = 99.9; - data[4] = event.progress; - row[5] = event.num_seeds; - if (event.num_complete != -1) - row[5] += " (" + event.num_complete + ")"; - data[5] = event.num_seeds; - row[6] = event.num_leechs; - if (event.num_incomplete != -1) - row[6] += " (" + event.num_incomplete + ")"; - data[6] = event.num_leechs; - row[7] = friendlyUnit(event.dlspeed, true); - data[7] = event.dlspeed; - row[8] = friendlyUnit(event.upspeed, true); - data[8] = event.upspeed; - row[9] = friendlyDuration(event.eta); - data[9] = event.eta; - if (event.ratio == -1) - row[10] = "∞"; - else - row[10] = (Math.floor(100 * event.ratio) / 100).toFixed(2); //Don't round up - data[10] = event.ratio; - if (row[2] != null) - queueing_enabled = true; - if (!torrent_hashes.contains(event.hash)) { - // New unfinished torrent - torrent_hashes[torrent_hashes.length] = event.hash; - //alert("Inserting row"); - myTable.insertRow(event.hash, row, data, event.state, pos); - } else { - // Update torrent data - myTable.updateRow(event.hash, row, data, event.state, pos); - } - - pos++; - }); - // Remove deleted torrents - torrent_hashes.each(function (hash) { - if (!events_hashes.contains(hash)) { - myTable.removeRow(hash); - } - }); - if (queueing_enabled) { - $('queueingButtons').removeClass('invisible'); - $('queueingMenuItems').removeClass('invisible'); - myTable.showPriority(); - } else { - $('queueingButtons').addClass('invisible'); - $('queueingMenuItems').addClass('invisible'); - myTable.hidePriority(); - } - - myTable.altRow(); - } - ajaxfnTimer = ajaxfn.delay(1500); - } - }).send(); - }; - - var updateTransferList = function() { - clearTimeout(ajaxfnTimer); - ajaxfnTimer = ajaxfn(); - } - setSortedColumn = function (column) { myTable.setSortedColumn(column); updateTransferList(); diff --git a/src/webui/www/public/scripts/mocha-init.js b/src/webui/www/public/scripts/mocha-init.js index ea9fba72a..5d6676a51 100644 --- a/src/webui/www/public/scripts/mocha-init.js +++ b/src/webui/www/public/scripts/mocha-init.js @@ -48,6 +48,7 @@ initializeWindows = function() { width: 500, height: 300 }); + updateTransferList(); }); addClickEvent('preferences', function(e) { @@ -87,6 +88,7 @@ initializeWindows = function() { width: 600, height: 130 }); + updateTransferList(); }); globalUploadLimitFN = function() { @@ -181,6 +183,7 @@ initializeWindows = function() { width: 424, height: 140 }); + updateTransferList(); } }; @@ -201,6 +204,7 @@ initializeWindows = function() { } }).send(); }); + updateTransferList(); } }; @@ -216,6 +220,7 @@ initializeWindows = function() { } }).send(); }); + updateTransferList(); } }; @@ -248,6 +253,7 @@ initializeWindows = function() { } }).send(); }); + updateTransferList(); } }); @@ -276,6 +282,7 @@ initializeWindows = function() { hashes: h.join("|") } }).send(); + updateTransferList(); } } From 5b604ac2511019f79723d77705b0ebcf2a829375 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 03:03:53 +0300 Subject: [PATCH 08/13] Save torrent list sort order in local storage --- src/webui/www/public/scripts/dynamicTable.js | 10 ++++++---- src/webui/www/public/scripts/mocha-init.js | 7 +++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/webui/www/public/scripts/dynamicTable.js b/src/webui/www/public/scripts/dynamicTable.js index b1687b04f..4e032b362 100644 --- a/src/webui/www/public/scripts/dynamicTable.js +++ b/src/webui/www/public/scripts/dynamicTable.js @@ -42,18 +42,20 @@ var dynamicTable = new Class({ this.priority_hidden = false; this.progressIndex = progressIndex; this.context_menu = context_menu; - this.table.sortedColumn = 'name'; // Default is NAME - this.table.reverseSort = false; + this.table.sortedColumn = getLocalStorageItem('sorted_column', 'name'); + this.table.reverseSort = getLocalStorageItem('reverse_sort', 'false');; }, setSortedColumn : function (column) { if (column != this.table.sortedColumn) { this.table.sortedColumn = column; - this.table.reverseSort = false; + this.table.reverseSort = 'false'; } else { // Toggle sort order - this.table.reverseSort = !this.table.reverseSort; + this.table.reverseSort = this.table.reverseSort == 'true' ? 'false' : 'true'; } + localStorage.setItem('sorted_column', column); + localStorage.setItem('reverse_sort', this.table.reverseSort); }, getCurrentTorrentHash : function () { diff --git a/src/webui/www/public/scripts/mocha-init.js b/src/webui/www/public/scripts/mocha-init.js index 5d6676a51..651bf19eb 100644 --- a/src/webui/www/public/scripts/mocha-init.js +++ b/src/webui/www/public/scripts/mocha-init.js @@ -22,6 +22,13 @@ if (typeof localStorage == 'undefined') { } } +function getLocalStorageItem(name, defaultVal) { + val = localStorage.getItem(name); + if (val === null || val === undefined) + val = defaultVal; + return val; +} + initializeWindows = function() { function addClickEvent(el, fn) { From 44992056cf96b572140272034b270083a0fec5c8 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 04:31:04 +0300 Subject: [PATCH 09/13] Restore selected filter on page load --- src/webui/www/public/filters.html | 11 +------- src/webui/www/public/scripts/client.js | 38 +++++++++++++++----------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/webui/www/public/filters.html b/src/webui/www/public/filters.html index c18cae28a..6e220a9de 100644 --- a/src/webui/www/public/filters.html +++ b/src/webui/www/public/filters.html @@ -5,13 +5,4 @@
  • _(Paused)
  • _(Active)
  • _(Inactive)
  • - - - + \ No newline at end of file diff --git a/src/webui/www/public/scripts/client.js b/src/webui/www/public/scripts/client.js index 6495df18b..9a4f7b9ba 100644 --- a/src/webui/www/public/scripts/client.js +++ b/src/webui/www/public/scripts/client.js @@ -39,6 +39,8 @@ var stateToImg = function (state) { return 'images/skin/' + state + '.png'; }; +filter = getLocalStorageItem('selected_filter', 'all'); + var loadTorrentsInfoTimer; var loadTorrentsInfo = function () { var queueing_enabled = false; @@ -172,6 +174,23 @@ window.addEvent('load', function () { resizeLimit : [100, 300] }); MochaUI.Desktop.setDesktopSize(); + + setFilter = function (f) { + // Visually Select the right filter + $("all_filter").removeClass("selectedFilter"); + $("downloading_filter").removeClass("selectedFilter"); + $("completed_filter").removeClass("selectedFilter"); + $("paused_filter").removeClass("selectedFilter"); + $("active_filter").removeClass("selectedFilter"); + $("inactive_filter").removeClass("selectedFilter"); + $(f + "_filter").addClass("selectedFilter"); + filter = f; + localStorage.setItem('selected_filter', f); + // Reload torrents + if (typeof myTable.table != 'undefined') + updateTransferList(); + } + new MochaUI.Panel({ id : 'Filters', title : 'Panel', @@ -184,6 +203,9 @@ window.addEvent('load', function () { }, loadMethod : 'xhr', contentURL : 'filters.html', + onContentLoaded : function () { + setFilter(filter); + }, column : 'filtersColumn', height : 300 }); @@ -290,22 +312,6 @@ window.addEvent('load', function () { column : 'mainColumn', height : prop_h }); - - setFilter = function (f) { - // Visually Select the right filter - $("all_filter").removeClass("selectedFilter"); - $("downloading_filter").removeClass("selectedFilter"); - $("completed_filter").removeClass("selectedFilter"); - $("paused_filter").removeClass("selectedFilter"); - $("active_filter").removeClass("selectedFilter"); - $("inactive_filter").removeClass("selectedFilter"); - $(f + "_filter").addClass("selectedFilter"); - filter = f; - localStorage.setItem('selected_filter', f); - // Reload torrents - updateTransferList(); - } - }); function closeWindows() { From 664479145881363cb64c352e3f61c6a6ab08b2b7 Mon Sep 17 00:00:00 2001 From: buinsky Date: Mon, 8 Dec 2014 04:40:58 +0300 Subject: [PATCH 10/13] Follow project coding style. Issue #2192. --- src/qtlibtorrent/qtorrenthandle.cpp | 853 +++++++------- src/qtlibtorrent/qtorrenthandle.h | 158 +-- src/transferlistwidget.cpp | 1598 ++++++++++++++------------- src/transferlistwidget.h | 115 +- src/webui/btjson.cpp | 25 +- src/webui/www/public/filters.html | 16 +- 6 files changed, 1426 insertions(+), 1339 deletions(-) diff --git a/src/qtlibtorrent/qtorrenthandle.cpp b/src/qtlibtorrent/qtorrenthandle.cpp index e81d0fa99..62b03ce5c 100644 --- a/src/qtlibtorrent/qtorrenthandle.cpp +++ b/src/qtlibtorrent/qtorrenthandle.cpp @@ -56,358 +56,395 @@ using namespace std; static QPair get_file_extremity_pieces(const torrent_info& t, int file_index) { - const int num_pieces = t.num_pieces(); - const int piece_size = t.piece_length(); - const file_entry& file = t.file_at(file_index); + const int num_pieces = t.num_pieces(); + const int piece_size = t.piece_length(); + const file_entry& file = t.file_at(file_index); - // Determine the first and last piece of the file - int first_piece = floor((file.offset + 1) / (float) piece_size); - Q_ASSERT(first_piece >= 0 && first_piece < num_pieces); - qDebug("First piece of the file is %d/%d", first_piece, num_pieces - 1); + // Determine the first and last piece of the file + int first_piece = floor((file.offset + 1) / (float) piece_size); + Q_ASSERT(first_piece >= 0 && first_piece < num_pieces); + qDebug("First piece of the file is %d/%d", first_piece, num_pieces - 1); - int num_pieces_in_file = ceil(file.size / (float) piece_size); - int last_piece = first_piece + num_pieces_in_file - 1; - Q_ASSERT(last_piece >= 0 && last_piece < num_pieces); - qDebug("last piece of the file is %d/%d", last_piece, num_pieces - 1); + int num_pieces_in_file = ceil(file.size / (float) piece_size); + int last_piece = first_piece + num_pieces_in_file - 1; + Q_ASSERT(last_piece >= 0 && last_piece < num_pieces); + qDebug("last piece of the file is %d/%d", last_piece, num_pieces - 1); - return qMakePair(first_piece, last_piece); + return qMakePair(first_piece, last_piece); } -QTorrentHandle::QTorrentHandle(const torrent_handle& h): torrent_handle(h) {} +QTorrentHandle::QTorrentHandle(const torrent_handle& h): torrent_handle(h) +{ +} // // Getters // -QString QTorrentHandle::hash() const { - return misc::toQString(torrent_handle::info_hash()); +QString QTorrentHandle::hash() const +{ + return misc::toQString(torrent_handle::info_hash()); } -QString QTorrentHandle::name() const { - QString name = TorrentPersistentData::getName(hash()); - if (name.isEmpty()) { +QString QTorrentHandle::name() const +{ + QString name = TorrentPersistentData::getName(hash()); + if (name.isEmpty()) { #if LIBTORRENT_VERSION_NUM < 10000 - name = misc::toQStringU(torrent_handle::name()); + name = misc::toQStringU(torrent_handle::name()); #else - name = misc::toQStringU(status(query_name).name); + name = misc::toQStringU(status(query_name).name); #endif - } - return name; + } + return name; } -QString QTorrentHandle::creation_date() const { +QString QTorrentHandle::creation_date() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - boost::optional t = torrent_handle::get_torrent_info().creation_date(); + boost::optional t = torrent_handle::get_torrent_info().creation_date(); #else - boost::optional t = torrent_handle::torrent_file()->creation_date(); + boost::optional t = torrent_handle::torrent_file()->creation_date(); #endif - return t ? misc::toQString(*t) : ""; + return t ? misc::toQString(*t) : ""; } -qlonglong QTorrentHandle::creation_date_unix() const { +qlonglong QTorrentHandle::creation_date_unix() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - boost::optional t = torrent_handle::get_torrent_info().creation_date(); + boost::optional t = torrent_handle::get_torrent_info().creation_date(); #else - boost::optional t = torrent_handle::torrent_file()->creation_date(); + boost::optional t = torrent_handle::torrent_file()->creation_date(); #endif - return t ? *t : -1; + return t ? *t : -1; } -QString QTorrentHandle::current_tracker() const { - return misc::toQString(status(0x0).current_tracker); +QString QTorrentHandle::current_tracker() const +{ + return misc::toQString(status(0x0).current_tracker); } -bool QTorrentHandle::is_paused() const { - return is_paused(status(0x0)); +bool QTorrentHandle::is_paused() const +{ + return is_paused(status(0x0)); } -bool QTorrentHandle::is_queued() const { - return is_queued(status(0x0)); +bool QTorrentHandle::is_queued() const +{ + return is_queued(status(0x0)); } -size_type QTorrentHandle::total_size() const { +size_type QTorrentHandle::total_size() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return torrent_handle::get_torrent_info().total_size(); + return torrent_handle::get_torrent_info().total_size(); #else - return torrent_handle::torrent_file()->total_size(); + return torrent_handle::torrent_file()->total_size(); #endif } -size_type QTorrentHandle::piece_length() const { +size_type QTorrentHandle::piece_length() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return torrent_handle::get_torrent_info().piece_length(); + return torrent_handle::get_torrent_info().piece_length(); #else - return torrent_handle::torrent_file()->piece_length(); + return torrent_handle::torrent_file()->piece_length(); #endif } -int QTorrentHandle::num_pieces() const { +int QTorrentHandle::num_pieces() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return torrent_handle::get_torrent_info().num_pieces(); + return torrent_handle::get_torrent_info().num_pieces(); #else - return torrent_handle::torrent_file()->num_pieces(); + return torrent_handle::torrent_file()->num_pieces(); #endif } -bool QTorrentHandle::first_last_piece_first() const { +bool QTorrentHandle::first_last_piece_first() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - torrent_info const* t = &get_torrent_info(); + torrent_info const* t = &get_torrent_info(); #else - boost::intrusive_ptr t = torrent_file(); + boost::intrusive_ptr t = torrent_file(); #endif - // Get int first media file - int index = 0; - for (index = 0; index < t->num_files(); ++index) { - QString path = misc::toQStringU(t->file_at(index).path); - const QString ext = fsutils::fileExtension(path); - if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) - break; - } + // Get int first media file + int index = 0; + for (index = 0; index < t->num_files(); ++index) { + QString path = misc::toQStringU(t->file_at(index).path); + const QString ext = fsutils::fileExtension(path); + if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) + break; + } - if (index >= t->num_files()) // No media file - return false; + if (index >= t->num_files()) // No media file + return false; + QPair extremities = get_file_extremity_pieces(*t, index); - QPair extremities = get_file_extremity_pieces(*t, index); - - return (torrent_handle::piece_priority(extremities.first) == 7) - && (torrent_handle::piece_priority(extremities.second) == 7); + return (torrent_handle::piece_priority(extremities.first) == 7) + && (torrent_handle::piece_priority(extremities.second) == 7); } -QString QTorrentHandle::save_path() const { +QString QTorrentHandle::save_path() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return fsutils::fromNativePath(misc::toQStringU(torrent_handle::save_path())); + return fsutils::fromNativePath(misc::toQStringU(torrent_handle::save_path())); #else - return fsutils::fromNativePath(misc::toQStringU(status(torrent_handle::query_save_path).save_path)); + return fsutils::fromNativePath(misc::toQStringU(status(torrent_handle::query_save_path).save_path)); #endif } -QString QTorrentHandle::save_path_parsed() const { +QString QTorrentHandle::save_path_parsed() const +{ QString p; if (has_metadata() && num_files() == 1) { - p = firstFileSavePath(); - } else { - p = fsutils::fromNativePath(TorrentPersistentData::getSavePath(hash())); - if (p.isEmpty()) - p = save_path(); + p = firstFileSavePath(); + } + else { + p = fsutils::fromNativePath(TorrentPersistentData::getSavePath(hash())); + if (p.isEmpty()) + p = save_path(); } return p; } -QStringList QTorrentHandle::url_seeds() const { - QStringList res; - try { - const std::set existing_seeds = torrent_handle::url_seeds(); +QStringList QTorrentHandle::url_seeds() const +{ + QStringList res; + try { + const std::set existing_seeds = torrent_handle::url_seeds(); - std::set::const_iterator it = existing_seeds.begin(); - std::set::const_iterator itend = existing_seeds.end(); - for ( ; it != itend; ++it) { - qDebug("URL Seed: %s", it->c_str()); - res << misc::toQString(*it); + std::set::const_iterator it = existing_seeds.begin(); + std::set::const_iterator itend = existing_seeds.end(); + for (; it != itend; ++it) { + qDebug("URL Seed: %s", it->c_str()); + res << misc::toQString(*it); + } + } catch(std::exception &e) { + std::cout << "ERROR: Failed to convert the URL seed" << std::endl; } - } catch(std::exception &e) { - std::cout << "ERROR: Failed to convert the URL seed" << std::endl; - } - return res; + return res; } // get the size of the torrent without the filtered files -size_type QTorrentHandle::actual_size() const { - return status(query_accurate_download_counters).total_wanted; +size_type QTorrentHandle::actual_size() const +{ + return status(query_accurate_download_counters).total_wanted; } -bool QTorrentHandle::has_filtered_pieces() const { - const std::vector piece_priorities = torrent_handle::piece_priorities(); - foreach (const int priority, piece_priorities) { - if (priority == 0) - return true; - } - return false; +bool QTorrentHandle::has_filtered_pieces() const +{ + const std::vector piece_priorities = torrent_handle::piece_priorities(); + foreach (const int priority, piece_priorities) + if (priority == 0) + return true; + return false; } -int QTorrentHandle::num_files() const { +int QTorrentHandle::num_files() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return torrent_handle::get_torrent_info().num_files(); + return torrent_handle::get_torrent_info().num_files(); #else - return torrent_handle::torrent_file()->num_files(); + return torrent_handle::torrent_file()->num_files(); #endif } -QString QTorrentHandle::filename_at(unsigned int index) const { +QString QTorrentHandle::filename_at(unsigned int index) const +{ #if LIBTORRENT_VERSION_NUM < 10000 - Q_ASSERT(index < (unsigned int)torrent_handle::get_torrent_info().num_files()); + Q_ASSERT(index < (unsigned int)torrent_handle::get_torrent_info().num_files()); #else - Q_ASSERT(index < (unsigned int)torrent_handle::torrent_file()->num_files()); + Q_ASSERT(index < (unsigned int)torrent_handle::torrent_file()->num_files()); #endif - return fsutils::fileName(filepath_at(index)); + return fsutils::fileName(filepath_at(index)); } -size_type QTorrentHandle::filesize_at(unsigned int index) const { +size_type QTorrentHandle::filesize_at(unsigned int index) const +{ #if LIBTORRENT_VERSION_NUM < 10000 - Q_ASSERT(index < (unsigned int)torrent_handle::get_torrent_info().num_files()); - return torrent_handle::get_torrent_info().files().file_size(index); + Q_ASSERT(index < (unsigned int)torrent_handle::get_torrent_info().num_files()); + return torrent_handle::get_torrent_info().files().file_size(index); #else - Q_ASSERT(index < (unsigned int)torrent_handle::torrent_file()->num_files()); - return torrent_handle::torrent_file()->files().file_size(index); + Q_ASSERT(index < (unsigned int)torrent_handle::torrent_file()->num_files()); + return torrent_handle::torrent_file()->files().file_size(index); #endif } -QString QTorrentHandle::filepath_at(unsigned int index) const { +QString QTorrentHandle::filepath_at(unsigned int index) const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return filepath_at(torrent_handle::get_torrent_info(), index); + return filepath_at(torrent_handle::get_torrent_info(), index); #else - return filepath_at(*torrent_handle::torrent_file(), index); + return filepath_at(*torrent_handle::torrent_file(), index); #endif } -QString QTorrentHandle::orig_filepath_at(unsigned int index) const { +QString QTorrentHandle::orig_filepath_at(unsigned int index) const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return fsutils::fromNativePath(misc::toQStringU(torrent_handle::get_torrent_info().orig_files().file_path(index))); + return fsutils::fromNativePath(misc::toQStringU(torrent_handle::get_torrent_info().orig_files().file_path(index))); #else - return fsutils::fromNativePath(misc::toQStringU(torrent_handle::torrent_file()->orig_files().file_path(index))); + return fsutils::fromNativePath(misc::toQStringU(torrent_handle::torrent_file()->orig_files().file_path(index))); #endif } -torrent_status::state_t QTorrentHandle::state() const { - return status(0x0).state; +torrent_status::state_t QTorrentHandle::state() const +{ + return status(0x0).state; } -QString QTorrentHandle::creator() const { +QString QTorrentHandle::creator() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return misc::toQStringU(torrent_handle::get_torrent_info().creator()); + return misc::toQStringU(torrent_handle::get_torrent_info().creator()); #else - return misc::toQStringU(torrent_handle::torrent_file()->creator()); + return misc::toQStringU(torrent_handle::torrent_file()->creator()); #endif } -QString QTorrentHandle::comment() const { +QString QTorrentHandle::comment() const +{ #if LIBTORRENT_VERSION_NUM < 10000 - return misc::toQStringU(torrent_handle::get_torrent_info().comment()); + return misc::toQStringU(torrent_handle::get_torrent_info().comment()); #else - return misc::toQStringU(torrent_handle::torrent_file()->comment()); + return misc::toQStringU(torrent_handle::torrent_file()->comment()); #endif } -bool QTorrentHandle::is_checking() const { - return is_checking(status(0x0)); +bool QTorrentHandle::is_checking() const +{ + return is_checking(status(0x0)); } // Return a list of absolute paths corresponding // to all files in a torrent -QStringList QTorrentHandle::absolute_files_path() const { - QDir saveDir(save_path()); - QStringList res; - for (int i = 0; i fp = torrent_handle::file_priorities(); - for (uint i = 0; i < fp.size(); ++i) { - if (fp[i] == 0) { - const QString file_path = fsutils::expandPathAbs(saveDir.absoluteFilePath(filepath_at(i))); - if (file_path.contains(".unwanted")) - res << file_path; +QStringList QTorrentHandle::absolute_files_path_uneeded() const +{ + QDir saveDir(save_path()); + QStringList res; + std::vector fp = torrent_handle::file_priorities(); + for (uint i = 0; i < fp.size(); ++i) { + if (fp[i] == 0) { + const QString file_path = fsutils::expandPathAbs(saveDir.absoluteFilePath(filepath_at(i))); + if (file_path.contains(".unwanted")) + res << file_path; + } } - } - return res; + return res; } -bool QTorrentHandle::has_missing_files() const { - const QStringList paths = absolute_files_path(); - foreach (const QString &path, paths) { - if (!QFile::exists(path)) return true; - } - return false; -} - -int QTorrentHandle::queue_position() const { - return queue_position(status(0x0)); -} - -bool QTorrentHandle::is_seed() const { - // Affected by bug http://code.rasterbar.com/libtorrent/ticket/402 - //return torrent_handle::is_seed(); - // May suffer from approximation problems - //return (progress() == 1.); - // This looks safe - return is_seed(status(0x0)); -} - -bool QTorrentHandle::is_sequential_download() const { - return status(0x0).sequential_download; -} - -bool QTorrentHandle::priv() const { - if (!has_metadata()) +bool QTorrentHandle::has_missing_files() const +{ + const QStringList paths = absolute_files_path(); + foreach (const QString &path, paths) + if (!QFile::exists(path)) return true; return false; +} + +int QTorrentHandle::queue_position() const +{ + return queue_position(status(0x0)); +} + +bool QTorrentHandle::is_seed() const +{ + // Affected by bug http://code.rasterbar.com/libtorrent/ticket/402 + //return torrent_handle::is_seed(); + // May suffer from approximation problems + //return (progress() == 1.); + // This looks safe + return is_seed(status(0x0)); +} + +bool QTorrentHandle::is_sequential_download() const +{ + return status(0x0).sequential_download; +} + +bool QTorrentHandle::priv() const +{ + if (!has_metadata()) + return false; #if LIBTORRENT_VERSION_NUM < 10000 - return torrent_handle::get_torrent_info().priv(); + return torrent_handle::get_torrent_info().priv(); #else - return torrent_handle::torrent_file()->priv(); + return torrent_handle::torrent_file()->priv(); #endif } -QString QTorrentHandle::firstFileSavePath() const { - Q_ASSERT(has_metadata()); - QString fsave_path = fsutils::fromNativePath(TorrentPersistentData::getSavePath(hash())); - if (fsave_path.isEmpty()) - fsave_path = save_path(); - if (!fsave_path.endsWith("/")) - fsave_path += "/"; - fsave_path += filepath_at(0); - // Remove .!qB extension - if (fsave_path.endsWith(".!qB", Qt::CaseInsensitive)) - fsave_path.chop(4); - return fsave_path; +QString QTorrentHandle::firstFileSavePath() const +{ + Q_ASSERT(has_metadata()); + QString fsave_path = fsutils::fromNativePath(TorrentPersistentData::getSavePath(hash())); + if (fsave_path.isEmpty()) + fsave_path = save_path(); + if (!fsave_path.endsWith("/")) + fsave_path += "/"; + fsave_path += filepath_at(0); + // Remove .!qB extension + if (fsave_path.endsWith(".!qB", Qt::CaseInsensitive)) + fsave_path.chop(4); + return fsave_path; } QString QTorrentHandle::root_path() const { - if (num_files() < 2) + if (num_files() < 2) + return save_path(); + QString first_filepath = filepath_at(0); + const int slashIndex = first_filepath.indexOf("/"); + if (slashIndex >= 0) + return QDir(save_path()).absoluteFilePath(first_filepath.left(slashIndex)); return save_path(); - QString first_filepath = filepath_at(0); - const int slashIndex = first_filepath.indexOf("/"); - if (slashIndex >= 0) - return QDir(save_path()).absoluteFilePath(first_filepath.left(slashIndex)); - return save_path(); } -bool QTorrentHandle::has_error() const { - return has_error(status(0x0)); +bool QTorrentHandle::has_error() const +{ + return has_error(status(0x0)); } -QString QTorrentHandle::error() const { - return misc::toQString(status(0x0).error); +QString QTorrentHandle::error() const +{ + return misc::toQString(status(0x0).error); } -void QTorrentHandle::downloading_pieces(bitfield &bf) const { - std::vector queue; - torrent_handle::get_download_queue(queue); +void QTorrentHandle::downloading_pieces(bitfield &bf) const +{ + std::vector queue; + torrent_handle::get_download_queue(queue); - std::vector::const_iterator it = queue.begin(); - std::vector::const_iterator itend = queue.end(); - for ( ; it!= itend; ++it) { - bf.set_bit(it->piece_index); - } - return; + std::vector::const_iterator it = queue.begin(); + std::vector::const_iterator itend = queue.end(); + for (; it!= itend; ++it) + bf.set_bit(it->piece_index); + return; } -bool QTorrentHandle::has_metadata() const { - return status(0x0).has_metadata; +bool QTorrentHandle::has_metadata() const +{ + return status(0x0).has_metadata; } -void QTorrentHandle::file_progress(std::vector& fp) const { +void QTorrentHandle::file_progress(std::vector& fp) const +{ torrent_handle::file_progress(fp, torrent_handle::piece_granularity); } -QTorrentState QTorrentHandle::torrentState() const { +QTorrentState QTorrentHandle::torrentState() const +{ QTorrentState state = QTorrentState::Unknown; libtorrent::torrent_status s = status(torrent_handle::query_accurate_download_counters); @@ -456,275 +493,295 @@ qulonglong QTorrentHandle::eta() const // Setters // -void QTorrentHandle::pause() const { - torrent_handle::auto_managed(false); - torrent_handle::pause(); - torrent_handle::save_resume_data(); +void QTorrentHandle::pause() const +{ + torrent_handle::auto_managed(false); + torrent_handle::pause(); + torrent_handle::save_resume_data(); } -void QTorrentHandle::resume() const { - if (has_error()) - torrent_handle::clear_error(); +void QTorrentHandle::resume() const +{ + if (has_error()) + torrent_handle::clear_error(); - const QString torrent_hash = hash(); - bool has_persistant_error = TorrentPersistentData::hasError(torrent_hash); - TorrentPersistentData::setErrorState(torrent_hash, false); - bool temp_path_enabled = Preferences::instance()->isTempPathEnabled(); - if (has_persistant_error && temp_path_enabled) { - // Torrent was supposed to be seeding, checking again in final destination - qDebug("Resuming a torrent with error..."); - const QString final_save_path = TorrentPersistentData::getSavePath(torrent_hash); - qDebug("Torrent final path is: %s", qPrintable(final_save_path)); - if (!final_save_path.isEmpty()) - move_storage(final_save_path); - } - torrent_handle::auto_managed(true); - torrent_handle::resume(); - if (has_persistant_error && temp_path_enabled) { - // Force recheck - torrent_handle::force_recheck(); - } + const QString torrent_hash = hash(); + bool has_persistant_error = TorrentPersistentData::hasError(torrent_hash); + TorrentPersistentData::setErrorState(torrent_hash, false); + bool temp_path_enabled = Preferences::instance()->isTempPathEnabled(); + if (has_persistant_error && temp_path_enabled) { + // Torrent was supposed to be seeding, checking again in final destination + qDebug("Resuming a torrent with error..."); + const QString final_save_path = TorrentPersistentData::getSavePath(torrent_hash); + qDebug("Torrent final path is: %s", qPrintable(final_save_path)); + if (!final_save_path.isEmpty()) + move_storage(final_save_path); + } + torrent_handle::auto_managed(true); + torrent_handle::resume(); + if (has_persistant_error && temp_path_enabled) + // Force recheck + torrent_handle::force_recheck(); } -void QTorrentHandle::remove_url_seed(const QString& seed) const { - torrent_handle::remove_url_seed(seed.toStdString()); +void QTorrentHandle::remove_url_seed(const QString& seed) const +{ + torrent_handle::remove_url_seed(seed.toStdString()); } -void QTorrentHandle::add_url_seed(const QString& seed) const { - const std::string str_seed = seed.toStdString(); - qDebug("calling torrent_handle::add_url_seed(%s)", str_seed.c_str()); - torrent_handle::add_url_seed(str_seed); +void QTorrentHandle::add_url_seed(const QString& seed) const +{ + const std::string str_seed = seed.toStdString(); + qDebug("calling torrent_handle::add_url_seed(%s)", str_seed.c_str()); + torrent_handle::add_url_seed(str_seed); } -void QTorrentHandle::set_tracker_login(const QString& username, const QString& password) const { - torrent_handle::set_tracker_login(std::string(username.toLocal8Bit().constData()), std::string(password.toLocal8Bit().constData())); +void QTorrentHandle::set_tracker_login(const QString& username, const QString& password) const +{ + torrent_handle::set_tracker_login(std::string(username.toLocal8Bit().constData()), std::string(password.toLocal8Bit().constData())); } -void QTorrentHandle::move_storage(const QString& new_path) const { - QString hashstr = hash(); +void QTorrentHandle::move_storage(const QString& new_path) const +{ + QString hashstr = hash(); - if (TorrentTempData::isMoveInProgress(hashstr)) { - qDebug("enqueue move storage to %s", qPrintable(new_path)); - TorrentTempData::enqueueMove(hashstr, new_path); - } - else { - QString old_path = save_path(); + if (TorrentTempData::isMoveInProgress(hashstr)) { + qDebug("enqueue move storage to %s", qPrintable(new_path)); + TorrentTempData::enqueueMove(hashstr, new_path); + } + else { + QString old_path = save_path(); - qDebug("move storage: %s to %s", qPrintable(old_path), qPrintable(new_path)); + qDebug("move storage: %s to %s", qPrintable(old_path), qPrintable(new_path)); - if (QDir(old_path) == QDir(new_path)) - return; + if (QDir(old_path) == QDir(new_path)) + return; - TorrentTempData::startMove(hashstr, old_path, new_path); + TorrentTempData::startMove(hashstr, old_path, new_path); - // Create destination directory if necessary - // or move_storage() will fail... - QDir().mkpath(new_path); - // Actually move the storage - torrent_handle::move_storage(fsutils::toNativePath(new_path).toUtf8().constData()); - } + // Create destination directory if necessary + // or move_storage() will fail... + QDir().mkpath(new_path); + // Actually move the storage + torrent_handle::move_storage(fsutils::toNativePath(new_path).toUtf8().constData()); + } } -bool QTorrentHandle::save_torrent_file(const QString& path) const { - if (!has_metadata()) return false; +bool QTorrentHandle::save_torrent_file(const QString& path) const +{ + if (!has_metadata()) return false; #if LIBTORRENT_VERSION_NUM < 10000 - torrent_info const* t = &get_torrent_info(); + torrent_info const* t = &get_torrent_info(); #else - boost::intrusive_ptr t = torrent_file(); + boost::intrusive_ptr t = torrent_file(); #endif - entry meta = bdecode(t->metadata().get(), - t->metadata().get() + t->metadata_size()); - entry torrent_entry(entry::dictionary_t); - torrent_entry["info"] = meta; - if (!torrent_handle::trackers().empty()) - torrent_entry["announce"] = torrent_handle::trackers().front().url; + entry meta = bdecode(t->metadata().get(), + t->metadata().get() + t->metadata_size()); + entry torrent_entry(entry::dictionary_t); + torrent_entry["info"] = meta; + if (!torrent_handle::trackers().empty()) + torrent_entry["announce"] = torrent_handle::trackers().front().url; - vector out; - bencode(back_inserter(out), torrent_entry); - QFile torrent_file(path); - if (!out.empty() && torrent_file.open(QIODevice::WriteOnly)) { - torrent_file.write(&out[0], out.size()); - torrent_file.close(); - return true; - } + vector out; + bencode(back_inserter(out), torrent_entry); + QFile torrent_file(path); + if (!out.empty() && torrent_file.open(QIODevice::WriteOnly)) { + torrent_file.write(&out[0], out.size()); + torrent_file.close(); + return true; + } - return false; + return false; } -void QTorrentHandle::file_priority(int index, int priority) const { - vector priorities = torrent_handle::file_priorities(); - if (priorities[index] != priority) { - priorities[index] = priority; - prioritize_files(priorities); - } +void QTorrentHandle::file_priority(int index, int priority) const +{ + vector priorities = torrent_handle::file_priorities(); + if (priorities[index] != priority) { + priorities[index] = priority; + prioritize_files(priorities); + } } -void QTorrentHandle::prioritize_files(const vector &files) const { +void QTorrentHandle::prioritize_files(const vector &files) const +{ #if LIBTORRENT_VERSION_NUM < 10000 - torrent_info const& info = torrent_handle::get_torrent_info(); + torrent_info const& info = torrent_handle::get_torrent_info(); #else - boost::intrusive_ptr info_ptr = torrent_handle::torrent_file(); - torrent_info const& info = *info_ptr; + boost::intrusive_ptr info_ptr = torrent_handle::torrent_file(); + torrent_info const& info = *info_ptr; #endif - if ((int)files.size() != info.num_files()) return; - qDebug() << Q_FUNC_INFO; - bool was_seed = is_seed(); - qDebug() << Q_FUNC_INFO << "Changing files priorities..."; - torrent_handle::prioritize_files(files); - qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder and conversely..."; + if ((int)files.size() != info.num_files()) return; + qDebug() << Q_FUNC_INFO; + bool was_seed = is_seed(); + qDebug() << Q_FUNC_INFO << "Changing files priorities..."; + torrent_handle::prioritize_files(files); + qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder and conversely..."; - QString spath = save_path(); + QString spath = save_path(); - for (uint i = 0; i < files.size(); ++i) { - QString filepath = filepath_at(info, i); - // Move unwanted files to a .unwanted subfolder - if (files[i] == 0) { - QString old_abspath = QDir(spath).absoluteFilePath(filepath); - QString parent_abspath = fsutils::branchPath(old_abspath); - // Make sure the file does not already exists - if (QDir(parent_abspath).dirName() != ".unwanted") { - QString unwanted_abspath = parent_abspath+"/.unwanted"; - QString new_abspath = unwanted_abspath+"/"+fsutils::fileName(filepath); - qDebug() << "Unwanted path is" << unwanted_abspath; - if (QFile::exists(new_abspath)) { - qWarning() << "File" << new_abspath << "already exists at destination."; - continue; - } - bool created = QDir().mkpath(unwanted_abspath); + for (uint i = 0; i < files.size(); ++i) { + QString filepath = filepath_at(info, i); + // Move unwanted files to a .unwanted subfolder + if (files[i] == 0) { + QString old_abspath = QDir(spath).absoluteFilePath(filepath); + QString parent_abspath = fsutils::branchPath(old_abspath); + // Make sure the file does not already exists + if (QDir(parent_abspath).dirName() != ".unwanted") { + QString unwanted_abspath = parent_abspath + "/.unwanted"; + QString new_abspath = unwanted_abspath + "/" + fsutils::fileName(filepath); + qDebug() << "Unwanted path is" << unwanted_abspath; + if (QFile::exists(new_abspath)) { + qWarning() << "File" << new_abspath << "already exists at destination."; + continue; + } + bool created = QDir().mkpath(unwanted_abspath); #ifdef Q_OS_WIN - qDebug() << "unwanted folder was created:" << created; - if (created) { - // Hide the folder on Windows - qDebug() << "Hiding folder (Windows)"; - wstring win_path = fsutils::toNativePath(unwanted_abspath).toStdWString(); - DWORD dwAttrs = GetFileAttributesW(win_path.c_str()); - bool ret = SetFileAttributesW(win_path.c_str(), dwAttrs|FILE_ATTRIBUTE_HIDDEN); - Q_ASSERT(ret != 0); Q_UNUSED(ret); - } + qDebug() << "unwanted folder was created:" << created; + if (created) { + // Hide the folder on Windows + qDebug() << "Hiding folder (Windows)"; + wstring win_path = fsutils::toNativePath(unwanted_abspath).toStdWString(); + DWORD dwAttrs = GetFileAttributesW(win_path.c_str()); + bool ret = SetFileAttributesW(win_path.c_str(), dwAttrs | FILE_ATTRIBUTE_HIDDEN); + Q_ASSERT(ret != 0); Q_UNUSED(ret); + } #else - Q_UNUSED(created); + Q_UNUSED(created); #endif - QString parent_path = fsutils::branchPath(filepath); - if (!parent_path.isEmpty() && !parent_path.endsWith("/")) - parent_path += "/"; - rename_file(i, parent_path+".unwanted/"+fsutils::fileName(filepath)); - } + QString parent_path = fsutils::branchPath(filepath); + if (!parent_path.isEmpty() && !parent_path.endsWith("/")) + parent_path += "/"; + rename_file(i, parent_path + ".unwanted/" + fsutils::fileName(filepath)); + } + } + // Move wanted files back to their original folder + if (files[i] > 0) { + QString parent_relpath = fsutils::branchPath(filepath); + if (QDir(parent_relpath).dirName() == ".unwanted") { + QString old_name = fsutils::fileName(filepath); + QString new_relpath = fsutils::branchPath(parent_relpath); + if (new_relpath.isEmpty()) + rename_file(i, old_name); + else + rename_file(i, QDir(new_relpath).filePath(old_name)); + // Remove .unwanted directory if empty + qDebug() << "Attempting to remove .unwanted folder at " << QDir(spath + "/" + new_relpath).absoluteFilePath(".unwanted"); + QDir(spath + "/" + new_relpath).rmdir(".unwanted"); + } + } } - // Move wanted files back to their original folder - if (files[i] > 0) { - QString parent_relpath = fsutils::branchPath(filepath); - if (QDir(parent_relpath).dirName() == ".unwanted") { - QString old_name = fsutils::fileName(filepath); - QString new_relpath = fsutils::branchPath(parent_relpath); - if (new_relpath.isEmpty()) - rename_file(i, old_name); - else - rename_file(i, QDir(new_relpath).filePath(old_name)); - // Remove .unwanted directory if empty - qDebug() << "Attempting to remove .unwanted folder at " << QDir(spath + "/" + new_relpath).absoluteFilePath(".unwanted"); - QDir(spath + "/" + new_relpath).rmdir(".unwanted"); - } - } - } - if (was_seed && !is_seed()) { - qDebug() << "Torrent is no longer SEEDING"; - // Save seed status - TorrentPersistentData::saveSeedStatus(*this); - // Move to temp folder if necessary - const Preferences* const pref = Preferences::instance(); - if (pref->isTempPathEnabled()) { - QString tmp_path = pref->getTempPath(); - qDebug() << "tmp folder is enabled, move torrent to " << tmp_path << " from " << spath; - move_storage(tmp_path); + if (was_seed && !is_seed()) { + qDebug() << "Torrent is no longer SEEDING"; + // Save seed status + TorrentPersistentData::saveSeedStatus(*this); + // Move to temp folder if necessary + const Preferences* const pref = Preferences::instance(); + if (pref->isTempPathEnabled()) { + QString tmp_path = pref->getTempPath(); + qDebug() << "tmp folder is enabled, move torrent to " << tmp_path << " from " << spath; + move_storage(tmp_path); + } } - } } -void QTorrentHandle::prioritize_first_last_piece(int file_index, bool b) const { - // Determine the priority to set - int prio = b ? 7 : torrent_handle::file_priority(file_index); +void QTorrentHandle::prioritize_first_last_piece(int file_index, bool b) const +{ + // Determine the priority to set + int prio = b ? 7 : torrent_handle::file_priority(file_index); #if LIBTORRENT_VERSION_NUM < 10000 - torrent_info const* tf = &get_torrent_info(); + torrent_info const* tf = &get_torrent_info(); #else - boost::intrusive_ptr tf = torrent_file(); + boost::intrusive_ptr tf = torrent_file(); #endif - QPair extremities = get_file_extremity_pieces(*tf, file_index); - piece_priority(extremities.first, prio); - piece_priority(extremities.second, prio); + QPair extremities = get_file_extremity_pieces(*tf, file_index); + piece_priority(extremities.first, prio); + piece_priority(extremities.second, prio); } -void QTorrentHandle::prioritize_first_last_piece(bool b) const { - if (!has_metadata()) return; - // Download first and last pieces first for all media files in the torrent - const uint nbfiles = num_files(); - for (uint index = 0; index < nbfiles; ++index) { - const QString path = filepath_at(index); - const QString ext = fsutils::fileExtension(path); - if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) { - qDebug() << "File" << path << "is previewable, toggle downloading of first/last pieces first"; - prioritize_first_last_piece(index, b); +void QTorrentHandle::prioritize_first_last_piece(bool b) const +{ + if (!has_metadata()) return; + // Download first and last pieces first for all media files in the torrent + const uint nbfiles = num_files(); + for (uint index = 0; index < nbfiles; ++index) { + const QString path = filepath_at(index); + const QString ext = fsutils::fileExtension(path); + if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) { + qDebug() << "File" << path << "is previewable, toggle downloading of first/last pieces first"; + prioritize_first_last_piece(index, b); + } } - } } -void QTorrentHandle::rename_file(int index, const QString& name) const { - qDebug() << Q_FUNC_INFO << index << name; - torrent_handle::rename_file(index, std::string(fsutils::toNativePath(name).toUtf8().constData())); +void QTorrentHandle::rename_file(int index, const QString& name) const +{ + qDebug() << Q_FUNC_INFO << index << name; + torrent_handle::rename_file(index, std::string(fsutils::toNativePath(name).toUtf8().constData())); } // // Operators // -bool QTorrentHandle::operator ==(const QTorrentHandle& new_h) const { - return info_hash() == new_h.info_hash(); +bool QTorrentHandle::operator ==(const QTorrentHandle& new_h) const +{ + return info_hash() == new_h.info_hash(); } -bool QTorrentHandle::is_paused(const libtorrent::torrent_status &status) { - return status.paused && !status.auto_managed; +bool QTorrentHandle::is_paused(const libtorrent::torrent_status &status) +{ + return status.paused && !status.auto_managed; } -int QTorrentHandle::queue_position(const libtorrent::torrent_status &status) { - if (status.queue_position < 0) - return -1; - return status.queue_position+1; +int QTorrentHandle::queue_position(const libtorrent::torrent_status &status) +{ + if (status.queue_position < 0) + return -1; + return status.queue_position + 1; } -bool QTorrentHandle::is_queued(const libtorrent::torrent_status &status) { - return status.paused && status.auto_managed; +bool QTorrentHandle::is_queued(const libtorrent::torrent_status &status) +{ + return status.paused && status.auto_managed; } -bool QTorrentHandle::is_seed(const libtorrent::torrent_status &status) { - return status.state == torrent_status::finished - || status.state == torrent_status::seeding; +bool QTorrentHandle::is_seed(const libtorrent::torrent_status &status) +{ + return status.state == torrent_status::finished + || status.state == torrent_status::seeding; } -bool QTorrentHandle::is_checking(const libtorrent::torrent_status &status) { - return status.state == torrent_status::checking_files - || status.state == torrent_status::checking_resume_data; +bool QTorrentHandle::is_checking(const libtorrent::torrent_status &status) +{ + return status.state == torrent_status::checking_files + || status.state == torrent_status::checking_resume_data; } -bool QTorrentHandle::has_error(const libtorrent::torrent_status &status) { - return status.paused && !status.error.empty(); +bool QTorrentHandle::has_error(const libtorrent::torrent_status &status) +{ + return status.paused && !status.error.empty(); } -float QTorrentHandle::progress(const libtorrent::torrent_status &status) { - if (!status.total_wanted) - return 0.; - if (status.total_wanted_done == status.total_wanted) - return 1.; - float progress = (float) status.total_wanted_done / (float) status.total_wanted; - Q_ASSERT(progress >= 0.f && progress <= 1.f); - return progress; +float QTorrentHandle::progress(const libtorrent::torrent_status &status) +{ + if (!status.total_wanted) + return 0.; + if (status.total_wanted_done == status.total_wanted) + return 1.; + float progress = (float) status.total_wanted_done / (float) status.total_wanted; + Q_ASSERT(progress >= 0.f && progress <= 1.f); + return progress; } -QString QTorrentHandle::filepath_at(const libtorrent::torrent_info &info, unsigned int index) { - return fsutils::fromNativePath(misc::toQStringU(info.files().file_path(index))); +QString QTorrentHandle::filepath_at(const libtorrent::torrent_info &info, unsigned int index) +{ + return fsutils::fromNativePath(misc::toQStringU(info.files().file_path(index))); } diff --git a/src/qtlibtorrent/qtorrenthandle.h b/src/qtlibtorrent/qtorrenthandle.h index 6c25dcc96..a36593ba5 100644 --- a/src/qtlibtorrent/qtorrenthandle.h +++ b/src/qtlibtorrent/qtorrenthandle.h @@ -42,7 +42,8 @@ QT_END_NAMESPACE class QTorrentState { public: - enum { + enum + { Unknown = -1, Error, @@ -71,93 +72,94 @@ private: // A wrapper for torrent_handle in libtorrent // to interact well with Qt types -class QTorrentHandle : public libtorrent::torrent_handle { +class QTorrentHandle: public libtorrent::torrent_handle +{ public: - // - // Constructors - // + // + // Constructors + // - QTorrentHandle() {} - explicit QTorrentHandle(const libtorrent::torrent_handle& h); + QTorrentHandle() {} + explicit QTorrentHandle(const libtorrent::torrent_handle& h); - // - // Getters - // - QString hash() const; - QString name() const; - QString current_tracker() const; - bool is_paused() const; - bool has_filtered_pieces() const; - libtorrent::size_type total_size() const; - libtorrent::size_type piece_length() const; - int num_pieces() const; - QString save_path() const; - QString save_path_parsed() const; - QStringList url_seeds() const; - libtorrent::size_type actual_size() const; - int num_files() const; - int queue_position() const; - bool is_queued() const; - QString filename_at(unsigned int index) const; - libtorrent::size_type filesize_at(unsigned int index) const; - QString filepath_at(unsigned int index) const; - QString orig_filepath_at(unsigned int index) const; - libtorrent::torrent_status::state_t state() const; - QString creator() const; - QString comment() const; - QStringList absolute_files_path() const; - QStringList absolute_files_path_uneeded() const; - bool has_missing_files() const; - bool is_seed() const; - bool is_checking() const; - bool is_sequential_download() const; - QString creation_date() const; - qlonglong creation_date_unix() const; - bool priv() const; - bool first_last_piece_first() const; - QString root_path() const; - QString firstFileSavePath() const; - bool has_error() const; - QString error() const; - void downloading_pieces(libtorrent::bitfield& bf) const; - bool has_metadata() const; - void file_progress(std::vector& fp) const; - QTorrentState torrentState() const; - qulonglong eta() const; + // + // Getters + // + QString hash() const; + QString name() const; + QString current_tracker() const; + bool is_paused() const; + bool has_filtered_pieces() const; + libtorrent::size_type total_size() const; + libtorrent::size_type piece_length() const; + int num_pieces() const; + QString save_path() const; + QString save_path_parsed() const; + QStringList url_seeds() const; + libtorrent::size_type actual_size() const; + int num_files() const; + int queue_position() const; + bool is_queued() const; + QString filename_at(unsigned int index) const; + libtorrent::size_type filesize_at(unsigned int index) const; + QString filepath_at(unsigned int index) const; + QString orig_filepath_at(unsigned int index) const; + libtorrent::torrent_status::state_t state() const; + QString creator() const; + QString comment() const; + QStringList absolute_files_path() const; + QStringList absolute_files_path_uneeded() const; + bool has_missing_files() const; + bool is_seed() const; + bool is_checking() const; + bool is_sequential_download() const; + QString creation_date() const; + qlonglong creation_date_unix() const; + bool priv() const; + bool first_last_piece_first() const; + QString root_path() const; + QString firstFileSavePath() const; + bool has_error() const; + QString error() const; + void downloading_pieces(libtorrent::bitfield& bf) const; + bool has_metadata() const; + void file_progress(std::vector& fp) const; + QTorrentState torrentState() const; + qulonglong eta() const; - // - // Setters - // - void pause() const; - void resume() const; - void remove_url_seed(const QString& seed) const; - void add_url_seed(const QString& seed) const; - void set_tracker_login(const QString& username, const QString& password) const; - void move_storage(const QString& path) const; - void prioritize_first_last_piece(bool b) const; - void rename_file(int index, const QString& name) const; - bool save_torrent_file(const QString& path) const; - void prioritize_files(const std::vector& files) const; - void file_priority(int index, int priority) const; + // + // Setters + // + void pause() const; + void resume() const; + void remove_url_seed(const QString& seed) const; + void add_url_seed(const QString& seed) const; + void set_tracker_login(const QString& username, const QString& password) const; + void move_storage(const QString& path) const; + void prioritize_first_last_piece(bool b) const; + void rename_file(int index, const QString& name) const; + bool save_torrent_file(const QString& path) const; + void prioritize_files(const std::vector& files) const; + void file_priority(int index, int priority) const; - // - // Operators - // - bool operator ==(const QTorrentHandle& new_h) const; + // + // Operators + // + bool operator ==(const QTorrentHandle& new_h) const; - static bool is_paused(const libtorrent::torrent_status &status); - static int queue_position(const libtorrent::torrent_status &status); - static bool is_queued(const libtorrent::torrent_status &status); - static bool is_seed(const libtorrent::torrent_status &status); - static bool is_checking(const libtorrent::torrent_status &status); - static bool has_error(const libtorrent::torrent_status &status); - static float progress(const libtorrent::torrent_status &status); - static QString filepath_at(const libtorrent::torrent_info &info, unsigned int index); + static bool is_paused(const libtorrent::torrent_status &status); + static int queue_position(const libtorrent::torrent_status &status); + static bool is_queued(const libtorrent::torrent_status &status); + static bool is_seed(const libtorrent::torrent_status &status); + static bool is_checking(const libtorrent::torrent_status &status); + static bool has_error(const libtorrent::torrent_status &status); + static float progress(const libtorrent::torrent_status &status); + static QString filepath_at(const libtorrent::torrent_info &info, unsigned int index); private: - void prioritize_first_last_piece(int file_index, bool b) const; + void prioritize_first_last_piece(int file_index, bool b) const; }; diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp index 2b9a09614..382e76359 100644 --- a/src/transferlistwidget.cpp +++ b/src/transferlistwidget.cpp @@ -68,858 +68,884 @@ using namespace libtorrent; TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *main_window, QBtSession *_BTSession): - QTreeView(parent), BTSession(_BTSession), main_window(main_window) { + QTreeView(parent), BTSession(_BTSession), main_window(main_window) +{ - setUniformRowHeights(true); - // Load settings - bool column_loaded = loadSettings(); + setUniformRowHeights(true); + // Load settings + bool column_loaded = loadSettings(); - // Create and apply delegate - listDelegate = new TransferListDelegate(this); - setItemDelegate(listDelegate); + // Create and apply delegate + listDelegate = new TransferListDelegate(this); + setItemDelegate(listDelegate); - // Create transfer list model - listModel = new TorrentModel(this); + // Create transfer list model + listModel = new TorrentModel(this); - nameFilterModel = new TransferListSortModel(); - nameFilterModel->setDynamicSortFilter(true); - nameFilterModel->setSourceModel(listModel); - nameFilterModel->setFilterKeyColumn(TorrentModelItem::TR_NAME); - nameFilterModel->setFilterRole(Qt::DisplayRole); - nameFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive); + nameFilterModel = new TransferListSortModel(); + nameFilterModel->setDynamicSortFilter(true); + nameFilterModel->setSourceModel(listModel); + nameFilterModel->setFilterKeyColumn(TorrentModelItem::TR_NAME); + nameFilterModel->setFilterRole(Qt::DisplayRole); + nameFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive); - setModel(nameFilterModel); + setModel(nameFilterModel); - // Visual settings - setRootIsDecorated(false); - setAllColumnsShowFocus(true); - setSortingEnabled(true); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setItemsExpandable(false); - setAutoScroll(true); - setDragDropMode(QAbstractItemView::DragOnly); + // Visual settings + setRootIsDecorated(false); + setAllColumnsShowFocus(true); + setSortingEnabled(true); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setItemsExpandable(false); + setAutoScroll(true); + setDragDropMode(QAbstractItemView::DragOnly); #if defined(Q_OS_MAC) - setAttribute(Qt::WA_MacShowFocusRect, false); + setAttribute(Qt::WA_MacShowFocusRect, false); #endif - header()->setStretchLastSection(false); + header()->setStretchLastSection(false); - // Default hidden columns - if (!column_loaded) { - setColumnHidden(TorrentModelItem::TR_PRIORITY, true); - setColumnHidden(TorrentModelItem::TR_ADD_DATE, true); - setColumnHidden(TorrentModelItem::TR_SEED_DATE, true); - setColumnHidden(TorrentModelItem::TR_UPLIMIT, true); - setColumnHidden(TorrentModelItem::TR_DLLIMIT, true); - setColumnHidden(TorrentModelItem::TR_TRACKER, true); - setColumnHidden(TorrentModelItem::TR_AMOUNT_DOWNLOADED, true); - setColumnHidden(TorrentModelItem::TR_AMOUNT_UPLOADED, true); - setColumnHidden(TorrentModelItem::TR_AMOUNT_LEFT, true); - setColumnHidden(TorrentModelItem::TR_TIME_ELAPSED, true); - setColumnHidden(TorrentModelItem::TR_SAVE_PATH, true); - setColumnHidden(TorrentModelItem::TR_COMPLETED, true); - setColumnHidden(TorrentModelItem::TR_RATIO_LIMIT, true); - setColumnHidden(TorrentModelItem::TR_SEEN_COMPLETE_DATE, true); - setColumnHidden(TorrentModelItem::TR_LAST_ACTIVITY, true); - setColumnHidden(TorrentModelItem::TR_TOTAL_SIZE, true); - } - - //Ensure that at least one column is visible at all times - bool atLeastOne = false; - for (unsigned int i=0; i