Merge pull request #13912 from Chocobo1/infohash

Use the correct type when referring to info hash
This commit is contained in:
Mike Tzou 2020-12-08 20:53:12 +08:00 committed by GitHub
commit d484c0e7ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 152 additions and 160 deletions

View file

@ -35,11 +35,6 @@ using namespace BitTorrent;
const int InfoHashTypeId = qRegisterMetaType<InfoHash>();
InfoHash::InfoHash()
: m_valid(false)
{
}
InfoHash::InfoHash(const lt::sha1_hash &nativeHash)
: m_valid(true)
, m_nativeHash(nativeHash)

View file

@ -38,7 +38,7 @@ namespace BitTorrent
class InfoHash
{
public:
InfoHash();
InfoHash() = default;
InfoHash(const lt::sha1_hash &nativeHash);
InfoHash(const QString &hashString);
InfoHash(const InfoHash &other) = default;
@ -54,7 +54,7 @@ namespace BitTorrent
operator QString() const;
private:
bool m_valid;
bool m_valid = false;
lt::sha1_hash m_nativeHash;
QString m_hashString;
};

View file

@ -32,7 +32,7 @@
#include "bittorrent/torrenthandle.h"
const QString TorrentFilter::AnyCategory;
const QStringSet TorrentFilter::AnyHash = (QStringSet() << QString());
const InfoHashSet TorrentFilter::AnyHash {{}};
const QString TorrentFilter::AnyTag;
const TorrentFilter TorrentFilter::DownloadingTorrent(TorrentFilter::Downloading);
@ -49,12 +49,7 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
using BitTorrent::TorrentHandle;
TorrentFilter::TorrentFilter()
: m_type(All)
{
}
TorrentFilter::TorrentFilter(const Type type, const QStringSet &hashSet, const QString &category, const QString &tag)
TorrentFilter::TorrentFilter(const Type type, const InfoHashSet &hashSet, const QString &category, const QString &tag)
: m_type(type)
, m_category(category)
, m_tag(tag)
@ -62,7 +57,7 @@ TorrentFilter::TorrentFilter(const Type type, const QStringSet &hashSet, const Q
{
}
TorrentFilter::TorrentFilter(const QString &filter, const QStringSet &hashSet, const QString &category, const QString &tag)
TorrentFilter::TorrentFilter(const QString &filter, const InfoHashSet &hashSet, const QString &category, const QString &tag)
: m_type(All)
, m_category(category)
, m_tag(tag)
@ -112,7 +107,7 @@ bool TorrentFilter::setTypeByName(const QString &filter)
return setType(type);
}
bool TorrentFilter::setHashSet(const QStringSet &hashSet)
bool TorrentFilter::setHashSet(const InfoHashSet &hashSet)
{
if (m_hashSet != hashSet)
{

View file

@ -32,13 +32,15 @@
#include <QSet>
#include <QString>
typedef QSet<QString> QStringSet;
#include "base/bittorrent/infohash.h"
namespace BitTorrent
{
class TorrentHandle;
}
using InfoHashSet = QSet<BitTorrent::InfoHash>;
class TorrentFilter
{
public:
@ -60,7 +62,7 @@ public:
// These mean any permutation, including no category / tag.
static const QString AnyCategory;
static const QStringSet AnyHash;
static const InfoHashSet AnyHash;
static const QString AnyTag;
static const TorrentFilter DownloadingTorrent;
@ -75,15 +77,15 @@ public:
static const TorrentFilter StalledDownloadingTorrent;
static const TorrentFilter ErroredTorrent;
TorrentFilter();
TorrentFilter() = default;
// category & tags: pass empty string for uncategorized / untagged torrents.
// Pass null string (QString()) to disable filtering (i.e. all torrents).
TorrentFilter(Type type, const QStringSet &hashSet = AnyHash, const QString &category = AnyCategory, const QString &tag = AnyTag);
TorrentFilter(const QString &filter, const QStringSet &hashSet = AnyHash, const QString &category = AnyCategory, const QString &tags = AnyTag);
TorrentFilter(Type type, const InfoHashSet &hashSet = AnyHash, const QString &category = AnyCategory, const QString &tag = AnyTag);
TorrentFilter(const QString &filter, const InfoHashSet &hashSet = AnyHash, const QString &category = AnyCategory, const QString &tags = AnyTag);
bool setType(Type type);
bool setTypeByName(const QString &filter);
bool setHashSet(const QStringSet &hashSet);
bool setHashSet(const InfoHashSet &hashSet);
bool setCategory(const QString &category);
bool setTag(const QString &tag);
@ -95,10 +97,10 @@ private:
bool matchCategory(const BitTorrent::TorrentHandle *torrent) const;
bool matchTag(const BitTorrent::TorrentHandle *torrent) const;
Type m_type;
Type m_type {All};
QString m_category;
QString m_tag;
QStringSet m_hashSet;
InfoHashSet m_hashSet;
};
#endif // TORRENTFILTER_H

View file

@ -264,11 +264,11 @@ MainWindow::MainWindow(QWidget *parent)
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerlessStateChanged, m_transferListFiltersWidget, &TransferListFiltersWidget::changeTrackerless);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerSuccess
, m_transferListFiltersWidget, qOverload<BitTorrent::TorrentHandle *const, const QString &>(&TransferListFiltersWidget::trackerSuccess));
, m_transferListFiltersWidget, qOverload<const BitTorrent::TorrentHandle *, const QString &>(&TransferListFiltersWidget::trackerSuccess));
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerError
, m_transferListFiltersWidget, qOverload<BitTorrent::TorrentHandle *const, const QString &>(&TransferListFiltersWidget::trackerError));
, m_transferListFiltersWidget, qOverload<const BitTorrent::TorrentHandle *, const QString &>(&TransferListFiltersWidget::trackerError));
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerWarning
, m_transferListFiltersWidget, qOverload<BitTorrent::TorrentHandle *const, const QString &>(&TransferListFiltersWidget::trackerWarning));
, m_transferListFiltersWidget, qOverload<const BitTorrent::TorrentHandle *, const QString &>(&TransferListFiltersWidget::trackerWarning));
#ifdef Q_OS_MACOS
// Increase top spacing to avoid tab overlapping

View file

@ -74,6 +74,19 @@ namespace
return scheme;
}
QString getHost(const QString &tracker)
{
// We want the domain + tld. Subdomains should be disregarded
const QUrl url {tracker};
const QString host {url.host()};
// host is in IP format
if (!QHostAddress(host).isNull())
return host;
return host.section('.', -2, -1);
}
class ArrowCheckBox final : public QCheckBox
{
public:
@ -97,6 +110,8 @@ namespace
style()->drawControl(QStyle::CE_CheckBoxLabel, &labelOption, &painter, this);
}
};
const QString NULL_HOST {""};
}
BaseFilterWidget::BaseFilterWidget(QWidget *parent, TransferListWidget *transferList)
@ -294,7 +309,7 @@ TrackerFiltersList::TrackerFiltersList(QWidget *parent, TransferListWidget *tran
auto *warningTracker = new QListWidgetItem(this);
warningTracker->setData(Qt::DisplayRole, tr("Warning (0)"));
warningTracker->setData(Qt::DecorationRole, style()->standardIcon(QStyle::SP_MessageBoxWarning));
m_trackers.insert("", QStringList());
m_trackers[NULL_HOST] = {};
setCurrentRow(0, QItemSelectionModel::SelectCurrent);
toggleFilter(Preferences::instance()->getTrackerFilterState());
@ -306,27 +321,20 @@ TrackerFiltersList::~TrackerFiltersList()
Utils::Fs::forceRemove(iconPath);
}
void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoHash &hash)
{
QStringList tmp;
QListWidgetItem *trackerItem = nullptr;
QString host = getHost(tracker);
bool exists = m_trackers.contains(host);
const QString host {getHost(tracker)};
const bool exists {m_trackers.contains(host)};
QListWidgetItem *trackerItem {nullptr};
if (exists)
{
tmp = m_trackers.value(host);
if (tmp.contains(hash))
if (m_trackers.value(host).contains(hash))
return;
if (host != "")
{
trackerItem = item(rowFromTracker(host));
}
else
{
trackerItem = item(TRACKERLESS_ROW);
}
trackerItem = item((host == NULL_HOST)
? TRACKERLESS_ROW
: rowFromTracker(host));
}
else
{
@ -338,17 +346,18 @@ void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
}
if (!trackerItem) return;
tmp.append(hash);
m_trackers.insert(host, tmp);
if (host == "")
QSet<BitTorrent::InfoHash> &hashes {m_trackers[host]};
hashes.insert(hash);
if (host == NULL_HOST)
{
trackerItem->setText(tr("Trackerless (%1)").arg(tmp.size()));
trackerItem->setText(tr("Trackerless (%1)").arg(hashes.size()));
if (currentRow() == TRACKERLESS_ROW)
applyFilter(TRACKERLESS_ROW);
return;
}
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(tmp.size())));
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(hashes.size())));
if (exists)
{
if (currentRow() == rowFromTracker(host))
@ -370,16 +379,17 @@ void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
updateGeometry();
}
void TrackerFiltersList::removeItem(const QString &tracker, const QString &hash)
void TrackerFiltersList::removeItem(const QString &tracker, const BitTorrent::InfoHash &hash)
{
QString host = getHost(tracker);
QListWidgetItem *trackerItem = nullptr;
QStringList tmp = m_trackers.value(host);
int row = 0;
const QString host = getHost(tracker);
QSet<BitTorrent::InfoHash> hashes = m_trackers.value(host);
if (tmp.empty())
if (hashes.empty())
return;
tmp.removeAll(hash);
hashes.remove(hash);
int row = 0;
QListWidgetItem *trackerItem = nullptr;
if (!host.isEmpty())
{
@ -387,7 +397,8 @@ void TrackerFiltersList::removeItem(const QString &tracker, const QString &hash)
trackerSuccess(hash, tracker);
row = rowFromTracker(host);
trackerItem = item(row);
if (tmp.empty())
if (hashes.empty())
{
if (currentRow() == row)
setCurrentRow(0, QItemSelectionModel::SelectCurrent);
@ -396,27 +407,29 @@ void TrackerFiltersList::removeItem(const QString &tracker, const QString &hash)
updateGeometry();
return;
}
if (trackerItem)
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(tmp.size())));
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(hashes.size())));
}
else
{
row = 1;
trackerItem = item(TRACKERLESS_ROW);
trackerItem->setText(tr("Trackerless (%1)").arg(tmp.size()));
trackerItem->setText(tr("Trackerless (%1)").arg(hashes.size()));
}
m_trackers.insert(host, tmp);
m_trackers.insert(host, hashes);
if (currentRow() == row)
applyFilter(row);
}
void TrackerFiltersList::changeTrackerless(bool trackerless, const QString &hash)
void TrackerFiltersList::changeTrackerless(const bool trackerless, const BitTorrent::InfoHash &hash)
{
if (trackerless)
addItem("", hash);
addItem(NULL_HOST, hash);
else
removeItem("", hash);
removeItem(NULL_HOST, hash);
}
void TrackerFiltersList::setDownloadTrackerFavicon(bool value)
@ -439,70 +452,57 @@ void TrackerFiltersList::setDownloadTrackerFavicon(bool value)
}
}
void TrackerFiltersList::trackerSuccess(const QString &hash, const QString &tracker)
void TrackerFiltersList::trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker)
{
QStringList errored = m_errors.value(hash);
QStringList warned = m_warnings.value(hash);
if (errored.contains(tracker))
const auto errorHashesIter = m_errors.find(hash);
if (errorHashesIter != m_errors.end())
{
errored.removeAll(tracker);
QSet<QString> &errored = *errorHashesIter;
errored.remove(tracker);
if (errored.empty())
{
m_errors.remove(hash);
m_errors.erase(errorHashesIter);
item(ERROR_ROW)->setText(tr("Error (%1)").arg(m_errors.size()));
if (currentRow() == ERROR_ROW)
applyFilter(ERROR_ROW);
}
else
{
m_errors.insert(hash, errored);
}
}
if (warned.contains(tracker))
const auto warningHashesIter = m_warnings.find(hash);
if (warningHashesIter != m_warnings.end())
{
warned.removeAll(tracker);
QSet<QString> &warned = *warningHashesIter;
warned.remove(tracker);
if (warned.empty())
{
m_warnings.remove(hash);
m_warnings.erase(warningHashesIter);
item(WARNING_ROW)->setText(tr("Warning (%1)").arg(m_warnings.size()));
if (currentRow() == WARNING_ROW)
applyFilter(WARNING_ROW);
}
else
{
m_warnings.insert(hash, warned);
}
}
}
void TrackerFiltersList::trackerError(const QString &hash, const QString &tracker)
void TrackerFiltersList::trackerError(const BitTorrent::InfoHash &hash, const QString &tracker)
{
QStringList trackers = m_errors.value(hash);
QSet<QString> &trackers {m_errors[hash]};
if (trackers.contains(tracker))
return;
trackers.append(tracker);
m_errors.insert(hash, trackers);
trackers.insert(tracker);
item(ERROR_ROW)->setText(tr("Error (%1)").arg(m_errors.size()));
if (currentRow() == ERROR_ROW)
applyFilter(ERROR_ROW);
}
void TrackerFiltersList::trackerWarning(const QString &hash, const QString &tracker)
void TrackerFiltersList::trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker)
{
QStringList trackers = m_warnings.value(hash);
QSet<QString> &trackers {m_warnings[hash]};
if (trackers.contains(tracker))
return;
trackers.append(tracker);
m_warnings.insert(hash, trackers);
trackers.insert(tracker);
item(WARNING_ROW)->setText(tr("Warning (%1)").arg(m_warnings.size()));
if (currentRow() == WARNING_ROW)
applyFilter(WARNING_ROW);
}
@ -574,33 +574,33 @@ void TrackerFiltersList::applyFilter(const int row)
if (row == ALL_ROW)
transferList->applyTrackerFilterAll();
else if (isVisible())
transferList->applyTrackerFilter(getHashes(row));
transferList->applyTrackerFilter(getInfoHashes(row));
}
void TrackerFiltersList::handleNewTorrent(BitTorrent::TorrentHandle *const torrent)
{
QString hash = torrent->hash();
const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
const BitTorrent::InfoHash hash {torrent->hash()};
const QVector<BitTorrent::TrackerEntry> trackers {torrent->trackers()};
for (const BitTorrent::TrackerEntry &tracker : trackers)
addItem(tracker.url(), hash);
//Check for trackerless torrent
// Check for trackerless torrent
if (trackers.isEmpty())
addItem("", hash);
addItem(NULL_HOST, hash);
item(ALL_ROW)->setText(tr("All (%1)", "this is for the tracker filter").arg(++m_totalTorrents));
}
void TrackerFiltersList::torrentAboutToBeDeleted(BitTorrent::TorrentHandle *const torrent)
{
QString hash = torrent->hash();
const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
const BitTorrent::InfoHash hash {torrent->hash()};
const QVector<BitTorrent::TrackerEntry> trackers {torrent->trackers()};
for (const BitTorrent::TrackerEntry &tracker : trackers)
removeItem(tracker.url(), hash);
//Check for trackerless torrent
// Check for trackerless torrent
if (trackers.isEmpty())
removeItem("", hash);
removeItem(NULL_HOST, hash);
item(ALL_ROW)->setText(tr("All (%1)", "this is for the tracker filter").arg(--m_totalTorrents));
}
@ -618,34 +618,24 @@ QString TrackerFiltersList::trackerFromRow(int row) const
int TrackerFiltersList::rowFromTracker(const QString &tracker) const
{
Q_ASSERT(!tracker.isEmpty());
for (int i = 4; i<count(); ++i)
if (tracker == trackerFromRow(i)) return i;
for (int i = 4; i < count(); ++i)
{
if (tracker == trackerFromRow(i))
return i;
}
return -1;
}
QString TrackerFiltersList::getHost(const QString &tracker) const
{
// We want the domain + tld. Subdomains should be disregarded
const QUrl url {tracker};
const QString host {url.host()};
// host is in IP format
if (!QHostAddress(host).isNull())
return host;
return host.section('.', -2, -1);
}
QStringList TrackerFiltersList::getHashes(const int row) const
QSet<BitTorrent::InfoHash> TrackerFiltersList::getInfoHashes(const int row) const
{
switch (row)
{
case TRACKERLESS_ROW:
return m_trackers.value("");
return m_trackers.value(NULL_HOST);
case ERROR_ROW:
return m_errors.keys();
return List::toSet(m_errors.keys());
case WARNING_ROW:
return m_warnings.keys();
return List::toSet(m_warnings.keys());
default:
return m_trackers.value(trackerFromRow(row));
}
@ -739,11 +729,11 @@ TransferListFiltersWidget::TransferListFiltersWidget(QWidget *parent, TransferLi
connect(trackerLabel, &QCheckBox::toggled, m_trackerFilters, &TrackerFiltersList::toggleFilter);
connect(trackerLabel, &QCheckBox::toggled, pref, &Preferences::setTrackerFilterState);
connect(this, qOverload<const QString &, const QString &>(&TransferListFiltersWidget::trackerSuccess)
connect(this, qOverload<const BitTorrent::InfoHash &, const QString &>(&TransferListFiltersWidget::trackerSuccess)
, m_trackerFilters, &TrackerFiltersList::trackerSuccess);
connect(this, qOverload<const QString &, const QString &>(&TransferListFiltersWidget::trackerError)
connect(this, qOverload<const BitTorrent::InfoHash &, const QString &>(&TransferListFiltersWidget::trackerError)
, m_trackerFilters, &TrackerFiltersList::trackerError);
connect(this, qOverload<const QString &, const QString &>(&TransferListFiltersWidget::trackerWarning)
connect(this, qOverload<const BitTorrent::InfoHash &, const QString &>(&TransferListFiltersWidget::trackerWarning)
, m_trackerFilters, &TrackerFiltersList::trackerWarning);
}
@ -752,34 +742,34 @@ void TransferListFiltersWidget::setDownloadTrackerFavicon(bool value)
m_trackerFilters->setDownloadTrackerFavicon(value);
}
void TransferListFiltersWidget::addTrackers(BitTorrent::TorrentHandle *const torrent, const QVector<BitTorrent::TrackerEntry> &trackers)
void TransferListFiltersWidget::addTrackers(const BitTorrent::TorrentHandle *torrent, const QVector<BitTorrent::TrackerEntry> &trackers)
{
for (const BitTorrent::TrackerEntry &tracker : trackers)
m_trackerFilters->addItem(tracker.url(), torrent->hash());
}
void TransferListFiltersWidget::removeTrackers(BitTorrent::TorrentHandle *const torrent, const QVector<BitTorrent::TrackerEntry> &trackers)
void TransferListFiltersWidget::removeTrackers(const BitTorrent::TorrentHandle *torrent, const QVector<BitTorrent::TrackerEntry> &trackers)
{
for (const BitTorrent::TrackerEntry &tracker : trackers)
m_trackerFilters->removeItem(tracker.url(), torrent->hash());
}
void TransferListFiltersWidget::changeTrackerless(BitTorrent::TorrentHandle *const torrent, bool trackerless)
void TransferListFiltersWidget::changeTrackerless(const BitTorrent::TorrentHandle *torrent, const bool trackerless)
{
m_trackerFilters->changeTrackerless(trackerless, torrent->hash());
}
void TransferListFiltersWidget::trackerSuccess(BitTorrent::TorrentHandle *const torrent, const QString &tracker)
void TransferListFiltersWidget::trackerSuccess(const BitTorrent::TorrentHandle *torrent, const QString &tracker)
{
emit trackerSuccess(torrent->hash(), tracker);
}
void TransferListFiltersWidget::trackerWarning(BitTorrent::TorrentHandle *const torrent, const QString &tracker)
void TransferListFiltersWidget::trackerWarning(const BitTorrent::TorrentHandle *torrent, const QString &tracker)
{
emit trackerWarning(torrent->hash(), tracker);
}
void TransferListFiltersWidget::trackerError(BitTorrent::TorrentHandle *const torrent, const QString &tracker)
void TransferListFiltersWidget::trackerError(const BitTorrent::TorrentHandle *torrent, const QString &tracker)
{
emit trackerError(torrent->hash(), tracker);
}

View file

@ -31,6 +31,7 @@
#include <QFrame>
#include <QListWidget>
#include <QtContainerFwd>
class QCheckBox;
class QResizeEvent;
@ -39,6 +40,7 @@ class TransferListWidget;
namespace BitTorrent
{
class InfoHash;
class TorrentHandle;
class TrackerEntry;
}
@ -103,15 +105,15 @@ public:
~TrackerFiltersList() override;
// Redefine addItem() to make sure the list stays sorted
void addItem(const QString &tracker, const QString &hash);
void removeItem(const QString &tracker, const QString &hash);
void changeTrackerless(bool trackerless, const QString &hash);
void addItem(const QString &tracker, const BitTorrent::InfoHash &hash);
void removeItem(const QString &tracker, const BitTorrent::InfoHash &hash);
void changeTrackerless(bool trackerless, const BitTorrent::InfoHash &hash);
void setDownloadTrackerFavicon(bool value);
public slots:
void trackerSuccess(const QString &hash, const QString &tracker);
void trackerError(const QString &hash, const QString &tracker);
void trackerWarning(const QString &hash, const QString &tracker);
void trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker);
void trackerError(const BitTorrent::InfoHash &hash, const QString &tracker);
void trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker);
private slots:
void handleFavicoDownloadFinished(const Net::DownloadResult &result);
@ -125,13 +127,12 @@ private:
void torrentAboutToBeDeleted(BitTorrent::TorrentHandle *const torrent) override;
QString trackerFromRow(int row) const;
int rowFromTracker(const QString &tracker) const;
QString getHost(const QString &tracker) const;
QStringList getHashes(int row) const;
QSet<BitTorrent::InfoHash> getInfoHashes(int row) const;
void downloadFavicon(const QString &url);
QHash<QString, QStringList> m_trackers;
QHash<QString, QStringList> m_errors;
QHash<QString, QStringList> m_warnings;
QHash<QString, QSet<BitTorrent::InfoHash>> m_trackers; // <tracker host, torrent hashes>
QHash<BitTorrent::InfoHash, QSet<QString>> m_errors; // <torrent hash, tracker hosts>
QHash<BitTorrent::InfoHash, QSet<QString>> m_warnings; // <torrent hash, tracker hosts>
QStringList m_iconPaths;
int m_totalTorrents;
bool m_downloadTrackerFavicon;
@ -140,26 +141,27 @@ private:
class CategoryFilterWidget;
class TagFilterWidget;
class TransferListFiltersWidget : public QFrame
class TransferListFiltersWidget final : public QFrame
{
Q_OBJECT
Q_DISABLE_COPY(TransferListFiltersWidget)
public:
TransferListFiltersWidget(QWidget *parent, TransferListWidget *transferList, bool downloadFavicon);
void setDownloadTrackerFavicon(bool value);
public slots:
void addTrackers(BitTorrent::TorrentHandle *const torrent, const QVector<BitTorrent::TrackerEntry> &trackers);
void removeTrackers(BitTorrent::TorrentHandle *const torrent, const QVector<BitTorrent::TrackerEntry> &trackers);
void changeTrackerless(BitTorrent::TorrentHandle *const torrent, bool trackerless);
void trackerSuccess(BitTorrent::TorrentHandle *const torrent, const QString &tracker);
void trackerWarning(BitTorrent::TorrentHandle *const torrent, const QString &tracker);
void trackerError(BitTorrent::TorrentHandle *const torrent, const QString &tracker);
void addTrackers(const BitTorrent::TorrentHandle *torrent, const QVector<BitTorrent::TrackerEntry> &trackers);
void removeTrackers(const BitTorrent::TorrentHandle *torrent, const QVector<BitTorrent::TrackerEntry> &trackers);
void changeTrackerless(const BitTorrent::TorrentHandle *torrent, bool trackerless);
void trackerSuccess(const BitTorrent::TorrentHandle *torrent, const QString &tracker);
void trackerWarning(const BitTorrent::TorrentHandle *torrent, const QString &tracker);
void trackerError(const BitTorrent::TorrentHandle *torrent, const QString &tracker);
signals:
void trackerSuccess(const QString &hash, const QString &tracker);
void trackerError(const QString &hash, const QString &tracker);
void trackerWarning(const QString &hash, const QString &tracker);
void trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker);
void trackerError(const BitTorrent::InfoHash &hash, const QString &tracker);
void trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker);
private slots:
void onCategoryFilterStateChanged(bool enabled);

View file

@ -29,7 +29,6 @@
#include "transferlistsortmodel.h"
#include <QDateTime>
#include <QStringList>
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/torrenthandle.h"
@ -75,9 +74,9 @@ void TransferListSortModel::disableTagFilter()
invalidateFilter();
}
void TransferListSortModel::setTrackerFilter(const QStringList &hashes)
void TransferListSortModel::setTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes)
{
if (m_filter.setHashSet(List::toSet(hashes)))
if (m_filter.setHashSet(hashes))
invalidateFilter();
}

View file

@ -31,7 +31,10 @@
#include <QSortFilterProxyModel>
#include "base/torrentfilter.h"
class QStringList;
namespace BitTorrent
{
class InfoHash;
}
class TransferListSortModel final : public QSortFilterProxyModel
{
@ -46,7 +49,7 @@ public:
void disableCategoryFilter();
void setTagFilter(const QString &tag);
void disableTagFilter();
void setTrackerFilter(const QStringList &hashes);
void setTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes);
void disableTrackerFilter();
private:

View file

@ -41,6 +41,7 @@
#include <QSet>
#include <QShortcut>
#include <QTableView>
#include <QVector>
#include <QWheelEvent>
#include "base/bittorrent/infohash.h"
@ -1226,7 +1227,7 @@ void TransferListWidget::applyTrackerFilterAll()
m_sortFilterModel->disableTrackerFilter();
}
void TransferListWidget::applyTrackerFilter(const QStringList &hashes)
void TransferListWidget::applyTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes)
{
m_sortFilterModel->setTrackerFilter(hashes);
}

View file

@ -30,8 +30,8 @@
#define TRANSFERLISTWIDGET_H
#include <functional>
#include <QtContainerFwd>
#include <QTreeView>
#include <QVector>
class MainWindow;
class TransferListDelegate;
@ -40,6 +40,7 @@ class TransferListSortModel;
namespace BitTorrent
{
class InfoHash;
class TorrentHandle;
}
@ -90,7 +91,7 @@ public slots:
void applyCategoryFilter(const QString &category);
void applyTagFilter(const QString &tag);
void applyTrackerFilterAll();
void applyTrackerFilter(const QStringList &hashes);
void applyTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes);
void previewFile(const QString &filePath);
void renameSelectedTorrent();

View file

@ -256,10 +256,14 @@ void TorrentsController::infoAction()
const bool reverse {parseBool(params()["reverse"], false)};
int limit {params()["limit"].toInt()};
int offset {params()["offset"].toInt()};
const QStringSet hashSet {List::toSet(params()["hashes"].split('|', QString::SkipEmptyParts))};
const QStringList hashes {params()["hashes"].split('|', QString::SkipEmptyParts)};
InfoHashSet hashSet;
for (const QString &hash : hashes)
hashSet.insert(BitTorrent::InfoHash {hash});
QVariantList torrentList;
TorrentFilter torrentFilter(filter, (hashSet.isEmpty() ? TorrentFilter::AnyHash : hashSet), category);
TorrentFilter torrentFilter(filter, (hashes.isEmpty() ? TorrentFilter::AnyHash : hashSet), category);
for (BitTorrent::TorrentHandle *const torrent : asConst(BitTorrent::Session::instance()->torrents()))
{
if (torrentFilter.match(torrent))