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. 193
      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 @@ -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 &params)
{
// `source`: .torrent file path/url or magnet uri

1
src/base/bittorrent/session.h

@ -459,6 +459,7 @@ namespace BitTorrent @@ -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;

193
src/gui/transferlistfilterswidget.cpp

@ -169,13 +169,6 @@ void BaseFilterWidget::toggleFilter(bool checked) @@ -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 @@ -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() @@ -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();
}
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);
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));
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) @@ -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)

21
src/gui/transferlistfilterswidget.h

@ -35,6 +35,7 @@ @@ -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: @@ -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: @@ -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…
Cancel
Save