|
|
|
@ -29,9 +29,11 @@
@@ -29,9 +29,11 @@
|
|
|
|
|
|
|
|
|
|
#include "trackersfilterwidget.h" |
|
|
|
|
|
|
|
|
|
#include <QCheckBox> |
|
|
|
|
#include <QIcon> |
|
|
|
|
#include <QListWidgetItem> |
|
|
|
|
#include <QMenu> |
|
|
|
|
#include <QMessageBox> |
|
|
|
|
#include <QUrl> |
|
|
|
|
|
|
|
|
|
#include "base/algorithm.h" |
|
|
|
@ -54,7 +56,7 @@ namespace
@@ -54,7 +56,7 @@ namespace
|
|
|
|
|
OTHERERROR_ROW, |
|
|
|
|
WARNING_ROW, |
|
|
|
|
|
|
|
|
|
NUM_ROWS |
|
|
|
|
NUM_SPECIAL_ROWS |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const QString NULL_HOST = u""_s; |
|
|
|
@ -262,10 +264,10 @@ void TrackersFilterWidget::addItems(const QString &trackerURL, const QVector<Bit
@@ -262,10 +264,10 @@ void TrackersFilterWidget::addItems(const QString &trackerURL, const QVector<Bit
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Q_ASSERT(count() >= NUM_ROWS); |
|
|
|
|
Q_ASSERT(count() >= NUM_SPECIAL_ROWS); |
|
|
|
|
const Utils::Compare::NaturalLessThan<Qt::CaseSensitive> naturalLessThan {}; |
|
|
|
|
int insPos = count(); |
|
|
|
|
for (int i = NUM_ROWS; i < count(); ++i) |
|
|
|
|
for (int i = NUM_SPECIAL_ROWS; i < count(); ++i) |
|
|
|
|
{ |
|
|
|
|
if (naturalLessThan(host, item(i)->text())) |
|
|
|
|
{ |
|
|
|
@ -469,6 +471,28 @@ void TrackersFilterWidget::downloadFavicon(const QString &trackerHost, const QSt
@@ -469,6 +471,28 @@ void TrackersFilterWidget::downloadFavicon(const QString &trackerHost, const QSt
|
|
|
|
|
downloadingFaviconNode.insert(trackerHost); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TrackersFilterWidget::removeTracker(const QString &tracker) |
|
|
|
|
{ |
|
|
|
|
for (const BitTorrent::TorrentID &torrentID : asConst(m_trackers.value(tracker).torrents)) |
|
|
|
|
{ |
|
|
|
|
auto *torrent = BitTorrent::Session::instance()->getTorrent(torrentID); |
|
|
|
|
Q_ASSERT(torrent); |
|
|
|
|
if (!torrent) [[unlikely]] |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
QStringList trackersToRemove; |
|
|
|
|
for (const BitTorrent::TrackerEntry &trackerEntry : asConst(torrent->trackers())) |
|
|
|
|
{ |
|
|
|
|
if ((trackerEntry.url == tracker) || (QUrl(trackerEntry.url).host() == tracker)) |
|
|
|
|
trackersToRemove.append(trackerEntry.url); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
torrent->removeTrackers({trackersToRemove}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
updateGeometry(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TrackersFilterWidget::handleFavicoDownloadFinished(const Net::DownloadResult &result) |
|
|
|
|
{ |
|
|
|
|
const QSet<QString> trackerHosts = m_downloadingFavicons.take(result.url); |
|
|
|
@ -537,6 +561,13 @@ void TrackersFilterWidget::showMenu()
@@ -537,6 +561,13 @@ void TrackersFilterWidget::showMenu()
|
|
|
|
|
QMenu *menu = new QMenu(this); |
|
|
|
|
menu->setAttribute(Qt::WA_DeleteOnClose); |
|
|
|
|
|
|
|
|
|
if (currentRow() >= NUM_SPECIAL_ROWS) |
|
|
|
|
{ |
|
|
|
|
menu->addAction(UIThemeManager::instance()->getIcon(u"edit-clear"_s, u"list-remove"_s), tr("Remove tracker") |
|
|
|
|
, this, &TrackersFilterWidget::onRemoveTrackerTriggered); |
|
|
|
|
menu->addSeparator(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
menu->addAction(UIThemeManager::instance()->getIcon(u"torrent-start"_s, u"media-playback-start"_s), tr("Resume torrents") |
|
|
|
|
, transferList(), &TransferListWidget::startVisibleTorrents); |
|
|
|
|
menu->addAction(UIThemeManager::instance()->getIcon(u"torrent-stop"_s, u"media-playback-pause"_s), tr("Pause torrents") |
|
|
|
@ -593,6 +624,34 @@ void TrackersFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const to
@@ -593,6 +624,34 @@ void TrackersFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const to
|
|
|
|
|
item(ALL_ROW)->setText(formatItemText(ALL_ROW, --m_totalTorrents)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TrackersFilterWidget::onRemoveTrackerTriggered() |
|
|
|
|
{ |
|
|
|
|
const int row = currentRow(); |
|
|
|
|
if (row < NUM_SPECIAL_ROWS) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
const QString &tracker = trackerFromRow(row); |
|
|
|
|
if (!Preferences::instance()->confirmRemoveTrackerFromAllTorrents()) |
|
|
|
|
{ |
|
|
|
|
removeTracker(tracker); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto *confirmBox = new QMessageBox(QMessageBox::Question, tr("Removal confirmation") |
|
|
|
|
, tr("Are you sure you want to remove tracker \"%1\" from all torrents?").arg(tracker) |
|
|
|
|
, (QMessageBox::Yes | QMessageBox::No), this); |
|
|
|
|
confirmBox->setCheckBox(new QCheckBox(tr("Don't ask me again."))); |
|
|
|
|
confirmBox->setAttribute(Qt::WA_DeleteOnClose); |
|
|
|
|
connect(confirmBox, &QDialog::accepted, this, [this, confirmBox, tracker] |
|
|
|
|
{ |
|
|
|
|
removeTracker(tracker); |
|
|
|
|
|
|
|
|
|
if (confirmBox->checkBox()->isChecked()) |
|
|
|
|
Preferences::instance()->setConfirmRemoveTrackerFromAllTorrents(false); |
|
|
|
|
}); |
|
|
|
|
confirmBox->open(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString TrackersFilterWidget::trackerFromRow(int row) const |
|
|
|
|
{ |
|
|
|
|
Q_ASSERT(row > 1); |
|
|
|
@ -606,7 +665,7 @@ QString TrackersFilterWidget::trackerFromRow(int row) const
@@ -606,7 +665,7 @@ QString TrackersFilterWidget::trackerFromRow(int row) const
|
|
|
|
|
int TrackersFilterWidget::rowFromTracker(const QString &tracker) const |
|
|
|
|
{ |
|
|
|
|
Q_ASSERT(!tracker.isEmpty()); |
|
|
|
|
for (int i = NUM_ROWS; i < count(); ++i) |
|
|
|
|
for (int i = NUM_SPECIAL_ROWS; i < count(); ++i) |
|
|
|
|
{ |
|
|
|
|
if (tracker == trackerFromRow(i)) |
|
|
|
|
return i; |
|
|
|
|