Browse Source

Merge pull request #11313 from Chocobo1/queue

Preserve relative order when moving to top/bottom in queue
adaptive-webui-19844
Mike Tzou 5 years ago committed by GitHub
parent
commit
339e195043
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 61
      src/base/bittorrent/session.cpp
  2. 8
      src/base/bittorrent/session.h
  3. 15
      src/gui/transferlistwidget.cpp
  4. 18
      src/webui/api/torrentscontroller.cpp

61
src/base/bittorrent/session.cpp

@ -33,6 +33,7 @@
#include <cstdlib> #include <cstdlib>
#include <queue> #include <queue>
#include <string> #include <string>
#include <utility>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <wincrypt.h> #include <wincrypt.h>
@ -1699,22 +1700,23 @@ bool Session::cancelLoadMetadata(const InfoHash &hash)
return true; return true;
} }
void Session::increaseTorrentsQueuePos(const QStringList &hashes) void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
{ {
std::priority_queue<QPair<int, TorrentHandle *>, using ElementType = std::pair<int, TorrentHandle *>;
std::vector<QPair<int, TorrentHandle *>>, std::priority_queue<ElementType
std::greater<QPair<int, TorrentHandle *>>> torrentQueue; , std::vector<ElementType>
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash infoHash : hashes) { for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash); TorrentHandle *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed()) if (torrent && !torrent->isSeed())
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent)); torrentQueue.emplace(torrent->queuePosition(), torrent);
} }
// Increase torrents queue position (starting with the one in the highest queue position) // Increase torrents queue position (starting with the one in the highest queue position)
while (!torrentQueue.empty()) { while (!torrentQueue.empty()) {
TorrentHandle *const torrent = torrentQueue.top().second; const TorrentHandle *torrent = torrentQueue.top().second;
torrentQueuePositionUp(torrent->nativeHandle()); torrentQueuePositionUp(torrent->nativeHandle());
torrentQueue.pop(); torrentQueue.pop();
} }
@ -1722,22 +1724,21 @@ void Session::increaseTorrentsQueuePos(const QStringList &hashes)
saveTorrentsQueue(); saveTorrentsQueue();
} }
void Session::decreaseTorrentsQueuePos(const QStringList &hashes) void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
{ {
std::priority_queue<QPair<int, TorrentHandle *>, using ElementType = std::pair<int, TorrentHandle *>;
std::vector<QPair<int, TorrentHandle *>>, std::priority_queue<ElementType> torrentQueue;
std::less<QPair<int, TorrentHandle *>>> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash infoHash : hashes) { for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash); TorrentHandle *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed()) if (torrent && !torrent->isSeed())
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent)); torrentQueue.emplace(torrent->queuePosition(), torrent);
} }
// Decrease torrents queue position (starting with the one in the lowest queue position) // Decrease torrents queue position (starting with the one in the lowest queue position)
while (!torrentQueue.empty()) { while (!torrentQueue.empty()) {
TorrentHandle *const torrent = torrentQueue.top().second; const TorrentHandle *torrent = torrentQueue.top().second;
torrentQueuePositionDown(torrent->nativeHandle()); torrentQueuePositionDown(torrent->nativeHandle());
torrentQueue.pop(); torrentQueue.pop();
} }
@ -1748,22 +1749,21 @@ void Session::decreaseTorrentsQueuePos(const QStringList &hashes)
saveTorrentsQueue(); saveTorrentsQueue();
} }
void Session::topTorrentsQueuePos(const QStringList &hashes) void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
{ {
std::priority_queue<QPair<int, TorrentHandle *>, using ElementType = std::pair<int, TorrentHandle *>;
std::vector<QPair<int, TorrentHandle *>>, std::priority_queue<ElementType> torrentQueue;
std::greater<QPair<int, TorrentHandle *>>> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash infoHash : hashes) { for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash); TorrentHandle *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed()) if (torrent && !torrent->isSeed())
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent)); torrentQueue.emplace(torrent->queuePosition(), torrent);
} }
// Top torrents queue position (starting with the one in the highest queue position) // Top torrents queue position (starting with the one in the lowest queue position)
while (!torrentQueue.empty()) { while (!torrentQueue.empty()) {
TorrentHandle *const torrent = torrentQueue.top().second; const TorrentHandle *torrent = torrentQueue.top().second;
torrentQueuePositionTop(torrent->nativeHandle()); torrentQueuePositionTop(torrent->nativeHandle());
torrentQueue.pop(); torrentQueue.pop();
} }
@ -1771,22 +1771,23 @@ void Session::topTorrentsQueuePos(const QStringList &hashes)
saveTorrentsQueue(); saveTorrentsQueue();
} }
void Session::bottomTorrentsQueuePos(const QStringList &hashes) void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
{ {
std::priority_queue<QPair<int, TorrentHandle *>, using ElementType = std::pair<int, TorrentHandle *>;
std::vector<QPair<int, TorrentHandle *>>, std::priority_queue<ElementType
std::less<QPair<int, TorrentHandle *>>> torrentQueue; , std::vector<ElementType>
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash infoHash : hashes) { for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash); TorrentHandle *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed()) if (torrent && !torrent->isSeed())
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent)); torrentQueue.emplace(torrent->queuePosition(), torrent);
} }
// Bottom torrents queue position (starting with the one in the lowest queue position) // Bottom torrents queue position (starting with the one in the highest queue position)
while (!torrentQueue.empty()) { while (!torrentQueue.empty()) {
TorrentHandle *const torrent = torrentQueue.top().second; const TorrentHandle *torrent = torrentQueue.top().second;
torrentQueuePositionBottom(torrent->nativeHandle()); torrentQueuePositionBottom(torrent->nativeHandle());
torrentQueue.pop(); torrentQueue.pop();
} }

8
src/base/bittorrent/session.h

@ -412,10 +412,10 @@ namespace BitTorrent
bool cancelLoadMetadata(const InfoHash &hash); bool cancelLoadMetadata(const InfoHash &hash);
void recursiveTorrentDownload(const InfoHash &hash); void recursiveTorrentDownload(const InfoHash &hash);
void increaseTorrentsQueuePos(const QStringList &hashes); void increaseTorrentsQueuePos(const QVector<InfoHash> &hashes);
void decreaseTorrentsQueuePos(const QStringList &hashes); void decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes);
void topTorrentsQueuePos(const QStringList &hashes); void topTorrentsQueuePos(const QVector<InfoHash> &hashes);
void bottomTorrentsQueuePos(const QStringList &hashes); void bottomTorrentsQueuePos(const QVector<InfoHash> &hashes);
// TorrentHandle interface // TorrentHandle interface
void handleTorrentSaveResumeDataRequested(const TorrentHandle *torrent); void handleTorrentSaveResumeDataRequested(const TorrentHandle *torrent);

15
src/gui/transferlistwidget.cpp

@ -43,6 +43,7 @@
#include <QTableView> #include <QTableView>
#include <QWheelEvent> #include <QWheelEvent>
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/session.h" #include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h" #include "base/bittorrent/torrenthandle.h"
#include "base/bittorrent/trackerentry.h" #include "base/bittorrent/trackerentry.h"
@ -75,12 +76,12 @@
namespace namespace
{ {
QStringList extractHashes(const QVector<BitTorrent::TorrentHandle *> &torrents) QVector<BitTorrent::InfoHash> extractHashes(const QVector<BitTorrent::TorrentHandle *> &torrents)
{ {
QStringList hashes; QVector<BitTorrent::InfoHash> hashes;
for (BitTorrent::TorrentHandle *const torrent : torrents) hashes.reserve(torrents.size());
for (const BitTorrent::TorrentHandle *torrent : torrents)
hashes << torrent->hash(); hashes << torrent->hash();
return hashes; return hashes;
} }
@ -283,10 +284,12 @@ void TransferListWidget::torrentDoubleClicked()
QVector<BitTorrent::TorrentHandle *> TransferListWidget::getSelectedTorrents() const QVector<BitTorrent::TorrentHandle *> TransferListWidget::getSelectedTorrents() const
{ {
const QModelIndexList selectedRows = selectionModel()->selectedRows();
QVector<BitTorrent::TorrentHandle *> torrents; QVector<BitTorrent::TorrentHandle *> torrents;
for (const QModelIndex &index : asConst(selectionModel()->selectedRows())) torrents.reserve(selectedRows.size());
for (const QModelIndex &index : selectedRows)
torrents << m_listModel->torrentHandle(mapToSource(index)); torrents << m_listModel->torrentHandle(mapToSource(index));
return torrents; return torrents;
} }

18
src/webui/api/torrentscontroller.cpp

@ -40,6 +40,7 @@
#include <QUrl> #include <QUrl>
#include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/downloadpriority.h"
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/peeraddress.h" #include "base/bittorrent/peeraddress.h"
#include "base/bittorrent/peerinfo.h" #include "base/bittorrent/peerinfo.h"
#include "base/bittorrent/session.h" #include "base/bittorrent/session.h"
@ -197,6 +198,15 @@ namespace
return {dht, pex, lsd}; return {dht, pex, lsd};
} }
QVector<BitTorrent::InfoHash> toInfoHashes(const QStringList &hashes)
{
QVector<BitTorrent::InfoHash> infoHashes;
infoHashes.reserve(hashes.size());
for (const QString &hash : hashes)
infoHashes << hash;
return infoHashes;
}
} }
// Returns all the torrents in JSON format. // Returns all the torrents in JSON format.
@ -901,7 +911,7 @@ void TorrentsController::increasePrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->increaseTorrentsQueuePos(hashes); BitTorrent::Session::instance()->increaseTorrentsQueuePos(toInfoHashes(hashes));
} }
void TorrentsController::decreasePrioAction() void TorrentsController::decreasePrioAction()
@ -912,7 +922,7 @@ void TorrentsController::decreasePrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->decreaseTorrentsQueuePos(hashes); BitTorrent::Session::instance()->decreaseTorrentsQueuePos(toInfoHashes(hashes));
} }
void TorrentsController::topPrioAction() void TorrentsController::topPrioAction()
@ -923,7 +933,7 @@ void TorrentsController::topPrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->topTorrentsQueuePos(hashes); BitTorrent::Session::instance()->topTorrentsQueuePos(toInfoHashes(hashes));
} }
void TorrentsController::bottomPrioAction() void TorrentsController::bottomPrioAction()
@ -934,7 +944,7 @@ void TorrentsController::bottomPrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->bottomTorrentsQueuePos(hashes); BitTorrent::Session::instance()->bottomTorrentsQueuePos(toInfoHashes(hashes));
} }
void TorrentsController::setLocationAction() void TorrentsController::setLocationAction()

Loading…
Cancel
Save