|
|
|
@ -54,6 +54,8 @@
@@ -54,6 +54,8 @@
|
|
|
|
|
#include "propertieswidget.h" |
|
|
|
|
#include "trackersadditiondialog.h" |
|
|
|
|
|
|
|
|
|
#define NB_STICKY_ITEM 3 |
|
|
|
|
|
|
|
|
|
TrackerListWidget::TrackerListWidget(PropertiesWidget *properties) |
|
|
|
|
: QTreeWidget() |
|
|
|
|
, m_properties(properties) |
|
|
|
@ -87,6 +89,7 @@ TrackerListWidget::TrackerListWidget(PropertiesWidget *properties)
@@ -87,6 +89,7 @@ TrackerListWidget::TrackerListWidget(PropertiesWidget *properties)
|
|
|
|
|
connect(header(), &QHeaderView::sectionMoved, this, &TrackerListWidget::saveSettings); |
|
|
|
|
connect(header(), &QHeaderView::sectionResized, this, &TrackerListWidget::saveSettings); |
|
|
|
|
connect(header(), &QHeaderView::sortIndicatorChanged, this, &TrackerListWidget::saveSettings); |
|
|
|
|
|
|
|
|
|
// Set DHT, PeX, LSD items
|
|
|
|
|
m_DHTItem = new QTreeWidgetItem({ "", "** [DHT] **", "", "0", "", "", "0" }); |
|
|
|
|
insertTopLevelItem(0, m_DHTItem); |
|
|
|
@ -97,33 +100,38 @@ TrackerListWidget::TrackerListWidget(PropertiesWidget *properties)
@@ -97,33 +100,38 @@ TrackerListWidget::TrackerListWidget(PropertiesWidget *properties)
|
|
|
|
|
m_LSDItem = new QTreeWidgetItem({ "", "** [LSD] **", "", "0", "", "", "0" }); |
|
|
|
|
insertTopLevelItem(2, m_LSDItem); |
|
|
|
|
setRowColor(2, QColor("grey")); |
|
|
|
|
|
|
|
|
|
// Set static items alignment
|
|
|
|
|
m_DHTItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_DHTItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_DHTItem->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_DHTItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
const Qt::Alignment alignment = (Qt::AlignRight | Qt::AlignVCenter); |
|
|
|
|
m_DHTItem->setTextAlignment(COL_PEERS, alignment); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_PEERS, alignment); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_PEERS, alignment); |
|
|
|
|
m_DHTItem->setTextAlignment(COL_SEEDS, alignment); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_SEEDS, alignment); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_SEEDS, alignment); |
|
|
|
|
m_DHTItem->setTextAlignment(COL_LEECHES, alignment); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_LEECHES, alignment); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_LEECHES, alignment); |
|
|
|
|
m_DHTItem->setTextAlignment(COL_DOWNLOADED, alignment); |
|
|
|
|
m_PEXItem->setTextAlignment(COL_DOWNLOADED, alignment); |
|
|
|
|
m_LSDItem->setTextAlignment(COL_DOWNLOADED, alignment); |
|
|
|
|
|
|
|
|
|
// Set header alignment
|
|
|
|
|
headerItem()->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
headerItem()->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
headerItem()->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
headerItem()->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
headerItem()->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
headerItem()->setTextAlignment(COL_TIER, alignment); |
|
|
|
|
headerItem()->setTextAlignment(COL_PEERS, alignment); |
|
|
|
|
headerItem()->setTextAlignment(COL_SEEDS, alignment); |
|
|
|
|
headerItem()->setTextAlignment(COL_LEECHES, alignment); |
|
|
|
|
headerItem()->setTextAlignment(COL_DOWNLOADED, alignment); |
|
|
|
|
|
|
|
|
|
// Set hotkeys
|
|
|
|
|
m_editHotkey = new QShortcut(Qt::Key_F2, this, nullptr, nullptr, Qt::WidgetShortcut); |
|
|
|
|
connect(m_editHotkey, &QShortcut::activated, this, &TrackerListWidget::editSelectedTracker); |
|
|
|
|
const auto *editHotkey = new QShortcut(Qt::Key_F2, this, nullptr, nullptr, Qt::WidgetShortcut); |
|
|
|
|
connect(editHotkey, &QShortcut::activated, this, &TrackerListWidget::editSelectedTracker); |
|
|
|
|
const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, this, nullptr, nullptr, Qt::WidgetShortcut); |
|
|
|
|
connect(deleteHotkey, &QShortcut::activated, this, &TrackerListWidget::deleteSelectedTrackers); |
|
|
|
|
const auto *copyHotkey = new QShortcut(QKeySequence::Copy, this, nullptr, nullptr, Qt::WidgetShortcut); |
|
|
|
|
connect(copyHotkey, &QShortcut::activated, this, &TrackerListWidget::copyTrackerUrl); |
|
|
|
|
|
|
|
|
|
connect(this, &QAbstractItemView::doubleClicked, this, &TrackerListWidget::editSelectedTracker); |
|
|
|
|
m_deleteHotkey = new QShortcut(QKeySequence::Delete, this, nullptr, nullptr, Qt::WidgetShortcut); |
|
|
|
|
connect(m_deleteHotkey, &QShortcut::activated, this, &TrackerListWidget::deleteSelectedTrackers); |
|
|
|
|
m_copyHotkey = new QShortcut(QKeySequence::Copy, this, nullptr, nullptr, Qt::WidgetShortcut); |
|
|
|
|
connect(m_copyHotkey, &QShortcut::activated, this, &TrackerListWidget::copyTrackerUrl); |
|
|
|
|
|
|
|
|
|
// This hack fixes reordering of first column with Qt5.
|
|
|
|
|
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
|
|
|
@ -138,10 +146,12 @@ TrackerListWidget::~TrackerListWidget()
@@ -138,10 +146,12 @@ TrackerListWidget::~TrackerListWidget()
|
|
|
|
|
saveSettings(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QList<QTreeWidgetItem*> TrackerListWidget::getSelectedTrackerItems() const |
|
|
|
|
QVector<QTreeWidgetItem *> TrackerListWidget::getSelectedTrackerItems() const |
|
|
|
|
{ |
|
|
|
|
const QList<QTreeWidgetItem *> selectedTrackerItems = selectedItems(); |
|
|
|
|
QList<QTreeWidgetItem *> selectedTrackers; |
|
|
|
|
QVector<QTreeWidgetItem *> selectedTrackers; |
|
|
|
|
selectedTrackers.reserve(selectedTrackerItems.size()); |
|
|
|
|
|
|
|
|
|
for (QTreeWidgetItem *item : selectedTrackerItems) { |
|
|
|
|
if (indexOfTopLevelItem(item) >= NB_STICKY_ITEM) // Ignore STICKY ITEMS
|
|
|
|
|
selectedTrackers << item; |
|
|
|
@ -165,7 +175,7 @@ void TrackerListWidget::moveSelectionUp()
@@ -165,7 +175,7 @@ void TrackerListWidget::moveSelectionUp()
|
|
|
|
|
clear(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
const QVector<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
if (selectedTrackerItems.isEmpty()) return; |
|
|
|
|
|
|
|
|
|
bool change = false; |
|
|
|
@ -207,7 +217,7 @@ void TrackerListWidget::moveSelectionDown()
@@ -207,7 +217,7 @@ void TrackerListWidget::moveSelectionDown()
|
|
|
|
|
clear(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
const QVector<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
if (selectedTrackerItems.isEmpty()) return; |
|
|
|
|
|
|
|
|
|
bool change = false; |
|
|
|
@ -246,6 +256,7 @@ void TrackerListWidget::clear()
@@ -246,6 +256,7 @@ void TrackerListWidget::clear()
|
|
|
|
|
{ |
|
|
|
|
qDeleteAll(m_trackerItems); |
|
|
|
|
m_trackerItems.clear(); |
|
|
|
|
|
|
|
|
|
m_DHTItem->setText(COL_STATUS, ""); |
|
|
|
|
m_DHTItem->setText(COL_SEEDS, ""); |
|
|
|
|
m_DHTItem->setText(COL_LEECHES, ""); |
|
|
|
@ -260,7 +271,7 @@ void TrackerListWidget::clear()
@@ -260,7 +271,7 @@ void TrackerListWidget::clear()
|
|
|
|
|
m_LSDItem->setText(COL_MSG, ""); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TrackerListWidget::loadStickyItems(BitTorrent::TorrentHandle *const torrent) |
|
|
|
|
void TrackerListWidget::loadStickyItems(const BitTorrent::TorrentHandle *torrent) |
|
|
|
|
{ |
|
|
|
|
QString working = tr("Working"); |
|
|
|
|
QString disabled = tr("Disabled"); |
|
|
|
@ -327,16 +338,18 @@ void TrackerListWidget::loadStickyItems(BitTorrent::TorrentHandle *const torrent
@@ -327,16 +338,18 @@ void TrackerListWidget::loadStickyItems(BitTorrent::TorrentHandle *const torrent
|
|
|
|
|
void TrackerListWidget::loadTrackers() |
|
|
|
|
{ |
|
|
|
|
// Load trackers from torrent handle
|
|
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
|
const BitTorrent::TorrentHandle *torrent = m_properties->getCurrentTorrent(); |
|
|
|
|
if (!torrent) return; |
|
|
|
|
|
|
|
|
|
loadStickyItems(torrent); |
|
|
|
|
|
|
|
|
|
// Load actual trackers information
|
|
|
|
|
QHash<QString, BitTorrent::TrackerInfo> trackerData = torrent->trackerInfos(); |
|
|
|
|
const QHash<QString, BitTorrent::TrackerInfo> trackerData = torrent->trackerInfos(); |
|
|
|
|
QStringList oldTrackerURLs = m_trackerItems.keys(); |
|
|
|
|
|
|
|
|
|
for (const BitTorrent::TrackerEntry &entry : asConst(torrent->trackers())) { |
|
|
|
|
QString trackerURL = entry.url(); |
|
|
|
|
const QString trackerURL = entry.url(); |
|
|
|
|
|
|
|
|
|
QTreeWidgetItem *item = m_trackerItems.value(trackerURL, nullptr); |
|
|
|
|
if (!item) { |
|
|
|
|
item = new QTreeWidgetItem(); |
|
|
|
@ -347,9 +360,11 @@ void TrackerListWidget::loadTrackers()
@@ -347,9 +360,11 @@ void TrackerListWidget::loadTrackers()
|
|
|
|
|
else { |
|
|
|
|
oldTrackerURLs.removeOne(trackerURL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
item->setText(COL_TIER, QString::number(entry.tier())); |
|
|
|
|
BitTorrent::TrackerInfo data = trackerData.value(trackerURL); |
|
|
|
|
QString errorMessage = data.lastMessage.trimmed(); |
|
|
|
|
|
|
|
|
|
const BitTorrent::TrackerInfo data = trackerData.value(trackerURL); |
|
|
|
|
|
|
|
|
|
switch (entry.status()) { |
|
|
|
|
case BitTorrent::TrackerEntry::Working: |
|
|
|
|
item->setText(COL_STATUS, tr("Working")); |
|
|
|
@ -361,7 +376,7 @@ void TrackerListWidget::loadTrackers()
@@ -361,7 +376,7 @@ void TrackerListWidget::loadTrackers()
|
|
|
|
|
break; |
|
|
|
|
case BitTorrent::TrackerEntry::NotWorking: |
|
|
|
|
item->setText(COL_STATUS, tr("Not working")); |
|
|
|
|
item->setText(COL_MSG, errorMessage); |
|
|
|
|
item->setText(COL_MSG, data.lastMessage.trimmed()); |
|
|
|
|
break; |
|
|
|
|
case BitTorrent::TrackerEntry::NotContacted: |
|
|
|
|
item->setText(COL_STATUS, tr("Not contacted yet")); |
|
|
|
@ -370,16 +385,24 @@ void TrackerListWidget::loadTrackers()
@@ -370,16 +385,24 @@ void TrackerListWidget::loadTrackers()
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
item->setText(COL_PEERS, QString::number(data.numPeers)); |
|
|
|
|
item->setText(COL_SEEDS, (entry.numSeeds() > -1) ? QString::number(entry.numSeeds()) : tr("N/A")); |
|
|
|
|
item->setText(COL_LEECHES, (entry.numLeeches() > -1) ? QString::number(entry.numLeeches()) : tr("N/A")); |
|
|
|
|
item->setText(COL_DOWNLOADED, (entry.numDownloaded() > -1) ? QString::number(entry.numDownloaded()) : tr("N/A")); |
|
|
|
|
|
|
|
|
|
item->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
item->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
item->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
item->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
item->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
item->setText(COL_SEEDS, ((entry.numSeeds() > -1) |
|
|
|
|
? QString::number(entry.numSeeds()) |
|
|
|
|
: tr("N/A"))); |
|
|
|
|
item->setText(COL_LEECHES, ((entry.numLeeches() > -1) |
|
|
|
|
? QString::number(entry.numLeeches()) |
|
|
|
|
: tr("N/A"))); |
|
|
|
|
item->setText(COL_DOWNLOADED, ((entry.numDownloaded() > -1) |
|
|
|
|
? QString::number(entry.numDownloaded()) |
|
|
|
|
: tr("N/A"))); |
|
|
|
|
|
|
|
|
|
const Qt::Alignment alignment = (Qt::AlignRight | Qt::AlignVCenter); |
|
|
|
|
item->setTextAlignment(COL_TIER, alignment); |
|
|
|
|
item->setTextAlignment(COL_PEERS, alignment); |
|
|
|
|
item->setTextAlignment(COL_SEEDS, alignment); |
|
|
|
|
item->setTextAlignment(COL_LEECHES, alignment); |
|
|
|
|
item->setTextAlignment(COL_DOWNLOADED, alignment); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Remove old trackers
|
|
|
|
|
for (const QString &tracker : asConst(oldTrackerURLs)) |
|
|
|
|
delete m_trackerItems.take(tracker); |
|
|
|
@ -400,7 +423,7 @@ void TrackerListWidget::askForTrackers()
@@ -400,7 +423,7 @@ void TrackerListWidget::askForTrackers()
|
|
|
|
|
|
|
|
|
|
void TrackerListWidget::copyTrackerUrl() |
|
|
|
|
{ |
|
|
|
|
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
const QVector<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
if (selectedTrackerItems.isEmpty()) return; |
|
|
|
|
|
|
|
|
|
QStringList urlsToCopy; |
|
|
|
@ -421,7 +444,7 @@ void TrackerListWidget::deleteSelectedTrackers()
@@ -421,7 +444,7 @@ void TrackerListWidget::deleteSelectedTrackers()
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
const QVector<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
if (selectedTrackerItems.isEmpty()) return; |
|
|
|
|
|
|
|
|
|
QStringList urlsToRemove; |
|
|
|
@ -453,7 +476,7 @@ void TrackerListWidget::editSelectedTracker()
@@ -453,7 +476,7 @@ void TrackerListWidget::editSelectedTracker()
|
|
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
|
if (!torrent) return; |
|
|
|
|
|
|
|
|
|
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
const QVector<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems(); |
|
|
|
|
if (selectedTrackerItems.isEmpty()) return; |
|
|
|
|
|
|
|
|
|
// During multi-select only process item selected last
|
|
|
|
@ -574,7 +597,7 @@ void TrackerListWidget::saveSettings() const
@@ -574,7 +597,7 @@ void TrackerListWidget::saveSettings() const
|
|
|
|
|
|
|
|
|
|
QStringList TrackerListWidget::headerLabels() |
|
|
|
|
{ |
|
|
|
|
static const QStringList header { |
|
|
|
|
return { |
|
|
|
|
tr("Tier") |
|
|
|
|
, tr("URL") |
|
|
|
|
, tr("Status") |
|
|
|
@ -584,8 +607,6 @@ QStringList TrackerListWidget::headerLabels()
@@ -584,8 +607,6 @@ QStringList TrackerListWidget::headerLabels()
|
|
|
|
|
, tr("Downloaded") |
|
|
|
|
, tr("Message") |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
return header; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int TrackerListWidget::visibleColumnsCount() const |
|
|
|
|