mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 07:18:08 +00:00
Improve Status Filter
replaces quadratic update operation with linear
This commit is contained in:
parent
25be00931a
commit
30319e51e5
@ -2085,6 +2085,11 @@ QVector<Torrent *> Session::torrents() const
|
||||
return result;
|
||||
}
|
||||
|
||||
qsizetype Session::torrentsCount() const
|
||||
{
|
||||
return m_torrents.size();
|
||||
}
|
||||
|
||||
bool Session::addTorrent(const QString &source, const AddTorrentParams ¶ms)
|
||||
{
|
||||
// `source`: .torrent file path/url or magnet uri
|
||||
|
@ -459,6 +459,7 @@ namespace BitTorrent
|
||||
void startUpTorrents();
|
||||
Torrent *findTorrent(const TorrentID &id) const;
|
||||
QVector<Torrent *> torrents() const;
|
||||
qsizetype torrentsCount() const;
|
||||
bool hasActiveTorrents() const;
|
||||
bool hasUnfinishedTorrents() const;
|
||||
bool hasRunningSeed() const;
|
||||
|
@ -169,13 +169,6 @@ void BaseFilterWidget::toggleFilter(bool checked)
|
||||
StatusFilterWidget::StatusFilterWidget(QWidget *parent, TransferListWidget *transferList)
|
||||
: BaseFilterWidget(parent, transferList)
|
||||
{
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentLoaded
|
||||
, this, &StatusFilterWidget::updateTorrentNumbers);
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentsUpdated
|
||||
, this, &StatusFilterWidget::updateTorrentNumbers);
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentAboutToBeRemoved
|
||||
, this, &StatusFilterWidget::updateTorrentNumbers);
|
||||
|
||||
// Add status filters
|
||||
auto *all = new QListWidgetItem(this);
|
||||
all->setData(Qt::DisplayRole, tr("All (0)", "this is for the status filter"));
|
||||
@ -220,6 +213,11 @@ StatusFilterWidget::StatusFilterWidget(QWidget *parent, TransferListWidget *tran
|
||||
const Preferences *const pref = Preferences::instance();
|
||||
setCurrentRow(pref->getTransSelFilter(), QItemSelectionModel::SelectCurrent);
|
||||
toggleFilter(pref->getStatusFilterState());
|
||||
|
||||
populate();
|
||||
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentsUpdated
|
||||
, this, &StatusFilterWidget::handleTorrentsUpdated);
|
||||
}
|
||||
|
||||
StatusFilterWidget::~StatusFilterWidget()
|
||||
@ -227,63 +225,87 @@ StatusFilterWidget::~StatusFilterWidget()
|
||||
Preferences::instance()->setTransSelFilter(currentRow());
|
||||
}
|
||||
|
||||
void StatusFilterWidget::updateTorrentNumbers()
|
||||
void StatusFilterWidget::populate()
|
||||
{
|
||||
int nbDownloading = 0;
|
||||
int nbSeeding = 0;
|
||||
int nbCompleted = 0;
|
||||
int nbResumed = 0;
|
||||
int nbPaused = 0;
|
||||
int nbActive = 0;
|
||||
int nbInactive = 0;
|
||||
int nbStalled = 0;
|
||||
int nbStalledUploading = 0;
|
||||
int nbStalledDownloading = 0;
|
||||
int nbChecking = 0;
|
||||
int nbErrored = 0;
|
||||
m_torrentsStatus.clear();
|
||||
|
||||
const QVector<BitTorrent::Torrent *> torrents = BitTorrent::Session::instance()->torrents();
|
||||
for (const BitTorrent::Torrent *torrent : torrents)
|
||||
{
|
||||
if (torrent->isDownloading())
|
||||
++nbDownloading;
|
||||
if (torrent->isUploading())
|
||||
++nbSeeding;
|
||||
if (torrent->isCompleted())
|
||||
++nbCompleted;
|
||||
if (torrent->isResumed())
|
||||
++nbResumed;
|
||||
if (torrent->isPaused())
|
||||
++nbPaused;
|
||||
if (torrent->isActive())
|
||||
++nbActive;
|
||||
if (torrent->isInactive())
|
||||
++nbInactive;
|
||||
if (torrent->state() == BitTorrent::TorrentState::StalledUploading)
|
||||
++nbStalledUploading;
|
||||
if (torrent->state() == BitTorrent::TorrentState::StalledDownloading)
|
||||
++nbStalledDownloading;
|
||||
if (torrent->isChecking())
|
||||
++nbChecking;
|
||||
if (torrent->isErrored())
|
||||
++nbErrored;
|
||||
updateTorrentStatus(torrent);
|
||||
}
|
||||
|
||||
nbStalled = nbStalledUploading + nbStalledDownloading;
|
||||
updateTexts();
|
||||
}
|
||||
|
||||
item(TorrentFilter::All)->setData(Qt::DisplayRole, tr("All (%1)").arg(torrents.count()));
|
||||
item(TorrentFilter::Downloading)->setData(Qt::DisplayRole, tr("Downloading (%1)").arg(nbDownloading));
|
||||
item(TorrentFilter::Seeding)->setData(Qt::DisplayRole, tr("Seeding (%1)").arg(nbSeeding));
|
||||
item(TorrentFilter::Completed)->setData(Qt::DisplayRole, tr("Completed (%1)").arg(nbCompleted));
|
||||
item(TorrentFilter::Resumed)->setData(Qt::DisplayRole, tr("Resumed (%1)").arg(nbResumed));
|
||||
item(TorrentFilter::Paused)->setData(Qt::DisplayRole, tr("Paused (%1)").arg(nbPaused));
|
||||
item(TorrentFilter::Active)->setData(Qt::DisplayRole, tr("Active (%1)").arg(nbActive));
|
||||
item(TorrentFilter::Inactive)->setData(Qt::DisplayRole, tr("Inactive (%1)").arg(nbInactive));
|
||||
item(TorrentFilter::Stalled)->setData(Qt::DisplayRole, tr("Stalled (%1)").arg(nbStalled));
|
||||
item(TorrentFilter::StalledUploading)->setData(Qt::DisplayRole, tr("Stalled Uploading (%1)").arg(nbStalledUploading));
|
||||
item(TorrentFilter::StalledDownloading)->setData(Qt::DisplayRole, tr("Stalled Downloading (%1)").arg(nbStalledDownloading));
|
||||
item(TorrentFilter::Checking)->setData(Qt::DisplayRole, tr("Checking (%1)").arg(nbChecking));
|
||||
item(TorrentFilter::Errored)->setData(Qt::DisplayRole, tr("Errored (%1)").arg(nbErrored));
|
||||
void StatusFilterWidget::updateTorrentStatus(const BitTorrent::Torrent *torrent)
|
||||
{
|
||||
const auto update = [this, torrent](const TorrentFilter::Type status, const bool insert, int &count)
|
||||
{
|
||||
const bool contains = m_torrentsStatus.contains(torrent, status);
|
||||
if (insert && !contains)
|
||||
{
|
||||
++count;
|
||||
m_torrentsStatus.insert(torrent, status);
|
||||
}
|
||||
else if (!insert && contains)
|
||||
{
|
||||
--count;
|
||||
m_torrentsStatus.remove(torrent, status);
|
||||
}
|
||||
};
|
||||
|
||||
update(TorrentFilter::Downloading, torrent->isDownloading(), m_nbDownloading);
|
||||
|
||||
update(TorrentFilter::Seeding, torrent->isUploading(), m_nbSeeding);
|
||||
|
||||
update(TorrentFilter::Completed, torrent->isCompleted(), m_nbCompleted);
|
||||
|
||||
update(TorrentFilter::Resumed, torrent->isResumed(), m_nbResumed);
|
||||
|
||||
update(TorrentFilter::Paused, torrent->isPaused(), m_nbPaused);
|
||||
|
||||
update(TorrentFilter::Active, torrent->isActive(), m_nbActive);
|
||||
|
||||
update(TorrentFilter::Inactive, torrent->isInactive(), m_nbInactive);
|
||||
|
||||
const bool isStalledUploading = (torrent->state() == BitTorrent::TorrentState::StalledUploading);
|
||||
update(TorrentFilter::StalledUploading, isStalledUploading, m_nbStalledUploading);
|
||||
|
||||
const bool isStalledDownloading = (torrent->state() == BitTorrent::TorrentState::StalledDownloading);
|
||||
update(TorrentFilter::StalledDownloading, isStalledDownloading, m_nbStalledDownloading);
|
||||
|
||||
update(TorrentFilter::Checking, torrent->isChecking(), m_nbChecking);
|
||||
|
||||
update(TorrentFilter::Errored, torrent->isErrored(), m_nbErrored);
|
||||
|
||||
m_nbStalled = m_nbStalledUploading + m_nbStalledDownloading;
|
||||
}
|
||||
|
||||
void StatusFilterWidget::updateTexts()
|
||||
{
|
||||
const qsizetype torrentsCount = BitTorrent::Session::instance()->torrentsCount();
|
||||
item(TorrentFilter::All)->setData(Qt::DisplayRole, tr("All (%1)").arg(torrentsCount));
|
||||
item(TorrentFilter::Downloading)->setData(Qt::DisplayRole, tr("Downloading (%1)").arg(m_nbDownloading));
|
||||
item(TorrentFilter::Seeding)->setData(Qt::DisplayRole, tr("Seeding (%1)").arg(m_nbSeeding));
|
||||
item(TorrentFilter::Completed)->setData(Qt::DisplayRole, tr("Completed (%1)").arg(m_nbCompleted));
|
||||
item(TorrentFilter::Resumed)->setData(Qt::DisplayRole, tr("Resumed (%1)").arg(m_nbResumed));
|
||||
item(TorrentFilter::Paused)->setData(Qt::DisplayRole, tr("Paused (%1)").arg(m_nbPaused));
|
||||
item(TorrentFilter::Active)->setData(Qt::DisplayRole, tr("Active (%1)").arg(m_nbActive));
|
||||
item(TorrentFilter::Inactive)->setData(Qt::DisplayRole, tr("Inactive (%1)").arg(m_nbInactive));
|
||||
item(TorrentFilter::Stalled)->setData(Qt::DisplayRole, tr("Stalled (%1)").arg(m_nbStalled));
|
||||
item(TorrentFilter::StalledUploading)->setData(Qt::DisplayRole, tr("Stalled Uploading (%1)").arg(m_nbStalledUploading));
|
||||
item(TorrentFilter::StalledDownloading)->setData(Qt::DisplayRole, tr("Stalled Downloading (%1)").arg(m_nbStalledDownloading));
|
||||
item(TorrentFilter::Checking)->setData(Qt::DisplayRole, tr("Checking (%1)").arg(m_nbChecking));
|
||||
item(TorrentFilter::Errored)->setData(Qt::DisplayRole, tr("Errored (%1)").arg(m_nbErrored));
|
||||
}
|
||||
|
||||
void StatusFilterWidget::handleTorrentsUpdated(const QVector<BitTorrent::Torrent *> torrents)
|
||||
{
|
||||
for (const BitTorrent::Torrent *torrent : torrents)
|
||||
updateTorrentStatus(torrent);
|
||||
|
||||
updateTexts();
|
||||
}
|
||||
|
||||
void StatusFilterWidget::showMenu()
|
||||
@ -306,9 +328,64 @@ void StatusFilterWidget::applyFilter(int row)
|
||||
transferList->applyStatusFilter(row);
|
||||
}
|
||||
|
||||
void StatusFilterWidget::handleNewTorrent(BitTorrent::Torrent *const) {}
|
||||
void StatusFilterWidget::handleNewTorrent(BitTorrent::Torrent *const torrent)
|
||||
{
|
||||
updateTorrentStatus(torrent);
|
||||
updateTexts();
|
||||
}
|
||||
|
||||
void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const) {}
|
||||
void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent)
|
||||
{
|
||||
for (const TorrentFilter::Type status : m_torrentsStatus.values(torrent))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case TorrentFilter::Downloading:
|
||||
--m_nbDownloading;
|
||||
break;
|
||||
case TorrentFilter::Seeding:
|
||||
--m_nbSeeding;
|
||||
break;
|
||||
case TorrentFilter::Completed:
|
||||
--m_nbCompleted;
|
||||
break;
|
||||
case TorrentFilter::Resumed:
|
||||
--m_nbResumed;
|
||||
break;
|
||||
case TorrentFilter::Paused:
|
||||
--m_nbPaused;
|
||||
break;
|
||||
case TorrentFilter::Active:
|
||||
--m_nbActive;
|
||||
break;
|
||||
case TorrentFilter::Inactive:
|
||||
--m_nbInactive;
|
||||
break;
|
||||
case TorrentFilter::StalledUploading:
|
||||
--m_nbStalledUploading;
|
||||
break;
|
||||
case TorrentFilter::StalledDownloading:
|
||||
--m_nbStalledDownloading;
|
||||
break;
|
||||
case TorrentFilter::Checking:
|
||||
--m_nbChecking;
|
||||
break;
|
||||
case TorrentFilter::Errored:
|
||||
--m_nbErrored;
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_nbStalled = m_nbStalledUploading + m_nbStalledDownloading;
|
||||
|
||||
m_torrentsStatus.remove(torrent);
|
||||
|
||||
updateTexts();
|
||||
}
|
||||
|
||||
TrackerFiltersList::TrackerFiltersList(QWidget *parent, TransferListWidget *transferList, const bool downloadFavicon)
|
||||
: BaseFilterWidget(parent, transferList)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "base/bittorrent/infohash.h"
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/trackerentry.h"
|
||||
#include "base/torrentfilter.h"
|
||||
#include "base/path.h"
|
||||
|
||||
class QCheckBox;
|
||||
@ -81,7 +82,7 @@ public:
|
||||
~StatusFilterWidget() override;
|
||||
|
||||
private slots:
|
||||
void updateTorrentNumbers();
|
||||
void handleTorrentsUpdated(const QVector<BitTorrent::Torrent *> torrents);
|
||||
|
||||
private:
|
||||
// These 4 methods are virtual slots in the base class.
|
||||
@ -90,6 +91,24 @@ private:
|
||||
void applyFilter(int row) override;
|
||||
void handleNewTorrent(BitTorrent::Torrent *const) override;
|
||||
void torrentAboutToBeDeleted(BitTorrent::Torrent *const) override;
|
||||
|
||||
void populate();
|
||||
void updateTorrentStatus(const BitTorrent::Torrent *torrent);
|
||||
void updateTexts();
|
||||
|
||||
QMultiHash<const BitTorrent::Torrent *, TorrentFilter::Type> m_torrentsStatus;
|
||||
int m_nbDownloading = 0;
|
||||
int m_nbSeeding = 0;
|
||||
int m_nbCompleted = 0;
|
||||
int m_nbResumed = 0;
|
||||
int m_nbPaused = 0;
|
||||
int m_nbActive = 0;
|
||||
int m_nbInactive = 0;
|
||||
int m_nbStalled = 0;
|
||||
int m_nbStalledUploading = 0;
|
||||
int m_nbStalledDownloading = 0;
|
||||
int m_nbChecking = 0;
|
||||
int m_nbErrored = 0;
|
||||
};
|
||||
|
||||
class TrackerFiltersList final : public BaseFilterWidget
|
||||
|
Loading…
Reference in New Issue
Block a user