Browse Source

Improve Status Filter

replaces quadratic update operation with linear
adaptive-webui-19844
Prince Gupta 3 years ago
parent
commit
30319e51e5
  1. 5
      src/base/bittorrent/session.cpp
  2. 1
      src/base/bittorrent/session.h
  3. 199
      src/gui/transferlistfilterswidget.cpp
  4. 21
      src/gui/transferlistfilterswidget.h

5
src/base/bittorrent/session.cpp

@ -2085,6 +2085,11 @@ QVector<Torrent *> Session::torrents() const
return result; return result;
} }
qsizetype Session::torrentsCount() const
{
return m_torrents.size();
}
bool Session::addTorrent(const QString &source, const AddTorrentParams &params) bool Session::addTorrent(const QString &source, const AddTorrentParams &params)
{ {
// `source`: .torrent file path/url or magnet uri // `source`: .torrent file path/url or magnet uri

1
src/base/bittorrent/session.h

@ -459,6 +459,7 @@ namespace BitTorrent
void startUpTorrents(); void startUpTorrents();
Torrent *findTorrent(const TorrentID &id) const; Torrent *findTorrent(const TorrentID &id) const;
QVector<Torrent *> torrents() const; QVector<Torrent *> torrents() const;
qsizetype torrentsCount() const;
bool hasActiveTorrents() const; bool hasActiveTorrents() const;
bool hasUnfinishedTorrents() const; bool hasUnfinishedTorrents() const;
bool hasRunningSeed() const; bool hasRunningSeed() const;

199
src/gui/transferlistfilterswidget.cpp

@ -169,13 +169,6 @@ void BaseFilterWidget::toggleFilter(bool checked)
StatusFilterWidget::StatusFilterWidget(QWidget *parent, TransferListWidget *transferList) StatusFilterWidget::StatusFilterWidget(QWidget *parent, TransferListWidget *transferList)
: BaseFilterWidget(parent, 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 // Add status filters
auto *all = new QListWidgetItem(this); auto *all = new QListWidgetItem(this);
all->setData(Qt::DisplayRole, tr("All (0)", "this is for the status filter")); 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(); const Preferences *const pref = Preferences::instance();
setCurrentRow(pref->getTransSelFilter(), QItemSelectionModel::SelectCurrent); setCurrentRow(pref->getTransSelFilter(), QItemSelectionModel::SelectCurrent);
toggleFilter(pref->getStatusFilterState()); toggleFilter(pref->getStatusFilterState());
populate();
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentsUpdated
, this, &StatusFilterWidget::handleTorrentsUpdated);
} }
StatusFilterWidget::~StatusFilterWidget() StatusFilterWidget::~StatusFilterWidget()
@ -227,63 +225,87 @@ StatusFilterWidget::~StatusFilterWidget()
Preferences::instance()->setTransSelFilter(currentRow()); Preferences::instance()->setTransSelFilter(currentRow());
} }
void StatusFilterWidget::updateTorrentNumbers() void StatusFilterWidget::populate()
{ {
int nbDownloading = 0; m_torrentsStatus.clear();
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;
const QVector<BitTorrent::Torrent *> torrents = BitTorrent::Session::instance()->torrents(); const QVector<BitTorrent::Torrent *> torrents = BitTorrent::Session::instance()->torrents();
for (const BitTorrent::Torrent *torrent : torrents) for (const BitTorrent::Torrent *torrent : torrents)
{ {
if (torrent->isDownloading()) updateTorrentStatus(torrent);
++nbDownloading; }
if (torrent->isUploading())
++nbSeeding; updateTexts();
if (torrent->isCompleted()) }
++nbCompleted;
if (torrent->isResumed()) void StatusFilterWidget::updateTorrentStatus(const BitTorrent::Torrent *torrent)
++nbResumed; {
if (torrent->isPaused()) const auto update = [this, torrent](const TorrentFilter::Type status, const bool insert, int &count)
++nbPaused; {
if (torrent->isActive()) const bool contains = m_torrentsStatus.contains(torrent, status);
++nbActive; if (insert && !contains)
if (torrent->isInactive()) {
++nbInactive; ++count;
if (torrent->state() == BitTorrent::TorrentState::StalledUploading) m_torrentsStatus.insert(torrent, status);
++nbStalledUploading; }
if (torrent->state() == BitTorrent::TorrentState::StalledDownloading) else if (!insert && contains)
++nbStalledDownloading; {
if (torrent->isChecking()) --count;
++nbChecking; m_torrentsStatus.remove(torrent, status);
if (torrent->isErrored()) }
++nbErrored; };
}
update(TorrentFilter::Downloading, torrent->isDownloading(), m_nbDownloading);
nbStalled = nbStalledUploading + nbStalledDownloading;
update(TorrentFilter::Seeding, torrent->isUploading(), m_nbSeeding);
item(TorrentFilter::All)->setData(Qt::DisplayRole, tr("All (%1)").arg(torrents.count()));
item(TorrentFilter::Downloading)->setData(Qt::DisplayRole, tr("Downloading (%1)").arg(nbDownloading)); update(TorrentFilter::Completed, torrent->isCompleted(), m_nbCompleted);
item(TorrentFilter::Seeding)->setData(Qt::DisplayRole, tr("Seeding (%1)").arg(nbSeeding));
item(TorrentFilter::Completed)->setData(Qt::DisplayRole, tr("Completed (%1)").arg(nbCompleted)); update(TorrentFilter::Resumed, torrent->isResumed(), m_nbResumed);
item(TorrentFilter::Resumed)->setData(Qt::DisplayRole, tr("Resumed (%1)").arg(nbResumed));
item(TorrentFilter::Paused)->setData(Qt::DisplayRole, tr("Paused (%1)").arg(nbPaused)); update(TorrentFilter::Paused, torrent->isPaused(), m_nbPaused);
item(TorrentFilter::Active)->setData(Qt::DisplayRole, tr("Active (%1)").arg(nbActive));
item(TorrentFilter::Inactive)->setData(Qt::DisplayRole, tr("Inactive (%1)").arg(nbInactive)); update(TorrentFilter::Active, torrent->isActive(), m_nbActive);
item(TorrentFilter::Stalled)->setData(Qt::DisplayRole, tr("Stalled (%1)").arg(nbStalled));
item(TorrentFilter::StalledUploading)->setData(Qt::DisplayRole, tr("Stalled Uploading (%1)").arg(nbStalledUploading)); update(TorrentFilter::Inactive, torrent->isInactive(), m_nbInactive);
item(TorrentFilter::StalledDownloading)->setData(Qt::DisplayRole, tr("Stalled Downloading (%1)").arg(nbStalledDownloading));
item(TorrentFilter::Checking)->setData(Qt::DisplayRole, tr("Checking (%1)").arg(nbChecking)); const bool isStalledUploading = (torrent->state() == BitTorrent::TorrentState::StalledUploading);
item(TorrentFilter::Errored)->setData(Qt::DisplayRole, tr("Errored (%1)").arg(nbErrored)); 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() void StatusFilterWidget::showMenu()
@ -306,9 +328,64 @@ void StatusFilterWidget::applyFilter(int row)
transferList->applyStatusFilter(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) TrackerFiltersList::TrackerFiltersList(QWidget *parent, TransferListWidget *transferList, const bool downloadFavicon)
: BaseFilterWidget(parent, transferList) : BaseFilterWidget(parent, transferList)

21
src/gui/transferlistfilterswidget.h

@ -35,6 +35,7 @@
#include "base/bittorrent/infohash.h" #include "base/bittorrent/infohash.h"
#include "base/bittorrent/session.h" #include "base/bittorrent/session.h"
#include "base/bittorrent/trackerentry.h" #include "base/bittorrent/trackerentry.h"
#include "base/torrentfilter.h"
#include "base/path.h" #include "base/path.h"
class QCheckBox; class QCheckBox;
@ -81,7 +82,7 @@ public:
~StatusFilterWidget() override; ~StatusFilterWidget() override;
private slots: private slots:
void updateTorrentNumbers(); void handleTorrentsUpdated(const QVector<BitTorrent::Torrent *> torrents);
private: private:
// These 4 methods are virtual slots in the base class. // These 4 methods are virtual slots in the base class.
@ -90,6 +91,24 @@ private:
void applyFilter(int row) override; void applyFilter(int row) override;
void handleNewTorrent(BitTorrent::Torrent *const) override; void handleNewTorrent(BitTorrent::Torrent *const) override;
void torrentAboutToBeDeleted(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 class TrackerFiltersList final : public BaseFilterWidget

Loading…
Cancel
Save