|
|
@ -30,78 +30,105 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "trackerlist.h" |
|
|
|
#include "trackerlist.h" |
|
|
|
|
|
|
|
|
|
|
|
#include <QApplication> |
|
|
|
|
|
|
|
#include <QTreeWidgetItem> |
|
|
|
|
|
|
|
#include <QStringList> |
|
|
|
|
|
|
|
#include <QMenu> |
|
|
|
|
|
|
|
#include <QHash> |
|
|
|
|
|
|
|
#include <QAction> |
|
|
|
#include <QAction> |
|
|
|
|
|
|
|
#include <QApplication> |
|
|
|
#include <QColor> |
|
|
|
#include <QColor> |
|
|
|
#include <QDebug> |
|
|
|
#include <QDebug> |
|
|
|
#include <QUrl> |
|
|
|
#include <QHash> |
|
|
|
|
|
|
|
#include <QHeaderView> |
|
|
|
|
|
|
|
#include <QMenu> |
|
|
|
#include <QMessageBox> |
|
|
|
#include <QMessageBox> |
|
|
|
|
|
|
|
#include <QStringList> |
|
|
|
#include <QTableView> |
|
|
|
#include <QTableView> |
|
|
|
#include <QHeaderView> |
|
|
|
#include <QTreeWidgetItem> |
|
|
|
|
|
|
|
#include <QUrl> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "base/bittorrent/peerinfo.h" |
|
|
|
#include "base/bittorrent/session.h" |
|
|
|
#include "base/bittorrent/session.h" |
|
|
|
#include "base/bittorrent/torrenthandle.h" |
|
|
|
#include "base/bittorrent/torrenthandle.h" |
|
|
|
#include "base/bittorrent/peerinfo.h" |
|
|
|
|
|
|
|
#include "base/bittorrent/trackerentry.h" |
|
|
|
#include "base/bittorrent/trackerentry.h" |
|
|
|
#include "base/preferences.h" |
|
|
|
#include "base/preferences.h" |
|
|
|
#include "base/utils/misc.h" |
|
|
|
#include "base/utils/misc.h" |
|
|
|
|
|
|
|
#include "autoexpandabledialog.h" |
|
|
|
|
|
|
|
#include "guiiconprovider.h" |
|
|
|
#include "propertieswidget.h" |
|
|
|
#include "propertieswidget.h" |
|
|
|
#include "trackersadditiondlg.h" |
|
|
|
#include "trackersadditiondlg.h" |
|
|
|
#include "guiiconprovider.h" |
|
|
|
|
|
|
|
#include "autoexpandabledialog.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TrackerList::TrackerList(PropertiesWidget *properties): QTreeWidget(), properties(properties) { |
|
|
|
TrackerList::TrackerList(PropertiesWidget *properties) |
|
|
|
|
|
|
|
: QTreeWidget() |
|
|
|
|
|
|
|
, m_properties(properties) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Set header
|
|
|
|
|
|
|
|
// Must be set before calling loadSettings() otherwise the header is reset on restart
|
|
|
|
|
|
|
|
setHeaderLabels(headerLabels()); |
|
|
|
|
|
|
|
// Load settings
|
|
|
|
|
|
|
|
loadSettings(); |
|
|
|
// Graphical settings
|
|
|
|
// Graphical settings
|
|
|
|
setRootIsDecorated(false); |
|
|
|
setRootIsDecorated(false); |
|
|
|
setAllColumnsShowFocus(true); |
|
|
|
setAllColumnsShowFocus(true); |
|
|
|
setItemsExpandable(false); |
|
|
|
setItemsExpandable(false); |
|
|
|
setSelectionMode(QAbstractItemView::ExtendedSelection); |
|
|
|
setSelectionMode(QAbstractItemView::ExtendedSelection); |
|
|
|
|
|
|
|
header()->setStretchLastSection(false); // Must be set after loadSettings() in order to work
|
|
|
|
|
|
|
|
// Ensure that at least one column is visible at all times
|
|
|
|
|
|
|
|
if (visibleColumnsCount() == 0) |
|
|
|
|
|
|
|
setColumnHidden(COL_URL, false); |
|
|
|
|
|
|
|
// To also mitigate the above issue, we have to resize each column when
|
|
|
|
|
|
|
|
// its size is 0, because explicitly 'showing' the column isn't enough
|
|
|
|
|
|
|
|
// in the above scenario.
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < COL_COUNT; ++i) |
|
|
|
|
|
|
|
if ((columnWidth(i) <= 0) && !isColumnHidden(i)) |
|
|
|
|
|
|
|
resizeColumnToContents(i); |
|
|
|
// Context menu
|
|
|
|
// Context menu
|
|
|
|
setContextMenuPolicy(Qt::CustomContextMenu); |
|
|
|
setContextMenuPolicy(Qt::CustomContextMenu); |
|
|
|
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint))); |
|
|
|
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint))); |
|
|
|
// Set header
|
|
|
|
// Header context menu
|
|
|
|
QStringList header; |
|
|
|
header()->setContextMenuPolicy(Qt::CustomContextMenu); |
|
|
|
header << "#"; |
|
|
|
connect(header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayToggleColumnsMenu(const QPoint&))); |
|
|
|
header << tr("URL"); |
|
|
|
// Set DHT, PeX, LSD items
|
|
|
|
header << tr("Status"); |
|
|
|
m_DHTItem = new QTreeWidgetItem({ "", "** [DHT] **", "", "0", "", "", "0" }); |
|
|
|
header << tr("Received"); |
|
|
|
insertTopLevelItem(0, m_DHTItem); |
|
|
|
header << tr("Seeds"); |
|
|
|
|
|
|
|
header << tr("Peers"); |
|
|
|
|
|
|
|
header << tr("Downloaded"); |
|
|
|
|
|
|
|
header << tr("Message"); |
|
|
|
|
|
|
|
setHeaderItem(new QTreeWidgetItem(header)); |
|
|
|
|
|
|
|
dht_item = new QTreeWidgetItem({ "", "** [DHT] **", "", "0", "", "", "0" }); |
|
|
|
|
|
|
|
insertTopLevelItem(0, dht_item); |
|
|
|
|
|
|
|
setRowColor(0, QColor("grey")); |
|
|
|
setRowColor(0, QColor("grey")); |
|
|
|
pex_item = new QTreeWidgetItem({ "", "** [PeX] **", "", "0", "", "", "0" }); |
|
|
|
m_PEXItem = new QTreeWidgetItem({ "", "** [PeX] **", "", "0", "", "", "0" }); |
|
|
|
insertTopLevelItem(1, pex_item); |
|
|
|
insertTopLevelItem(1, m_PEXItem); |
|
|
|
setRowColor(1, QColor("grey")); |
|
|
|
setRowColor(1, QColor("grey")); |
|
|
|
lsd_item = new QTreeWidgetItem({ "", "** [LSD] **", "", "0", "", "", "0" }); |
|
|
|
m_LSDItem = new QTreeWidgetItem({ "", "** [LSD] **", "", "0", "", "", "0" }); |
|
|
|
insertTopLevelItem(2, lsd_item); |
|
|
|
insertTopLevelItem(2, m_LSDItem); |
|
|
|
setRowColor(2, QColor("grey")); |
|
|
|
setRowColor(2, QColor("grey")); |
|
|
|
editHotkey = new QShortcut(Qt::Key_F2, this, SLOT(editSelectedTracker()), 0, Qt::WidgetShortcut); |
|
|
|
// Set static items alignment
|
|
|
|
|
|
|
|
m_DHTItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
m_PEXItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
m_LSDItem->setTextAlignment(COL_RECEIVED, (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_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_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
m_PEXItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
m_LSDItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
// Set header alignment
|
|
|
|
|
|
|
|
headerItem()->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
headerItem()->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
headerItem()->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
headerItem()->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
headerItem()->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
// Set hotkeys
|
|
|
|
|
|
|
|
m_editHotkey = new QShortcut(Qt::Key_F2, this, SLOT(editSelectedTracker()), 0, Qt::WidgetShortcut); |
|
|
|
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(editSelectedTracker())); |
|
|
|
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(editSelectedTracker())); |
|
|
|
deleteHotkey = new QShortcut(QKeySequence::Delete, this, SLOT(deleteSelectedTrackers()), 0, Qt::WidgetShortcut); |
|
|
|
m_deleteHotkey = new QShortcut(QKeySequence::Delete, this, SLOT(deleteSelectedTrackers()), 0, Qt::WidgetShortcut); |
|
|
|
copyHotkey = new QShortcut(QKeySequence::Copy, this, SLOT(copyTrackerUrl()), 0, Qt::WidgetShortcut); |
|
|
|
m_copyHotkey = new QShortcut(QKeySequence::Copy, this, SLOT(copyTrackerUrl()), 0, Qt::WidgetShortcut); |
|
|
|
|
|
|
|
|
|
|
|
// This hack fixes reordering of first column with Qt5.
|
|
|
|
// This hack fixes reordering of first column with Qt5.
|
|
|
|
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
|
|
|
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
|
|
|
QTableView unused; |
|
|
|
QTableView unused; |
|
|
|
unused.setVerticalHeader(this->header()); |
|
|
|
unused.setVerticalHeader(header()); |
|
|
|
this->header()->setParent(this); |
|
|
|
header()->setParent(this); |
|
|
|
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal)); |
|
|
|
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal)); |
|
|
|
|
|
|
|
|
|
|
|
loadSettings(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TrackerList::~TrackerList() { |
|
|
|
TrackerList::~TrackerList() |
|
|
|
delete editHotkey; |
|
|
|
{ |
|
|
|
delete deleteHotkey; |
|
|
|
|
|
|
|
delete copyHotkey; |
|
|
|
|
|
|
|
saveSettings(); |
|
|
|
saveSettings(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -125,7 +152,7 @@ void TrackerList::setRowColor(int row, QColor color) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::moveSelectionUp() { |
|
|
|
void TrackerList::moveSelectionUp() { |
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) { |
|
|
|
if (!torrent) { |
|
|
|
clear(); |
|
|
|
clear(); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -163,7 +190,7 @@ void TrackerList::moveSelectionUp() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::moveSelectionDown() { |
|
|
|
void TrackerList::moveSelectionDown() { |
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) { |
|
|
|
if (!torrent) { |
|
|
|
clear(); |
|
|
|
clear(); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -202,20 +229,20 @@ void TrackerList::moveSelectionDown() { |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::clear() |
|
|
|
void TrackerList::clear() |
|
|
|
{ |
|
|
|
{ |
|
|
|
qDeleteAll(tracker_items.values()); |
|
|
|
qDeleteAll(m_trackerItems.values()); |
|
|
|
tracker_items.clear(); |
|
|
|
m_trackerItems.clear(); |
|
|
|
dht_item->setText(COL_STATUS, ""); |
|
|
|
m_DHTItem->setText(COL_STATUS, ""); |
|
|
|
dht_item->setText(COL_SEEDS, ""); |
|
|
|
m_DHTItem->setText(COL_SEEDS, ""); |
|
|
|
dht_item->setText(COL_PEERS, ""); |
|
|
|
m_DHTItem->setText(COL_PEERS, ""); |
|
|
|
dht_item->setText(COL_MSG, ""); |
|
|
|
m_DHTItem->setText(COL_MSG, ""); |
|
|
|
pex_item->setText(COL_STATUS, ""); |
|
|
|
m_PEXItem->setText(COL_STATUS, ""); |
|
|
|
pex_item->setText(COL_SEEDS, ""); |
|
|
|
m_PEXItem->setText(COL_SEEDS, ""); |
|
|
|
pex_item->setText(COL_PEERS, ""); |
|
|
|
m_PEXItem->setText(COL_PEERS, ""); |
|
|
|
pex_item->setText(COL_MSG, ""); |
|
|
|
m_PEXItem->setText(COL_MSG, ""); |
|
|
|
lsd_item->setText(COL_STATUS, ""); |
|
|
|
m_LSDItem->setText(COL_STATUS, ""); |
|
|
|
lsd_item->setText(COL_SEEDS, ""); |
|
|
|
m_LSDItem->setText(COL_SEEDS, ""); |
|
|
|
lsd_item->setText(COL_PEERS, ""); |
|
|
|
m_LSDItem->setText(COL_PEERS, ""); |
|
|
|
lsd_item->setText(COL_MSG, ""); |
|
|
|
m_LSDItem->setText(COL_MSG, ""); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent) { |
|
|
|
void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent) { |
|
|
@ -224,27 +251,27 @@ void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent) { |
|
|
|
|
|
|
|
|
|
|
|
// load DHT information
|
|
|
|
// load DHT information
|
|
|
|
if (BitTorrent::Session::instance()->isDHTEnabled() && !torrent->isPrivate()) |
|
|
|
if (BitTorrent::Session::instance()->isDHTEnabled() && !torrent->isPrivate()) |
|
|
|
dht_item->setText(COL_STATUS, working); |
|
|
|
m_DHTItem->setText(COL_STATUS, working); |
|
|
|
else |
|
|
|
else |
|
|
|
dht_item->setText(COL_STATUS, disabled); |
|
|
|
m_DHTItem->setText(COL_STATUS, disabled); |
|
|
|
|
|
|
|
|
|
|
|
// Load PeX Information
|
|
|
|
// Load PeX Information
|
|
|
|
if (BitTorrent::Session::instance()->isPeXEnabled() && !torrent->isPrivate()) |
|
|
|
if (BitTorrent::Session::instance()->isPeXEnabled() && !torrent->isPrivate()) |
|
|
|
pex_item->setText(COL_STATUS, working); |
|
|
|
m_PEXItem->setText(COL_STATUS, working); |
|
|
|
else |
|
|
|
else |
|
|
|
pex_item->setText(COL_STATUS, disabled); |
|
|
|
m_PEXItem->setText(COL_STATUS, disabled); |
|
|
|
|
|
|
|
|
|
|
|
// Load LSD Information
|
|
|
|
// Load LSD Information
|
|
|
|
if (BitTorrent::Session::instance()->isLSDEnabled() && !torrent->isPrivate()) |
|
|
|
if (BitTorrent::Session::instance()->isLSDEnabled() && !torrent->isPrivate()) |
|
|
|
lsd_item->setText(COL_STATUS, working); |
|
|
|
m_LSDItem->setText(COL_STATUS, working); |
|
|
|
else |
|
|
|
else |
|
|
|
lsd_item->setText(COL_STATUS, disabled); |
|
|
|
m_LSDItem->setText(COL_STATUS, disabled); |
|
|
|
|
|
|
|
|
|
|
|
if (torrent->isPrivate()) { |
|
|
|
if (torrent->isPrivate()) { |
|
|
|
QString privateMsg = tr("This torrent is private"); |
|
|
|
QString privateMsg = tr("This torrent is private"); |
|
|
|
dht_item->setText(COL_MSG, privateMsg); |
|
|
|
m_DHTItem->setText(COL_MSG, privateMsg); |
|
|
|
pex_item->setText(COL_MSG, privateMsg); |
|
|
|
m_PEXItem->setText(COL_MSG, privateMsg); |
|
|
|
lsd_item->setText(COL_MSG, privateMsg); |
|
|
|
m_LSDItem->setText(COL_MSG, privateMsg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// XXX: libtorrent should provide this info...
|
|
|
|
// XXX: libtorrent should provide this info...
|
|
|
@ -273,31 +300,31 @@ void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
dht_item->setText(COL_SEEDS, QString::number(seedsDHT)); |
|
|
|
m_DHTItem->setText(COL_SEEDS, QString::number(seedsDHT)); |
|
|
|
dht_item->setText(COL_PEERS, QString::number(peersDHT)); |
|
|
|
m_DHTItem->setText(COL_PEERS, QString::number(peersDHT)); |
|
|
|
pex_item->setText(COL_SEEDS, QString::number(seedsPeX)); |
|
|
|
m_PEXItem->setText(COL_SEEDS, QString::number(seedsPeX)); |
|
|
|
pex_item->setText(COL_PEERS, QString::number(peersPeX)); |
|
|
|
m_PEXItem->setText(COL_PEERS, QString::number(peersPeX)); |
|
|
|
lsd_item->setText(COL_SEEDS, QString::number(seedsLSD)); |
|
|
|
m_LSDItem->setText(COL_SEEDS, QString::number(seedsLSD)); |
|
|
|
lsd_item->setText(COL_PEERS, QString::number(peersLSD)); |
|
|
|
m_LSDItem->setText(COL_PEERS, QString::number(peersLSD)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::loadTrackers() { |
|
|
|
void TrackerList::loadTrackers() { |
|
|
|
// Load trackers from torrent handle
|
|
|
|
// Load trackers from torrent handle
|
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) return; |
|
|
|
if (!torrent) return; |
|
|
|
|
|
|
|
|
|
|
|
loadStickyItems(torrent); |
|
|
|
loadStickyItems(torrent); |
|
|
|
// Load actual trackers information
|
|
|
|
// Load actual trackers information
|
|
|
|
QHash<QString, BitTorrent::TrackerInfo> trackers_data = torrent->trackerInfos(); |
|
|
|
QHash<QString, BitTorrent::TrackerInfo> trackers_data = torrent->trackerInfos(); |
|
|
|
QStringList old_trackers_urls = tracker_items.keys(); |
|
|
|
QStringList old_trackers_urls = m_trackerItems.keys(); |
|
|
|
foreach (const BitTorrent::TrackerEntry &entry, torrent->trackers()) { |
|
|
|
foreach (const BitTorrent::TrackerEntry &entry, torrent->trackers()) { |
|
|
|
QString trackerUrl = entry.url(); |
|
|
|
QString trackerUrl = entry.url(); |
|
|
|
QTreeWidgetItem *item = tracker_items.value(trackerUrl, 0); |
|
|
|
QTreeWidgetItem *item = m_trackerItems.value(trackerUrl, 0); |
|
|
|
if (!item) { |
|
|
|
if (!item) { |
|
|
|
item = new QTreeWidgetItem(); |
|
|
|
item = new QTreeWidgetItem(); |
|
|
|
item->setText(COL_URL, trackerUrl); |
|
|
|
item->setText(COL_URL, trackerUrl); |
|
|
|
addTopLevelItem(item); |
|
|
|
addTopLevelItem(item); |
|
|
|
tracker_items[trackerUrl] = item; |
|
|
|
m_trackerItems[trackerUrl] = item; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
old_trackers_urls.removeOne(trackerUrl); |
|
|
|
old_trackers_urls.removeOne(trackerUrl); |
|
|
|
} |
|
|
|
} |
|
|
@ -334,16 +361,21 @@ void TrackerList::loadTrackers() { |
|
|
|
item->setText(COL_DOWNLOADED, "0"); |
|
|
|
item->setText(COL_DOWNLOADED, "0"); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
item->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
item->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
item->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
item->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
|
|
|
|
item->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); |
|
|
|
} |
|
|
|
} |
|
|
|
// Remove old trackers
|
|
|
|
// Remove old trackers
|
|
|
|
foreach (const QString &tracker, old_trackers_urls) { |
|
|
|
foreach (const QString &tracker, old_trackers_urls) { |
|
|
|
delete tracker_items.take(tracker); |
|
|
|
delete m_trackerItems.take(tracker); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Ask the user for new trackers and add them to the torrent
|
|
|
|
// Ask the user for new trackers and add them to the torrent
|
|
|
|
void TrackerList::askForTrackers() { |
|
|
|
void TrackerList::askForTrackers() { |
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) return; |
|
|
|
if (!torrent) return; |
|
|
|
|
|
|
|
|
|
|
|
QList<BitTorrent::TrackerEntry> trackers; |
|
|
|
QList<BitTorrent::TrackerEntry> trackers; |
|
|
@ -366,7 +398,7 @@ void TrackerList::copyTrackerUrl() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::deleteSelectedTrackers() { |
|
|
|
void TrackerList::deleteSelectedTrackers() { |
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) { |
|
|
|
if (!torrent) { |
|
|
|
clear(); |
|
|
|
clear(); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -379,7 +411,7 @@ void TrackerList::deleteSelectedTrackers() { |
|
|
|
foreach (QTreeWidgetItem *item, selected_items) { |
|
|
|
foreach (QTreeWidgetItem *item, selected_items) { |
|
|
|
QString tracker_url = item->data(COL_URL, Qt::DisplayRole).toString(); |
|
|
|
QString tracker_url = item->data(COL_URL, Qt::DisplayRole).toString(); |
|
|
|
urls_to_remove << tracker_url; |
|
|
|
urls_to_remove << tracker_url; |
|
|
|
tracker_items.remove(tracker_url); |
|
|
|
m_trackerItems.remove(tracker_url); |
|
|
|
delete item; |
|
|
|
delete item; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -398,7 +430,7 @@ void TrackerList::deleteSelectedTrackers() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::editSelectedTracker() { |
|
|
|
void TrackerList::editSelectedTracker() { |
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) return; |
|
|
|
if (!torrent) return; |
|
|
|
|
|
|
|
|
|
|
|
QString hash = torrent->hash(); |
|
|
|
QString hash = torrent->hash(); |
|
|
@ -449,13 +481,13 @@ void TrackerList::reannounceSelected() { |
|
|
|
QList<QTreeWidgetItem *> selected_items = selectedItems(); |
|
|
|
QList<QTreeWidgetItem *> selected_items = selectedItems(); |
|
|
|
if (selected_items.isEmpty()) return; |
|
|
|
if (selected_items.isEmpty()) return; |
|
|
|
|
|
|
|
|
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) return; |
|
|
|
if (!torrent) return; |
|
|
|
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers(); |
|
|
|
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers(); |
|
|
|
|
|
|
|
|
|
|
|
foreach (QTreeWidgetItem* item, selected_items) { |
|
|
|
foreach (QTreeWidgetItem* item, selected_items) { |
|
|
|
// DHT case
|
|
|
|
// DHT case
|
|
|
|
if (item == dht_item) { |
|
|
|
if (item == m_DHTItem) { |
|
|
|
torrent->forceDHTAnnounce(); |
|
|
|
torrent->forceDHTAnnounce(); |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
@ -473,29 +505,29 @@ void TrackerList::reannounceSelected() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::showTrackerListMenu(QPoint) { |
|
|
|
void TrackerList::showTrackerListMenu(QPoint) { |
|
|
|
BitTorrent::TorrentHandle *const torrent = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); |
|
|
|
if (!torrent) return; |
|
|
|
if (!torrent) return; |
|
|
|
//QList<QTreeWidgetItem*> selected_items = getSelectedTrackerItems();
|
|
|
|
//QList<QTreeWidgetItem*> selected_items = getSelectedTrackerItems();
|
|
|
|
QMenu menu; |
|
|
|
QMenu menu; |
|
|
|
// Add actions
|
|
|
|
// Add actions
|
|
|
|
QAction *addAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-add"), tr("Add a new tracker...")); |
|
|
|
QAction *addAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-add"), tr("Add a new tracker...")); |
|
|
|
QAction *copyAct = 0; |
|
|
|
QAction *copyAct = nullptr; |
|
|
|
QAction *delAct = 0; |
|
|
|
QAction *delAct = nullptr; |
|
|
|
QAction *editAct = 0; |
|
|
|
QAction *editAct = nullptr; |
|
|
|
if (!getSelectedTrackerItems().isEmpty()) { |
|
|
|
if (!getSelectedTrackerItems().isEmpty()) { |
|
|
|
delAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-remove"), tr("Remove tracker")); |
|
|
|
delAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-remove"), tr("Remove tracker")); |
|
|
|
copyAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy tracker URL")); |
|
|
|
copyAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy tracker URL")); |
|
|
|
editAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-rename"),tr("Edit selected tracker URL")); |
|
|
|
editAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-rename"),tr("Edit selected tracker URL")); |
|
|
|
} |
|
|
|
} |
|
|
|
QAction *reannounceSelAct = NULL; |
|
|
|
QAction *reannounceSelAct = nullptr; |
|
|
|
QAction *reannounceAct = NULL; |
|
|
|
QAction *reannounceAct = nullptr; |
|
|
|
if (!torrent->isPaused()) { |
|
|
|
if (!torrent->isPaused()) { |
|
|
|
reannounceSelAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to selected trackers")); |
|
|
|
reannounceSelAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to selected trackers")); |
|
|
|
menu.addSeparator(); |
|
|
|
menu.addSeparator(); |
|
|
|
reannounceAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to all trackers")); |
|
|
|
reannounceAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to all trackers")); |
|
|
|
} |
|
|
|
} |
|
|
|
QAction *act = menu.exec(QCursor::pos()); |
|
|
|
QAction *act = menu.exec(QCursor::pos()); |
|
|
|
if (act == 0) return; |
|
|
|
if (act == nullptr) return; |
|
|
|
if (act == addAct) { |
|
|
|
if (act == addAct) { |
|
|
|
askForTrackers(); |
|
|
|
askForTrackers(); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -513,7 +545,7 @@ void TrackerList::showTrackerListMenu(QPoint) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (act == reannounceAct) { |
|
|
|
if (act == reannounceAct) { |
|
|
|
BitTorrent::TorrentHandle *h = properties->getCurrentTorrent(); |
|
|
|
BitTorrent::TorrentHandle *h = m_properties->getCurrentTorrent(); |
|
|
|
h->forceReannounce(); |
|
|
|
h->forceReannounce(); |
|
|
|
h->forceDHTAnnounce(); |
|
|
|
h->forceDHTAnnounce(); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -524,13 +556,65 @@ void TrackerList::showTrackerListMenu(QPoint) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::loadSettings() { |
|
|
|
void TrackerList::loadSettings() |
|
|
|
if (!header()->restoreState(Preferences::instance()->getPropTrackerListState())) { |
|
|
|
{ |
|
|
|
setColumnWidth(0, 30); |
|
|
|
header()->restoreState(Preferences::instance()->getPropTrackerListState()); |
|
|
|
setColumnWidth(1, 300); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::saveSettings() const { |
|
|
|
void TrackerList::saveSettings() const |
|
|
|
|
|
|
|
{ |
|
|
|
Preferences::instance()->setPropTrackerListState(header()->saveState()); |
|
|
|
Preferences::instance()->setPropTrackerListState(header()->saveState()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QStringList TrackerList::headerLabels() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static const QStringList header { |
|
|
|
|
|
|
|
"#" |
|
|
|
|
|
|
|
, tr("URL") |
|
|
|
|
|
|
|
, tr("Status") |
|
|
|
|
|
|
|
, tr("Received") |
|
|
|
|
|
|
|
, tr("Seeds") |
|
|
|
|
|
|
|
, tr("Peers") |
|
|
|
|
|
|
|
, tr("Downloaded") |
|
|
|
|
|
|
|
, tr("Message") |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return header; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int TrackerList::visibleColumnsCount() const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int visibleCols = 0; |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < COL_COUNT; ++i) { |
|
|
|
|
|
|
|
if (!isColumnHidden(i)) |
|
|
|
|
|
|
|
++visibleCols; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return visibleCols; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TrackerList::displayToggleColumnsMenu(const QPoint &) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QMenu hideshowColumn(this); |
|
|
|
|
|
|
|
hideshowColumn.setTitle(tr("Column visibility")); |
|
|
|
|
|
|
|
for (int i = 0; i < COL_COUNT; ++i) { |
|
|
|
|
|
|
|
QAction *myAct = hideshowColumn.addAction(headerLabels().at(i)); |
|
|
|
|
|
|
|
myAct->setCheckable(true); |
|
|
|
|
|
|
|
myAct->setChecked(!isColumnHidden(i)); |
|
|
|
|
|
|
|
myAct->setData(i); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Call menu
|
|
|
|
|
|
|
|
QAction *act = hideshowColumn.exec(QCursor::pos()); |
|
|
|
|
|
|
|
if (!act) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int col = act->data().toInt(); |
|
|
|
|
|
|
|
Q_ASSERT(visibleColumnsCount() > 0); |
|
|
|
|
|
|
|
if (!isColumnHidden(col) && (visibleColumnsCount() == 1)) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
qDebug("Toggling column %d visibility", col); |
|
|
|
|
|
|
|
setColumnHidden(col, !isColumnHidden(col)); |
|
|
|
|
|
|
|
if (!isColumnHidden(col) && (columnWidth(col) <= 5)) |
|
|
|
|
|
|
|
setColumnWidth(col, 100); |
|
|
|
|
|
|
|
saveSettings(); |
|
|
|
|
|
|
|
} |
|
|
|