|
|
@ -57,6 +57,22 @@ |
|
|
|
#include "propertieswidget.h" |
|
|
|
#include "propertieswidget.h" |
|
|
|
#include "uithememanager.h" |
|
|
|
#include "uithememanager.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct PeerEndpoint |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
BitTorrent::PeerAddress address; |
|
|
|
|
|
|
|
QString connectionType; // matches return type of `PeerInfo::connectionType()`
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool operator==(const PeerEndpoint &left, const PeerEndpoint &right) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return (left.address == right.address) && (left.connectionType == right.connectionType); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint qHash(const PeerEndpoint &peerEndpoint, const uint seed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return (qHash(peerEndpoint.address, seed) ^ ::qHash(peerEndpoint.connectionType)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PeerListWidget::PeerListWidget(PropertiesWidget *parent) |
|
|
|
PeerListWidget::PeerListWidget(PropertiesWidget *parent) |
|
|
|
: QTreeView(parent) |
|
|
|
: QTreeView(parent) |
|
|
|
, m_properties(parent) |
|
|
|
, m_properties(parent) |
|
|
@ -331,42 +347,45 @@ void PeerListWidget::loadPeers(const BitTorrent::TorrentHandle *torrent) |
|
|
|
if (!torrent) return; |
|
|
|
if (!torrent) return; |
|
|
|
|
|
|
|
|
|
|
|
const QVector<BitTorrent::PeerInfo> peers = torrent->peers(); |
|
|
|
const QVector<BitTorrent::PeerInfo> peers = torrent->peers(); |
|
|
|
QSet<QString> existingPeers; |
|
|
|
QSet<PeerEndpoint> existingPeers; |
|
|
|
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i) |
|
|
|
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i) |
|
|
|
existingPeers << i.key(); |
|
|
|
existingPeers << i.key(); |
|
|
|
|
|
|
|
|
|
|
|
for (const BitTorrent::PeerInfo &peer : peers) { |
|
|
|
for (const BitTorrent::PeerInfo &peer : peers) { |
|
|
|
const BitTorrent::PeerAddress addr = peer.address(); |
|
|
|
if (peer.address().ip.isNull()) continue; |
|
|
|
if (addr.ip.isNull()) continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const QString peerIp = addr.ip.toString(); |
|
|
|
|
|
|
|
bool isNewPeer = false; |
|
|
|
bool isNewPeer = false; |
|
|
|
updatePeer(peerIp, torrent, peer, isNewPeer); |
|
|
|
updatePeer(torrent, peer, isNewPeer); |
|
|
|
if (!isNewPeer) |
|
|
|
if (!isNewPeer) { |
|
|
|
existingPeers.remove(peerIp); |
|
|
|
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()}; |
|
|
|
|
|
|
|
existingPeers.remove(peerEndpoint); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Remove peers that are gone
|
|
|
|
// Remove peers that are gone
|
|
|
|
for (const QString &ip : asConst(existingPeers)) { |
|
|
|
for (const PeerEndpoint &peerEndpoint : asConst(existingPeers)) { |
|
|
|
const QStandardItem *item = m_peerItems.take(ip); |
|
|
|
const QStandardItem *item = m_peerItems.take(peerEndpoint); |
|
|
|
m_listModel->removeRow(item->row()); |
|
|
|
m_listModel->removeRow(item->row()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void PeerListWidget::updatePeer(const QString &ip, const BitTorrent::TorrentHandle *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer) |
|
|
|
void PeerListWidget::updatePeer(const BitTorrent::TorrentHandle *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto itemIter = m_peerItems.find(ip); |
|
|
|
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()}; |
|
|
|
|
|
|
|
const QString peerIp = peerEndpoint.address.ip.toString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto itemIter = m_peerItems.find(peerEndpoint); |
|
|
|
isNewPeer = (itemIter == m_peerItems.end()); |
|
|
|
isNewPeer = (itemIter == m_peerItems.end()); |
|
|
|
if (isNewPeer) { |
|
|
|
if (isNewPeer) { |
|
|
|
// new item
|
|
|
|
// new item
|
|
|
|
const int row = m_listModel->rowCount(); |
|
|
|
const int row = m_listModel->rowCount(); |
|
|
|
m_listModel->insertRow(row); |
|
|
|
m_listModel->insertRow(row); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), peerIp); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ip, Qt::ToolTipRole); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), peerIp, Qt::ToolTipRole); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::PORT), peer.address().port); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::PORT), peer.address().port); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP_HIDDEN), ip); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP_HIDDEN), peerIp); |
|
|
|
|
|
|
|
|
|
|
|
itemIter = m_peerItems.insert(ip, m_listModel->item(row, PeerListDelegate::IP)); |
|
|
|
itemIter = m_peerItems.insert(peerEndpoint, m_listModel->item(row, PeerListDelegate::IP)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const int row = (*itemIter)->row(); |
|
|
|
const int row = (*itemIter)->row(); |
|
|
@ -386,7 +405,7 @@ void PeerListWidget::updatePeer(const QString &ip, const BitTorrent::TorrentHand |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWNLOADING_PIECE), downloadingFiles.join('\n'), Qt::ToolTipRole); |
|
|
|
m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWNLOADING_PIECE), downloadingFiles.join('\n'), Qt::ToolTipRole); |
|
|
|
|
|
|
|
|
|
|
|
if (m_resolver) |
|
|
|
if (m_resolver) |
|
|
|
m_resolver->resolve(ip); |
|
|
|
m_resolver->resolve(peerIp); |
|
|
|
|
|
|
|
|
|
|
|
if (m_resolveCountries) { |
|
|
|
if (m_resolveCountries) { |
|
|
|
const QIcon icon = UIThemeManager::instance()->getFlagIcon(peer.country()); |
|
|
|
const QIcon icon = UIThemeManager::instance()->getFlagIcon(peer.country()); |
|
|
@ -400,9 +419,13 @@ void PeerListWidget::updatePeer(const QString &ip, const BitTorrent::TorrentHand |
|
|
|
|
|
|
|
|
|
|
|
void PeerListWidget::handleResolved(const QString &ip, const QString &hostname) |
|
|
|
void PeerListWidget::handleResolved(const QString &ip, const QString &hostname) |
|
|
|
{ |
|
|
|
{ |
|
|
|
QStandardItem *item = m_peerItems.value(ip, nullptr); |
|
|
|
for (auto iter = m_peerItems.cbegin(); iter != m_peerItems.cend(); ++iter) { |
|
|
|
if (item) |
|
|
|
if (iter.key().address.ip.toString() == ip) { |
|
|
|
|
|
|
|
QStandardItem *item {iter.value()}; |
|
|
|
item->setData(hostname, Qt::DisplayRole); |
|
|
|
item->setData(hostname, Qt::DisplayRole); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void PeerListWidget::handleSortColumnChanged(const int col) |
|
|
|
void PeerListWidget::handleSortColumnChanged(const int col) |
|
|
|