Browse Source

Follow project coding style. Issue #2192.

adaptive-webui-19844
buinsky 9 years ago
parent
commit
aea6c38b33
  1. 783
      src/gui/properties/peerlistwidget.cpp
  2. 70
      src/gui/properties/peerlistwidget.h

783
src/gui/properties/peerlistwidget.cpp

@ -51,447 +51,458 @@
#include "peerlistsortmodel.h" #include "peerlistsortmodel.h"
#include "peerlistwidget.h" #include "peerlistwidget.h"
PeerListWidget::PeerListWidget(PropertiesWidget *parent): PeerListWidget::PeerListWidget(PropertiesWidget *parent)
QTreeView(parent), m_properties(parent), m_displayFlags(false) : QTreeView(parent)
, m_properties(parent)
, m_displayFlags(false)
{ {
// Load settings // Load settings
loadSettings(); loadSettings();
// Visual settings // Visual settings
setUniformRowHeights(true); setUniformRowHeights(true);
setRootIsDecorated(false); setRootIsDecorated(false);
setItemsExpandable(false); setItemsExpandable(false);
setAllColumnsShowFocus(true); setAllColumnsShowFocus(true);
setSelectionMode(QAbstractItemView::ExtendedSelection); setSelectionMode(QAbstractItemView::ExtendedSelection);
// List Model // List Model
m_listModel = new QStandardItemModel(0, PeerListDelegate::COL_COUNT); m_listModel = new QStandardItemModel(0, PeerListDelegate::COL_COUNT);
m_listModel->setHeaderData(PeerListDelegate::COUNTRY, Qt::Horizontal, QVariant()); // Country flag column m_listModel->setHeaderData(PeerListDelegate::COUNTRY, Qt::Horizontal, QVariant()); // Country flag column
m_listModel->setHeaderData(PeerListDelegate::IP, Qt::Horizontal, tr("IP")); m_listModel->setHeaderData(PeerListDelegate::IP, Qt::Horizontal, tr("IP"));
m_listModel->setHeaderData(PeerListDelegate::PORT, Qt::Horizontal, tr("Port")); m_listModel->setHeaderData(PeerListDelegate::PORT, Qt::Horizontal, tr("Port"));
m_listModel->setHeaderData(PeerListDelegate::FLAGS, Qt::Horizontal, tr("Flags")); m_listModel->setHeaderData(PeerListDelegate::FLAGS, Qt::Horizontal, tr("Flags"));
m_listModel->setHeaderData(PeerListDelegate::CONNECTION, Qt::Horizontal, tr("Connection")); m_listModel->setHeaderData(PeerListDelegate::CONNECTION, Qt::Horizontal, tr("Connection"));
m_listModel->setHeaderData(PeerListDelegate::CLIENT, Qt::Horizontal, tr("Client", "i.e.: Client application")); m_listModel->setHeaderData(PeerListDelegate::CLIENT, Qt::Horizontal, tr("Client", "i.e.: Client application"));
m_listModel->setHeaderData(PeerListDelegate::PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded")); m_listModel->setHeaderData(PeerListDelegate::PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded"));
m_listModel->setHeaderData(PeerListDelegate::DOWN_SPEED, Qt::Horizontal, tr("Down Speed", "i.e: Download speed")); m_listModel->setHeaderData(PeerListDelegate::DOWN_SPEED, Qt::Horizontal, tr("Down Speed", "i.e: Download speed"));
m_listModel->setHeaderData(PeerListDelegate::UP_SPEED, Qt::Horizontal, tr("Up Speed", "i.e: Upload speed")); m_listModel->setHeaderData(PeerListDelegate::UP_SPEED, Qt::Horizontal, tr("Up Speed", "i.e: Upload speed"));
m_listModel->setHeaderData(PeerListDelegate::TOT_DOWN, Qt::Horizontal, tr("Downloaded", "i.e: total data downloaded")); m_listModel->setHeaderData(PeerListDelegate::TOT_DOWN, Qt::Horizontal, tr("Downloaded", "i.e: total data downloaded"));
m_listModel->setHeaderData(PeerListDelegate::TOT_UP, Qt::Horizontal, tr("Uploaded", "i.e: total data uploaded")); m_listModel->setHeaderData(PeerListDelegate::TOT_UP, Qt::Horizontal, tr("Uploaded", "i.e: total data uploaded"));
m_listModel->setHeaderData(PeerListDelegate::RELEVANCE, Qt::Horizontal, tr("Relevance", "i.e: How relevant this peer is to us. How many pieces it has that we don't.")); m_listModel->setHeaderData(PeerListDelegate::RELEVANCE, Qt::Horizontal, tr("Relevance", "i.e: How relevant this peer is to us. How many pieces it has that we don't."));
// Proxy model to support sorting without actually altering the underlying model // Proxy model to support sorting without actually altering the underlying model
m_proxyModel = new PeerListSortModel(); m_proxyModel = new PeerListSortModel();
m_proxyModel->setDynamicSortFilter(true); m_proxyModel->setDynamicSortFilter(true);
m_proxyModel->setSourceModel(m_listModel); m_proxyModel->setSourceModel(m_listModel);
m_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
setModel(m_proxyModel); setModel(m_proxyModel);
//Explicitly set the column visibility. When columns are added/removed //Explicitly set the column visibility. When columns are added/removed
//between versions this prevents some of them being hidden due to //between versions this prevents some of them being hidden due to
//incorrect restoreState() being used. //incorrect restoreState() being used.
for (unsigned int i=0; i<PeerListDelegate::IP_HIDDEN; i++) for (unsigned int i = 0; i < PeerListDelegate::IP_HIDDEN; i++)
showColumn(i); showColumn(i);
hideColumn(PeerListDelegate::IP_HIDDEN); hideColumn(PeerListDelegate::IP_HIDDEN);
hideColumn(PeerListDelegate::COL_COUNT); hideColumn(PeerListDelegate::COL_COUNT);
if (!Preferences::instance()->resolvePeerCountries()) if (!Preferences::instance()->resolvePeerCountries())
hideColumn(PeerListDelegate::COUNTRY); hideColumn(PeerListDelegate::COUNTRY);
//To also mitigate the above issue, we have to resize each column when //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 //its size is 0, because explicitly 'showing' the column isn't enough
//in the above scenario. //in the above scenario.
for (unsigned int i=0; i<PeerListDelegate::IP_HIDDEN; i++) for (unsigned int i = 0; i < PeerListDelegate::IP_HIDDEN; i++)
if (!columnWidth(i)) if (!columnWidth(i))
resizeColumnToContents(i); resizeColumnToContents(i);
// Context menu // Context menu
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showPeerListMenu(QPoint))); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showPeerListMenu(QPoint)));
// List delegate // List delegate
m_listDelegate = new PeerListDelegate(this); m_listDelegate = new PeerListDelegate(this);
setItemDelegate(m_listDelegate); setItemDelegate(m_listDelegate);
// Enable sorting // Enable sorting
setSortingEnabled(true); setSortingEnabled(true);
// IP to Hostname resolver // IP to Hostname resolver
updatePeerHostNameResolutionState(); updatePeerHostNameResolutionState();
// SIGNAL/SLOT // SIGNAL/SLOT
connect(header(), SIGNAL(sectionClicked(int)), SLOT(handleSortColumnChanged(int))); connect(header(), SIGNAL(sectionClicked(int)), SLOT(handleSortColumnChanged(int)));
handleSortColumnChanged(header()->sortIndicatorSection()); handleSortColumnChanged(header()->sortIndicatorSection());
copyHotkey = new QShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_C), this, SLOT(copySelectedPeers()), 0, Qt::WidgetShortcut); m_copyHotkey = new QShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_C), this, SLOT(copySelectedPeers()), 0, Qt::WidgetShortcut);
} }
PeerListWidget::~PeerListWidget() PeerListWidget::~PeerListWidget()
{ {
saveSettings(); saveSettings();
delete m_proxyModel; delete m_proxyModel;
delete m_listModel; delete m_listModel;
delete m_listDelegate; delete m_listDelegate;
if (m_resolver) if (m_resolver)
delete m_resolver; delete m_resolver;
delete copyHotkey; delete m_copyHotkey;
} }
void PeerListWidget::updatePeerHostNameResolutionState() void PeerListWidget::updatePeerHostNameResolutionState()
{ {
if (Preferences::instance()->resolvePeerHostNames()) { if (Preferences::instance()->resolvePeerHostNames()) {
if (!m_resolver) { if (!m_resolver) {
m_resolver = new Net::ReverseResolution(this); m_resolver = new Net::ReverseResolution(this);
connect(m_resolver, SIGNAL(ipResolved(QString,QString)), SLOT(handleResolved(QString,QString))); connect(m_resolver, SIGNAL(ipResolved(QString, QString)), SLOT(handleResolved(QString, QString)));
loadPeers(m_properties->getCurrentTorrent(), true); loadPeers(m_properties->getCurrentTorrent(), true);
}
}
else if (m_resolver) {
delete m_resolver;
} }
} else {
if (m_resolver)
delete m_resolver;
}
} }
void PeerListWidget::updatePeerCountryResolutionState() void PeerListWidget::updatePeerCountryResolutionState()
{ {
if (Preferences::instance()->resolvePeerCountries() != m_displayFlags) { if (Preferences::instance()->resolvePeerCountries() != m_displayFlags) {
m_displayFlags = !m_displayFlags; m_displayFlags = !m_displayFlags;
if (m_displayFlags) { if (m_displayFlags) {
loadPeers(m_properties->getCurrentTorrent()); loadPeers(m_properties->getCurrentTorrent());
showColumn(PeerListDelegate::COUNTRY); showColumn(PeerListDelegate::COUNTRY);
resizeColumnToContents(PeerListDelegate::COUNTRY); resizeColumnToContents(PeerListDelegate::COUNTRY);
} }
else { else {
hideColumn(PeerListDelegate::COUNTRY); hideColumn(PeerListDelegate::COUNTRY);
}
} }
}
} }
void PeerListWidget::showPeerListMenu(const QPoint&) void PeerListWidget::showPeerListMenu(const QPoint&)
{ {
QMenu menu; QMenu menu;
bool empty_menu = true; bool emptyMenu = true;
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
if (!torrent) return; if (!torrent) return;
// Add Peer Action // Add Peer Action
QAction *addPeerAct = 0; QAction *addPeerAct = 0;
if (!torrent->isQueued() && !torrent->isChecking()) { if (!torrent->isQueued() && !torrent->isChecking()) {
addPeerAct = menu.addAction(GuiIconProvider::instance()->getIcon("user-group-new"), tr("Add a new peer...")); addPeerAct = menu.addAction(GuiIconProvider::instance()->getIcon("user-group-new"), tr("Add a new peer..."));
empty_menu = false; emptyMenu = false;
} }
QAction *banAct = 0; QAction *banAct = 0;
QAction *copyPeerAct = 0; QAction *copyPeerAct = 0;
if (!selectionModel()->selectedRows().isEmpty()) { if (!selectionModel()->selectedRows().isEmpty()) {
copyPeerAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy selected")); copyPeerAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy selected"));
menu.addSeparator(); menu.addSeparator();
banAct = menu.addAction(GuiIconProvider::instance()->getIcon("user-group-delete"), tr("Ban peer permanently")); banAct = menu.addAction(GuiIconProvider::instance()->getIcon("user-group-delete"), tr("Ban peer permanently"));
empty_menu = false; emptyMenu = false;
} }
if (empty_menu) return; if (emptyMenu) return;
QAction *act = menu.exec(QCursor::pos()); QAction *act = menu.exec(QCursor::pos());
if (act == 0) return; if (act == 0) return;
if (act == addPeerAct) { if (act == addPeerAct) {
QList<BitTorrent::PeerAddress> peersList = PeersAdditionDlg::askForPeers(); QList<BitTorrent::PeerAddress> peersList = PeersAdditionDlg::askForPeers();
int peerCount = 0; int peerCount = 0;
foreach (const BitTorrent::PeerAddress &addr, peersList) { foreach (const BitTorrent::PeerAddress &addr, peersList) {
if (torrent->connectPeer(addr)) { if (torrent->connectPeer(addr)) {
qDebug("Adding peer %s...", qPrintable(addr.ip.toString())); qDebug("Adding peer %s...", qPrintable(addr.ip.toString()));
Logger::instance()->addMessage(tr("Manually adding peer '%1'...").arg(addr.ip.toString())); Logger::instance()->addMessage(tr("Manually adding peer '%1'...").arg(addr.ip.toString()));
peerCount++; peerCount++;
} }
else { else {
Logger::instance()->addMessage(tr("The peer '%1' could not be added to this torrent.").arg(addr.ip.toString()), Log::WARNING); Logger::instance()->addMessage(tr("The peer '%1' could not be added to this torrent.").arg(addr.ip.toString()), Log::WARNING);
}
} }
if (peerCount < peersList.length())
QMessageBox::information(0, tr("Peer addition"), tr("Some peers could not be added. Check the Log for details."));
else if (peerCount > 0)
QMessageBox::information(0, tr("Peer addition"), tr("The peers were added to this torrent."));
return;
}
if (act == banAct) {
banSelectedPeers();
return;
}
if (act == copyPeerAct) {
copySelectedPeers();
return;
} }
if (peerCount < peersList.length())
QMessageBox::information(0, tr("Peer addition"), tr("Some peers could not be added. Check the Log for details."));
else if (peerCount > 0)
QMessageBox::information(0, tr("Peer addition"), tr("The peers were added to this torrent."));
return;
}
if (act == banAct) {
banSelectedPeers();
return;
}
if (act == copyPeerAct) {
copySelectedPeers();
return;
}
} }
void PeerListWidget::banSelectedPeers() void PeerListWidget::banSelectedPeers()
{ {
// Confirm first // Confirm first
int ret = QMessageBox::question(this, tr("Ban peer permanently"), tr("Are you sure you want to ban permanently the selected peers?"), int ret = QMessageBox::question(this, tr("Ban peer permanently"), tr("Are you sure you want to ban permanently the selected peers?"),
tr("&Yes"), tr("&No"), tr("&Yes"), tr("&No"),
QString(), 0, 1); QString(), 0, 1);
if (ret) if (ret)
return; return;
QModelIndexList selectedIndexes = selectionModel()->selectedRows(); QModelIndexList selectedIndexes = selectionModel()->selectedRows();
foreach (const QModelIndex &index, selectedIndexes) { foreach (const QModelIndex &index, selectedIndexes) {
int row = m_proxyModel->mapToSource(index).row(); int row = m_proxyModel->mapToSource(index).row();
QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString(); QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString();
qDebug("Banning peer %s...", ip.toLocal8Bit().data()); qDebug("Banning peer %s...", ip.toLocal8Bit().data());
Logger::instance()->addMessage(tr("Manually banning peer '%1'...").arg(ip)); Logger::instance()->addMessage(tr("Manually banning peer '%1'...").arg(ip));
BitTorrent::Session::instance()->banIP(ip); BitTorrent::Session::instance()->banIP(ip);
} }
// Refresh list // Refresh list
loadPeers(m_properties->getCurrentTorrent()); loadPeers(m_properties->getCurrentTorrent());
} }
void PeerListWidget::copySelectedPeers() void PeerListWidget::copySelectedPeers()
{ {
QModelIndexList selectedIndexes = selectionModel()->selectedRows(); QModelIndexList selectedIndexes = selectionModel()->selectedRows();
QStringList selectedPeers; QStringList selectedPeers;
foreach (const QModelIndex &index, selectedIndexes) { foreach (const QModelIndex &index, selectedIndexes) {
int row = m_proxyModel->mapToSource(index).row(); int row = m_proxyModel->mapToSource(index).row();
QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString(); QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString();
QString myport = m_listModel->data(m_listModel->index(row, PeerListDelegate::PORT)).toString(); QString myport = m_listModel->data(m_listModel->index(row, PeerListDelegate::PORT)).toString();
if (ip.indexOf(".") == -1) // IPv6 if (ip.indexOf(".") == -1) // IPv6
selectedPeers << "[" + ip + "]:" + myport; selectedPeers << "[" + ip + "]:" + myport;
else // IPv4 else // IPv4
selectedPeers << ip + ":" + myport; selectedPeers << ip + ":" + myport;
} }
QApplication::clipboard()->setText(selectedPeers.join("\n")); QApplication::clipboard()->setText(selectedPeers.join("\n"));
} }
void PeerListWidget::clear() { void PeerListWidget::clear()
qDebug("clearing peer list"); {
m_peerItems.clear(); qDebug("clearing peer list");
m_peerAddresses.clear(); m_peerItems.clear();
m_missingFlags.clear(); m_peerAddresses.clear();
int nbrows = m_listModel->rowCount(); m_missingFlags.clear();
if (nbrows > 0) { int nbrows = m_listModel->rowCount();
qDebug("Cleared %d peers", nbrows); if (nbrows > 0) {
m_listModel->removeRows(0, nbrows); qDebug("Cleared %d peers", nbrows);
} m_listModel->removeRows(0, nbrows);
}
} }
void PeerListWidget::loadSettings() { void PeerListWidget::loadSettings()
header()->restoreState(Preferences::instance()->getPeerListState()); {
header()->restoreState(Preferences::instance()->getPeerListState());
} }
void PeerListWidget::saveSettings() const { void PeerListWidget::saveSettings() const
Preferences::instance()->setPeerListState(header()->saveState()); {
Preferences::instance()->setPeerListState(header()->saveState());
} }
void PeerListWidget::loadPeers(BitTorrent::TorrentHandle *const torrent, bool force_hostname_resolution) { void PeerListWidget::loadPeers(BitTorrent::TorrentHandle *const torrent, bool forceHostnameResolution)
if (!torrent) return; {
if (!torrent) return;
QList<BitTorrent::PeerInfo> peers = torrent->peers();
QSet<QString> old_peers_set = m_peerItems.keys().toSet(); QList<BitTorrent::PeerInfo> peers = torrent->peers();
QSet<QString> oldeersSet = m_peerItems.keys().toSet();
foreach (const BitTorrent::PeerInfo &peer, peers) {
BitTorrent::PeerAddress addr = peer.address(); foreach (const BitTorrent::PeerInfo &peer, peers) {
if (addr.ip.isNull()) continue; BitTorrent::PeerAddress addr = peer.address();
if (addr.ip.isNull()) continue;
QString peer_ip = addr.ip.toString();
if (m_peerItems.contains(peer_ip)) { QString peerIp = addr.ip.toString();
// Update existing peer if (m_peerItems.contains(peerIp)) {
updatePeer(peer_ip, torrent, peer); // Update existing peer
old_peers_set.remove(peer_ip); updatePeer(peerIp, torrent, peer);
if (force_hostname_resolution && m_resolver) { oldeersSet.remove(peerIp);
m_resolver->resolve(peer_ip); if (forceHostnameResolution && m_resolver)
} m_resolver->resolve(peerIp);
} else { }
// Add new peer else {
m_peerItems[peer_ip] = addPeer(peer_ip, torrent, peer); // Add new peer
m_peerAddresses[peer_ip] = addr; m_peerItems[peerIp] = addPeer(peerIp, torrent, peer);
// Resolve peer host name is asked m_peerAddresses[peerIp] = addr;
if (m_resolver) // Resolve peer host name is asked
m_resolver->resolve(peer_ip); if (m_resolver)
} m_resolver->resolve(peerIp);
} }
// Delete peers that are gone }
QSetIterator<QString> it(old_peers_set); // Delete peers that are gone
while(it.hasNext()) { QSetIterator<QString> it(oldeersSet);
const QString& ip = it.next(); while (it.hasNext()) {
m_missingFlags.remove(ip); const QString& ip = it.next();
m_peerAddresses.remove(ip); m_missingFlags.remove(ip);
QStandardItem *item = m_peerItems.take(ip); m_peerAddresses.remove(ip);
m_listModel->removeRow(item->row()); QStandardItem *item = m_peerItems.take(ip);
} m_listModel->removeRow(item->row());
}
} }
QStandardItem* PeerListWidget::addPeer(const QString& ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer) { QStandardItem* PeerListWidget::addPeer(const QString& ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer)
int row = m_listModel->rowCount(); {
// Adding Peer to peer list int row = m_listModel->rowCount();
m_listModel->insertRow(row); // Adding Peer to peer list
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip); m_listModel->insertRow(row);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip, Qt::ToolTipRole); m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::PORT), peer.address().port); m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip, Qt::ToolTipRole);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP_HIDDEN), ip); m_listModel->setData(m_listModel->index(row, PeerListDelegate::PORT), peer.address().port);
if (m_displayFlags) { m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP_HIDDEN), ip);
const QIcon ico = GuiIconProvider::instance()->getFlagIcon(peer.country()); if (m_displayFlags) {
if (!ico.isNull()) { const QIcon ico = GuiIconProvider::instance()->getFlagIcon(peer.country());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), ico, Qt::DecorationRole); if (!ico.isNull()) {
const QString country_name = Net::GeoIPManager::CountryName(peer.country()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), ico, Qt::DecorationRole);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), country_name, Qt::ToolTipRole); const QString countryName = Net::GeoIPManager::CountryName(peer.country());
} else { m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), countryName, Qt::ToolTipRole);
m_missingFlags.insert(ip); }
} else {
} m_missingFlags.insert(ip);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::CONNECTION), peer.connectionType()); }
QString flags, tooltip; }
getFlags(peer, flags, tooltip); m_listModel->setData(m_listModel->index(row, PeerListDelegate::CONNECTION), peer.connectionType());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), flags); QString flags, tooltip;
m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), tooltip, Qt::ToolTipRole); getFlags(peer, flags, tooltip);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::CLIENT), peer.client()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), flags);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::PROGRESS), peer.progress()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), tooltip, Qt::ToolTipRole);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payloadDownSpeed()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::CLIENT), peer.client());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::UP_SPEED), peer.payloadUpSpeed()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::PROGRESS), peer.progress());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_DOWN), peer.totalDownload()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payloadDownSpeed());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_UP), peer.totalUpload()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::UP_SPEED), peer.payloadUpSpeed());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::RELEVANCE), getPeerRelevance(torrent->pieces(), peer.pieces())); m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_DOWN), peer.totalDownload());
return m_listModel->item(row, PeerListDelegate::IP); m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_UP), peer.totalUpload());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::RELEVANCE), getPeerRelevance(torrent->pieces(), peer.pieces()));
return m_listModel->item(row, PeerListDelegate::IP);
} }
void PeerListWidget::updatePeer(const QString &ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer) { void PeerListWidget::updatePeer(const QString &ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer)
QStandardItem *item = m_peerItems.value(ip); {
int row = item->row(); QStandardItem *item = m_peerItems.value(ip);
if (m_displayFlags) { int row = item->row();
const QIcon ico = GuiIconProvider::instance()->getFlagIcon(peer.country()); if (m_displayFlags) {
if (!ico.isNull()) { const QIcon ico = GuiIconProvider::instance()->getFlagIcon(peer.country());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), ico, Qt::DecorationRole); if (!ico.isNull()) {
const QString country_name = Net::GeoIPManager::CountryName(peer.country()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), ico, Qt::DecorationRole);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), country_name, Qt::ToolTipRole); const QString countryName = Net::GeoIPManager::CountryName(peer.country());
m_missingFlags.remove(ip); m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), countryName, Qt::ToolTipRole);
} m_missingFlags.remove(ip);
} }
m_listModel->setData(m_listModel->index(row, PeerListDelegate::CONNECTION), peer.connectionType()); }
QString flags, tooltip; m_listModel->setData(m_listModel->index(row, PeerListDelegate::CONNECTION), peer.connectionType());
getFlags(peer, flags, tooltip); QString flags, tooltip;
m_listModel->setData(m_listModel->index(row, PeerListDelegate::PORT), peer.address().port); getFlags(peer, flags, tooltip);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), flags); m_listModel->setData(m_listModel->index(row, PeerListDelegate::PORT), peer.address().port);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), tooltip, Qt::ToolTipRole); m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), flags);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::CLIENT), peer.client()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), tooltip, Qt::ToolTipRole);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::PROGRESS), peer.progress()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::CLIENT), peer.client());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payloadDownSpeed()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::PROGRESS), peer.progress());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::UP_SPEED), peer.payloadUpSpeed()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payloadDownSpeed());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_DOWN), peer.totalDownload()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::UP_SPEED), peer.payloadUpSpeed());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_UP), peer.totalUpload()); m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_DOWN), peer.totalDownload());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::RELEVANCE), getPeerRelevance(torrent->pieces(), peer.pieces())); m_listModel->setData(m_listModel->index(row, PeerListDelegate::TOT_UP), peer.totalUpload());
m_listModel->setData(m_listModel->index(row, PeerListDelegate::RELEVANCE), getPeerRelevance(torrent->pieces(), peer.pieces()));
} }
void PeerListWidget::handleResolved(const QString &ip, const QString &hostname) { void PeerListWidget::handleResolved(const QString &ip, const QString &hostname)
QStandardItem *item = m_peerItems.value(ip, 0); {
if (item) { QStandardItem *item = m_peerItems.value(ip, 0);
qDebug("Resolved %s -> %s", qPrintable(ip), qPrintable(hostname)); if (item) {
item->setData(hostname, Qt::DisplayRole); qDebug("Resolved %s -> %s", qPrintable(ip), qPrintable(hostname));
} item->setData(hostname, Qt::DisplayRole);
}
} }
void PeerListWidget::handleSortColumnChanged(int col) void PeerListWidget::handleSortColumnChanged(int col)
{ {
if (col == PeerListDelegate::COUNTRY) { if (col == PeerListDelegate::COUNTRY) {
qDebug("Sorting by decoration"); qDebug("Sorting by decoration");
m_proxyModel->setSortRole(Qt::ToolTipRole); m_proxyModel->setSortRole(Qt::ToolTipRole);
} else { }
m_proxyModel->setSortRole(Qt::DisplayRole); else {
} m_proxyModel->setSortRole(Qt::DisplayRole);
}
} }
void PeerListWidget::getFlags(const BitTorrent::PeerInfo &peer, QString& flags, QString& tooltip) void PeerListWidget::getFlags(const BitTorrent::PeerInfo &peer, QString& flags, QString& tooltip)
{ {
if (peer.isInteresting()) { if (peer.isInteresting()) {
//d = Your client wants to download, but peer doesn't want to send (interested and choked) //d = Your client wants to download, but peer doesn't want to send (interested and choked)
if (peer.isRemoteChocked()) { if (peer.isRemoteChocked()) {
flags += "d "; flags += "d ";
tooltip += tr("interested(local) and choked(peer)"); tooltip += tr("interested(local) and choked(peer)");
tooltip += ", "; tooltip += ", ";
}
else {
//D = Currently downloading (interested and not choked)
flags += "D ";
tooltip += tr("interested(local) and unchoked(peer)");
tooltip += ", ";
}
} }
else {
//D = Currently downloading (interested and not choked) if (peer.isRemoteInterested()) {
flags += "D "; //u = Peer wants your client to upload, but your client doesn't want to (interested and choked)
tooltip += tr("interested(local) and unchoked(peer)"); if (peer.isChocked()) {
tooltip += ", "; flags += "u ";
tooltip += tr("interested(peer) and choked(local)");
tooltip += ", ";
}
else {
//U = Currently uploading (interested and not choked)
flags += "U ";
tooltip += tr("interested(peer) and unchoked(local)");
tooltip += ", ";
}
} }
}
if (peer.isRemoteInterested()) { //O = Optimistic unchoke
//u = Peer wants your client to upload, but your client doesn't want to (interested and choked) if (peer.optimisticUnchoke()) {
if (peer.isChocked()) { flags += "O ";
flags += "u "; tooltip += tr("optimistic unchoke");
tooltip += tr("interested(peer) and choked(local)"); tooltip += ", ";
tooltip += ", ";
} }
else {
//U = Currently uploading (interested and not choked) //S = Peer is snubbed
flags += "U "; if (peer.isSnubbed()) {
tooltip += tr("interested(peer) and unchoked(local)"); flags += "S ";
tooltip += ", "; tooltip += tr("peer snubbed");
} tooltip += ", ";
} }
//O = Optimistic unchoke //I = Peer is an incoming connection
if (peer.optimisticUnchoke()) { if (!peer.isLocalConnection()) {
flags += "O "; flags += "I ";
tooltip += tr("optimistic unchoke"); tooltip += tr("incoming connection");
tooltip += ", "; tooltip += ", ";
} }
//S = Peer is snubbed //K = Peer is unchoking your client, but your client is not interested
if (peer.isSnubbed()) { if (!peer.isRemoteChocked() && !peer.isInteresting()) {
flags += "S "; flags += "K ";
tooltip += tr("peer snubbed"); tooltip += tr("not interested(local) and unchoked(peer)");
tooltip += ", "; tooltip += ", ";
} }
//I = Peer is an incoming connection //? = Your client unchoked the peer but the peer is not interested
if (!peer.isLocalConnection()) { if (!peer.isChocked() && !peer.isRemoteInterested()) {
flags += "I "; flags += "? ";
tooltip += tr("incoming connection"); tooltip += tr("not interested(peer) and unchoked(local)");
tooltip += ", "; tooltip += ", ";
} }
//K = Peer is unchoking your client, but your client is not interested //X = Peer was included in peerlists obtained through Peer Exchange (PEX)
if (!peer.isRemoteChocked() && !peer.isInteresting()) { if (peer.fromPeX()) {
flags += "K "; flags += "X ";
tooltip += tr("not interested(local) and unchoked(peer)"); tooltip += tr("peer from PEX");
tooltip += ", "; tooltip += ", ";
} }
//? = Your client unchoked the peer but the peer is not interested //H = Peer was obtained through DHT
if (!peer.isChocked() && !peer.isRemoteInterested()) { if (peer.fromDHT()) {
flags += "? "; flags += "H ";
tooltip += tr("not interested(peer) and unchoked(local)"); tooltip += tr("peer from DHT");
tooltip += ", "; tooltip += ", ";
} }
//X = Peer was included in peerlists obtained through Peer Exchange (PEX) //E = Peer is using Protocol Encryption (all traffic)
if (peer.fromPeX()) { if (peer.isRC4Encrypted()) {
flags += "X "; flags += "E ";
tooltip += tr("peer from PEX"); tooltip += tr("encrypted traffic");
tooltip += ", "; tooltip += ", ";
} }
//H = Peer was obtained through DHT //e = Peer is using Protocol Encryption (handshake)
if (peer.fromDHT()) { if (peer.isPlaintextEncrypted()) {
flags += "H "; flags += "e ";
tooltip += tr("peer from DHT"); tooltip += tr("encrypted handshake");
tooltip += ", "; tooltip += ", ";
} }
//E = Peer is using Protocol Encryption (all traffic) //P = Peer is using uTorrent uTP
if (peer.isRC4Encrypted()) {
flags += "E "; if (peer.useUTPSocket()) {
tooltip += tr("encrypted traffic"); flags += "P ";
tooltip += ", "; tooltip += QString::fromUtf8(C_UTP);
} tooltip += ", ";
}
//e = Peer is using Protocol Encryption (handshake)
if (peer.isPlaintextEncrypted()) { //L = Peer is local
flags += "e "; if (peer.fromLSD()) {
tooltip += tr("encrypted handshake"); flags += "L";
tooltip += ", "; tooltip += tr("peer from LSD");
} }
//P = Peer is using uTorrent uTP flags = flags.trimmed();
tooltip = tooltip.trimmed();
if (peer.useUTPSocket()) { if (tooltip.endsWith(',', Qt::CaseInsensitive))
flags += "P "; tooltip.chop(1);
tooltip += QString::fromUtf8(C_UTP);
tooltip += ", ";
}
//L = Peer is local
if (peer.fromLSD()) {
flags += "L";
tooltip += tr("peer from LSD");
}
flags = flags.trimmed();
tooltip = tooltip.trimmed();
if (tooltip.endsWith(',', Qt::CaseInsensitive))
tooltip.chop(1);
} }
qreal PeerListWidget::getPeerRelevance(const QBitArray &allPieces, const QBitArray &peerPieces) qreal PeerListWidget::getPeerRelevance(const QBitArray &allPieces, const QBitArray &peerPieces)

70
src/gui/properties/peerlistwidget.h

@ -54,52 +54,50 @@ QT_END_NAMESPACE
namespace BitTorrent namespace BitTorrent
{ {
class TorrentHandle;
class TorrentHandle; class PeerInfo;
class PeerInfo; struct PeerAddress;
struct PeerAddress;
} }
class PeerListWidget : public QTreeView { class PeerListWidget: public QTreeView
Q_OBJECT {
Q_OBJECT
public: public:
PeerListWidget(PropertiesWidget *parent); explicit PeerListWidget(PropertiesWidget *parent);
~PeerListWidget(); ~PeerListWidget();
public slots: void loadPeers(BitTorrent::TorrentHandle *const torrent, bool forceHostnameResolution = false);
void loadPeers(BitTorrent::TorrentHandle *const torrent, bool force_hostname_resolution = false); QStandardItem *addPeer(const QString &ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer);
QStandardItem *addPeer(const QString &ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer); void updatePeer(const QString &ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer);
void updatePeer(const QString &ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer); void handleResolved(const QString &ip, const QString &hostname);
void handleResolved(const QString &ip, const QString &hostname); void updatePeerHostNameResolutionState();
void updatePeerHostNameResolutionState(); void updatePeerCountryResolutionState();
void updatePeerCountryResolutionState(); void clear();
void clear();
protected slots: private slots:
void loadSettings(); void loadSettings();
void saveSettings() const; void saveSettings() const;
void showPeerListMenu(const QPoint&); void showPeerListMenu(const QPoint&);
void banSelectedPeers(); void banSelectedPeers();
void copySelectedPeers(); void copySelectedPeers();
void handleSortColumnChanged(int col); void handleSortColumnChanged(int col);
private: private:
static void getFlags(const BitTorrent::PeerInfo &peer, QString &flags, QString &tooltip); static void getFlags(const BitTorrent::PeerInfo &peer, QString &flags, QString &tooltip);
qreal getPeerRelevance(const QBitArray &allPieces, const QBitArray &peerPieces); qreal getPeerRelevance(const QBitArray &allPieces, const QBitArray &peerPieces);
private: private:
QStandardItemModel *m_listModel; QStandardItemModel *m_listModel;
PeerListDelegate *m_listDelegate; PeerListDelegate *m_listDelegate;
PeerListSortModel *m_proxyModel; PeerListSortModel *m_proxyModel;
QHash<QString, QStandardItem*> m_peerItems; QHash<QString, QStandardItem*> m_peerItems;
QHash<QString, BitTorrent::PeerAddress> m_peerAddresses; QHash<QString, BitTorrent::PeerAddress> m_peerAddresses;
QSet<QString> m_missingFlags; QSet<QString> m_missingFlags;
QPointer<Net::ReverseResolution> m_resolver; QPointer<Net::ReverseResolution> m_resolver;
PropertiesWidget *m_properties; PropertiesWidget *m_properties;
bool m_displayFlags; bool m_displayFlags;
QShortcut *copyHotkey; QShortcut *m_copyHotkey;
}; };
#endif // PEERLISTWIDGET_H #endif // PEERLISTWIDGET_H

Loading…
Cancel
Save