mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-11 07:46:17 -07:00
Add sequential downloading menu items
This commit is contained in:
parent
6644791458
commit
2a712a81ea
12 changed files with 149 additions and 21 deletions
|
@ -489,6 +489,22 @@ qulonglong QTorrentHandle::eta() const
|
||||||
return QBtSession::instance()->getETA(hash(), s);
|
return QBtSession::instance()->getETA(hash(), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QTorrentHandle::toggleSequentialDownload()
|
||||||
|
{
|
||||||
|
if (is_valid() && has_metadata()) {
|
||||||
|
bool was_sequential = is_sequential_download();
|
||||||
|
set_sequential_download(!was_sequential);
|
||||||
|
if (!was_sequential)
|
||||||
|
prioritize_first_last_piece(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QTorrentHandle::toggleFirstLastPiecePrio()
|
||||||
|
{
|
||||||
|
if (is_valid() && has_metadata())
|
||||||
|
prioritize_first_last_piece(!first_last_piece_first());
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setters
|
// Setters
|
||||||
//
|
//
|
||||||
|
|
|
@ -128,6 +128,8 @@ public:
|
||||||
void file_progress(std::vector<libtorrent::size_type>& fp) const;
|
void file_progress(std::vector<libtorrent::size_type>& fp) const;
|
||||||
QTorrentState torrentState() const;
|
QTorrentState torrentState() const;
|
||||||
qulonglong eta() const;
|
qulonglong eta() const;
|
||||||
|
void toggleSequentialDownload();
|
||||||
|
void toggleFirstLastPiecePrio();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setters
|
// Setters
|
||||||
|
|
|
@ -610,12 +610,7 @@ void TransferListWidget::toggleSelectedTorrentsSequentialDownload() const
|
||||||
const QStringList hashes = getSelectedTorrentsHashes();
|
const QStringList hashes = getSelectedTorrentsHashes();
|
||||||
foreach (const QString &hash, hashes) {
|
foreach (const QString &hash, hashes) {
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
if (h.is_valid() && h.has_metadata()) {
|
h.toggleSequentialDownload();
|
||||||
bool was_sequential = h.is_sequential_download();
|
|
||||||
h.set_sequential_download(!was_sequential);
|
|
||||||
if (!was_sequential)
|
|
||||||
h.prioritize_first_last_piece(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,8 +619,7 @@ void TransferListWidget::toggleSelectedFirstLastPiecePrio() const
|
||||||
QStringList hashes = getSelectedTorrentsHashes();
|
QStringList hashes = getSelectedTorrentsHashes();
|
||||||
foreach (const QString &hash, hashes) {
|
foreach (const QString &hash, hashes) {
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
if (h.is_valid() && h.has_metadata())
|
h.toggleFirstLastPiecePrio();
|
||||||
h.prioritize_first_last_piece(!h.first_last_piece_first());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,8 @@ static const char KEY_TORRENT_NUM_INCOMPLETE[] = "num_incomplete";
|
||||||
static const char KEY_TORRENT_RATIO[] = "ratio";
|
static const char KEY_TORRENT_RATIO[] = "ratio";
|
||||||
static const char KEY_TORRENT_ETA[] = "eta";
|
static const char KEY_TORRENT_ETA[] = "eta";
|
||||||
static const char KEY_TORRENT_STATE[] = "state";
|
static const char KEY_TORRENT_STATE[] = "state";
|
||||||
|
static const char KEY_TORRENT_SEQUENTIAL_DOWNLOAD[] = "seq_dl";
|
||||||
|
static const char KEY_TORRENT_FIRST_LAST_PIECE_PRIO[] = "f_l_piece_prio";
|
||||||
|
|
||||||
// Tracker keys
|
// Tracker keys
|
||||||
static const char KEY_TRACKER_URL[] = "url";
|
static const char KEY_TRACKER_URL[] = "url";
|
||||||
|
@ -211,6 +213,12 @@ static QVariantMap toMap(const QTorrentHandle& h)
|
||||||
ret[KEY_TORRENT_RATIO] = (ratio > 100.) ? -1 : ratio;
|
ret[KEY_TORRENT_RATIO] = (ratio > 100.) ? -1 : ratio;
|
||||||
ret[KEY_TORRENT_STATE] = h.torrentState().toString();
|
ret[KEY_TORRENT_STATE] = h.torrentState().toString();
|
||||||
ret[KEY_TORRENT_ETA] = h.eta();
|
ret[KEY_TORRENT_ETA] = h.eta();
|
||||||
|
if (h.has_metadata()) {
|
||||||
|
if (status.sequential_download)
|
||||||
|
ret[KEY_TORRENT_SEQUENTIAL_DOWNLOAD] = true;
|
||||||
|
if (h.first_last_piece_first())
|
||||||
|
ret[KEY_TORRENT_FIRST_LAST_PIECE_PRIO] = true;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,8 @@ QMap<QString, QMap<QString, RequestHandler::Action> > RequestHandler::initialize
|
||||||
ADD_ACTION(command, getTorrentDlLimit);
|
ADD_ACTION(command, getTorrentDlLimit);
|
||||||
ADD_ACTION(command, setTorrentUpLimit);
|
ADD_ACTION(command, setTorrentUpLimit);
|
||||||
ADD_ACTION(command, setTorrentDlLimit);
|
ADD_ACTION(command, setTorrentDlLimit);
|
||||||
|
ADD_ACTION(command, toggleSequentialDownload);
|
||||||
|
ADD_ACTION(command, toggleFirstLastPiecePrio);
|
||||||
ADD_ACTION(command, delete);
|
ADD_ACTION(command, delete);
|
||||||
ADD_ACTION(command, deletePerm);
|
ADD_ACTION(command, deletePerm);
|
||||||
ADD_ACTION(command, increasePrio);
|
ADD_ACTION(command, increasePrio);
|
||||||
|
@ -426,6 +428,30 @@ void RequestHandler::action_command_setTorrentDlLimit()
|
||||||
h.set_download_limit(limit);
|
h.set_download_limit(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestHandler::action_command_toggleSequentialDownload()
|
||||||
|
{
|
||||||
|
QStringList hashes = request().posts["hashes"].split("|");
|
||||||
|
foreach (const QString &hash, hashes) {
|
||||||
|
try {
|
||||||
|
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
|
||||||
|
h.toggleSequentialDownload();
|
||||||
|
}
|
||||||
|
catch(invalid_handle&) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestHandler::action_command_toggleFirstLastPiecePrio()
|
||||||
|
{
|
||||||
|
QStringList hashes = request().posts["hashes"].split("|");
|
||||||
|
foreach (const QString &hash, hashes) {
|
||||||
|
try {
|
||||||
|
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
|
||||||
|
h.toggleFirstLastPiecePrio();
|
||||||
|
}
|
||||||
|
catch(invalid_handle&) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RequestHandler::action_command_delete()
|
void RequestHandler::action_command_delete()
|
||||||
{
|
{
|
||||||
QStringList hashes = request().posts["hashes"].split("|");
|
QStringList hashes = request().posts["hashes"].split("|");
|
||||||
|
|
|
@ -74,6 +74,8 @@ private:
|
||||||
void action_command_getTorrentDlLimit();
|
void action_command_getTorrentDlLimit();
|
||||||
void action_command_setTorrentUpLimit();
|
void action_command_setTorrentUpLimit();
|
||||||
void action_command_setTorrentDlLimit();
|
void action_command_setTorrentDlLimit();
|
||||||
|
void action_command_toggleSequentialDownload();
|
||||||
|
void action_command_toggleFirstLastPiecePrio();
|
||||||
void action_command_delete();
|
void action_command_delete();
|
||||||
void action_command_deletePerm();
|
void action_command_deletePerm();
|
||||||
void action_command_increasePrio();
|
void action_command_increasePrio();
|
||||||
|
|
|
@ -109,6 +109,8 @@
|
||||||
</li>
|
</li>
|
||||||
<li class="separator"><a href="#DownloadLimit"><img src="images/skin/download.png" alt="_(Limit download rate...)"/> _(Limit download rate...)</a></li>
|
<li class="separator"><a href="#DownloadLimit"><img src="images/skin/download.png" alt="_(Limit download rate...)"/> _(Limit download rate...)</a></li>
|
||||||
<li><a href="#UploadLimit"><img src="images/skin/seeding.png" alt="_(Limit upload rate...)"/> _(Limit upload rate...)</a></li>
|
<li><a href="#UploadLimit"><img src="images/skin/seeding.png" alt="_(Limit upload rate...)"/> _(Limit upload rate...)</a></li>
|
||||||
|
<li class="separator"><a href="#SequentialDownload"><img src="theme/checked" alt="_(Download in sequential order)"/> _(Download in sequential order)</a></li>
|
||||||
|
<li><a href="#FirstLastPiecePrio"><img src="theme/checked" alt="_(Download first and last piece first)"/> _(Download first and last piece first)</a></li>
|
||||||
<li class="separator"><a href="#ForceRecheck"><img src="theme/document-edit-verify" alt="_(Force recheck)"/> _(Force recheck)</a></li>
|
<li class="separator"><a href="#ForceRecheck"><img src="theme/document-edit-verify" alt="_(Force recheck)"/> _(Force recheck)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div id="desktopFooterWrapper">
|
<div id="desktopFooterWrapper">
|
||||||
|
|
|
@ -99,14 +99,21 @@ var loadTorrentsInfo = function () {
|
||||||
data[10] = event.ratio;
|
data[10] = event.ratio;
|
||||||
if (row[2] != null)
|
if (row[2] != null)
|
||||||
queueing_enabled = true;
|
queueing_enabled = true;
|
||||||
|
|
||||||
|
attrs = {};
|
||||||
|
attrs['downloaded'] = (event.progress == 1.0);
|
||||||
|
attrs['state'] = event.state;
|
||||||
|
attrs['seq_dl'] = (event.seq_dl == true);
|
||||||
|
attrs['f_l_piece_prio'] = (event.f_l_piece_prio == true);
|
||||||
|
|
||||||
if (!torrent_hashes.contains(event.hash)) {
|
if (!torrent_hashes.contains(event.hash)) {
|
||||||
// New unfinished torrent
|
// New unfinished torrent
|
||||||
torrent_hashes[torrent_hashes.length] = event.hash;
|
torrent_hashes[torrent_hashes.length] = event.hash;
|
||||||
//alert("Inserting row");
|
//alert("Inserting row");
|
||||||
myTable.insertRow(event.hash, row, data, event.state, pos);
|
myTable.insertRow(event.hash, row, data, attrs, pos);
|
||||||
} else {
|
} else {
|
||||||
// Update torrent data
|
// Update torrent data
|
||||||
myTable.updateRow(event.hash, row, data, event.state, pos);
|
myTable.updateRow(event.hash, row, data, attrs, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos++;
|
pos++;
|
||||||
|
|
|
@ -127,9 +127,36 @@ var ContextMenu = new Class({
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateMenuItems: function () {
|
||||||
|
all_are_seq_dl = true;
|
||||||
|
all_are_f_l_piece_prio = true;
|
||||||
|
all_are_downloaded = true;
|
||||||
|
|
||||||
|
var h = myTable.selectedIds();
|
||||||
|
h.each(function(item, index){
|
||||||
|
tr = myTable.rows.get(item);
|
||||||
|
if (tr.getAttribute('seq_dl') != 'true')
|
||||||
|
all_are_seq_dl = false;
|
||||||
|
if (tr.getAttribute('f_l_piece_prio') != 'true')
|
||||||
|
all_are_f_l_piece_prio = false;
|
||||||
|
if (tr.getAttribute('downloaded') != 'true')
|
||||||
|
all_are_downloaded = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (all_are_downloaded) {
|
||||||
|
this.hideItem('SequentialDownload');
|
||||||
|
this.hideItem('FirstLastPiecePrio');
|
||||||
|
} else {
|
||||||
|
this.showItem('SequentialDownload');
|
||||||
|
this.showItem('FirstLastPiecePrio');
|
||||||
|
this.setItemChecked('SequentialDownload', all_are_seq_dl);
|
||||||
|
this.setItemChecked('FirstLastPiecePrio', all_are_f_l_piece_prio);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
//show menu
|
//show menu
|
||||||
show: function(trigger) {
|
show: function(trigger) {
|
||||||
//this.menu.fade('in');
|
this.updateMenuItems();
|
||||||
this.fx.start(1);
|
this.fx.start(1);
|
||||||
this.fireEvent('show');
|
this.fireEvent('show');
|
||||||
this.shown = true;
|
this.shown = true;
|
||||||
|
@ -147,15 +174,21 @@ var ContextMenu = new Class({
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
//disable an item
|
setItemChecked: function(item, checked) {
|
||||||
disableItem: function(item) {
|
this.menu.getElement('a[href$=' + item + ']').firstChild.style.opacity =
|
||||||
this.menu.getElements('a[href$=' + item + ']').addClass('disabled');
|
checked ? '1' : '0';
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
//enable an item
|
//hide an item
|
||||||
enableItem: function(item) {
|
hideItem: function(item) {
|
||||||
this.menu.getElements('a[href$=' + item + ']').removeClass('disabled');
|
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;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -102,11 +102,13 @@ var dynamicTable = new Class({
|
||||||
this.priority_hidden = false;
|
this.priority_hidden = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
insertRow : function (id, row, data, status, pos) {
|
insertRow : function (id, row, data, attrs, pos) {
|
||||||
if (this.rows.has(id)) {
|
if (this.rows.has(id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var tr = new Element('tr');
|
var tr = new Element('tr');
|
||||||
|
for (var a in attrs)
|
||||||
|
tr.set(a, attrs[a]);
|
||||||
tr.addClass("menu-target");
|
tr.addClass("menu-target");
|
||||||
this.rows.set(id, tr);
|
this.rows.set(id, tr);
|
||||||
for (var i = 0; i < row.length; i++) {
|
for (var i = 0; i < row.length; i++) {
|
||||||
|
@ -246,12 +248,14 @@ var dynamicTable = new Class({
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateRow : function (id, row, data, status, newpos) {
|
updateRow : function (id, row, data, attrs, newpos) {
|
||||||
if (!this.rows.has(id)) {
|
if (!this.rows.has(id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tr = this.rows.get(id);
|
var tr = this.rows.get(id);
|
||||||
|
for (var a in attrs)
|
||||||
|
tr.set(a, attrs[a]);
|
||||||
var tds = tr.getElements('td');
|
var tds = tr.getElements('td');
|
||||||
for (var i = 0; i < row.length; i++) {
|
for (var i = 0; i < row.length; i++) {
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
|
|
|
@ -134,6 +134,34 @@ initializeWindows = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
toggleSequentialDownloadFN = function() {
|
||||||
|
var h = myTable.selectedIds();
|
||||||
|
if (h.length) {
|
||||||
|
new Request({
|
||||||
|
url: 'command/toggleSequentialDownload',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: h.join("|")
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
updateTransferList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleFirstLastPiecePrioFN = function() {
|
||||||
|
var h = myTable.selectedIds();
|
||||||
|
if (h.length) {
|
||||||
|
new Request({
|
||||||
|
url: 'command/toggleFirstLastPiecePrio',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: h.join("|")
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
updateTransferList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
globalDownloadLimitFN = function() {
|
globalDownloadLimitFN = function() {
|
||||||
new MochaUI.Window({
|
new MochaUI.Window({
|
||||||
id: 'downloadLimitPage',
|
id: 'downloadLimitPage',
|
||||||
|
|
|
@ -52,11 +52,17 @@
|
||||||
ForceRecheck : function (element, ref) {
|
ForceRecheck : function (element, ref) {
|
||||||
recheckFN();
|
recheckFN();
|
||||||
},
|
},
|
||||||
UploadLimit : function (element, red) {
|
UploadLimit : function (element, ref) {
|
||||||
uploadLimitFN();
|
uploadLimitFN();
|
||||||
},
|
},
|
||||||
DownloadLimit : function (element, red) {
|
DownloadLimit : function (element, ref) {
|
||||||
downloadLimitFN();
|
downloadLimitFN();
|
||||||
|
},
|
||||||
|
SequentialDownload : function (element, ref) {
|
||||||
|
toggleSequentialDownloadFN();
|
||||||
|
},
|
||||||
|
FirstLastPiecePrio : function (element, ref) {
|
||||||
|
toggleFirstLastPiecePrioFN();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
offsets : {
|
offsets : {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue