mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-20 23:47:23 -06:00
committed by
GitHub
parent
8cbe4a571c
commit
cdded6cef7
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -85,6 +86,21 @@ uint qHash(const PeerEndpoint &peerEndpoint, const uint seed = 0)
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
void setModelData(QStandardItemModel *model, const int row, const int column, const QString &displayData
|
||||
, const QVariant &underlyingData, const Qt::Alignment textAlignmentData = {}, const QString &toolTip = {})
|
||||
{
|
||||
const QMap<int, QVariant> data = {
|
||||
{Qt::DisplayRole, displayData},
|
||||
{PeerListSortModel::UnderlyingDataRole, underlyingData},
|
||||
{Qt::TextAlignmentRole, QVariant {textAlignmentData}},
|
||||
{Qt::ToolTipRole, toolTip}};
|
||||
|
||||
model->setItemData(model->index(row, column), data);
|
||||
}
|
||||
}
|
||||
|
||||
PeerListWidget::PeerListWidget(PropertiesWidget *parent)
|
||||
: QTreeView(parent)
|
||||
, m_properties(parent)
|
||||
@@ -404,23 +420,58 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
|
||||
if (torrent != m_properties->getCurrentTorrent())
|
||||
return;
|
||||
|
||||
// Remove I2P peers since they will be completely reloaded.
|
||||
for (QStandardItem *item : asConst(m_I2PPeerItems))
|
||||
m_listModel->removeRow(item->row());
|
||||
m_I2PPeerItems.clear();
|
||||
|
||||
QSet<PeerEndpoint> existingPeers;
|
||||
existingPeers.reserve(m_peerItems.size());
|
||||
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i)
|
||||
existingPeers.insert(i.key());
|
||||
|
||||
const bool hideZeroValues = Preferences::instance()->getHideZeroValues();
|
||||
for (const BitTorrent::PeerInfo &peer : peers)
|
||||
{
|
||||
if (peer.address().ip.isNull())
|
||||
continue;
|
||||
|
||||
bool isNewPeer = false;
|
||||
updatePeer(torrent, peer, isNewPeer);
|
||||
if (!isNewPeer)
|
||||
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
|
||||
|
||||
auto itemIter = m_peerItems.find(peerEndpoint);
|
||||
const bool isNewPeer = (itemIter == m_peerItems.end());
|
||||
const int row = isNewPeer ? m_listModel->rowCount() : (*itemIter)->row();
|
||||
if (isNewPeer)
|
||||
{
|
||||
m_listModel->insertRow(row);
|
||||
|
||||
const bool useI2PSocket = peer.useI2PSocket();
|
||||
|
||||
const QString peerIPString = useI2PSocket ? tr("N/A") : peerEndpoint.address.ip.toString();
|
||||
setModelData(m_listModel, row, PeerListColumns::IP, peerIPString, peerIPString, {}, peerIPString);
|
||||
|
||||
const QString peerIPHiddenString = useI2PSocket ? QString() : peerEndpoint.address.ip.toString();
|
||||
setModelData(m_listModel, row, PeerListColumns::IP_HIDDEN, peerIPHiddenString, peerIPHiddenString);
|
||||
|
||||
const QString peerPortString = useI2PSocket ? tr("N/A") : QString::number(peer.address().port);
|
||||
setModelData(m_listModel, row, PeerListColumns::PORT, peerPortString, peer.address().port, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
|
||||
if (useI2PSocket)
|
||||
{
|
||||
m_I2PPeerItems.append(m_listModel->item(row, PeerListColumns::IP));
|
||||
}
|
||||
else
|
||||
{
|
||||
itemIter = m_peerItems.insert(peerEndpoint, m_listModel->item(row, PeerListColumns::IP));
|
||||
m_itemsByIP[peerEndpoint.address.ip].insert(itemIter.value());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
|
||||
existingPeers.remove(peerEndpoint);
|
||||
}
|
||||
|
||||
updatePeer(row, torrent, peer, hideZeroValues);
|
||||
}
|
||||
|
||||
// Remove peers that are gone
|
||||
@@ -438,73 +489,51 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
|
||||
});
|
||||
}
|
||||
|
||||
void PeerListWidget::updatePeer(const BitTorrent::Torrent *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer)
|
||||
void PeerListWidget::updatePeer(const int row, const BitTorrent::Torrent *torrent, const BitTorrent::PeerInfo &peer, const bool hideZeroValues)
|
||||
{
|
||||
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
|
||||
const QString peerIp = peerEndpoint.address.ip.toString();
|
||||
const Qt::Alignment intDataTextAlignment = Qt::AlignRight | Qt::AlignVCenter;
|
||||
|
||||
const auto setModelData =
|
||||
[this](const int row, const int column, const QString &displayData
|
||||
, const QVariant &underlyingData, const Qt::Alignment textAlignmentData = {}
|
||||
, const QString &toolTip = {})
|
||||
{
|
||||
const QMap<int, QVariant> data =
|
||||
{
|
||||
{Qt::DisplayRole, displayData},
|
||||
{PeerListSortModel::UnderlyingDataRole, underlyingData},
|
||||
{Qt::TextAlignmentRole, QVariant {textAlignmentData}},
|
||||
{Qt::ToolTipRole, toolTip}
|
||||
};
|
||||
m_listModel->setItemData(m_listModel->index(row, column), data);
|
||||
};
|
||||
|
||||
auto itemIter = m_peerItems.find(peerEndpoint);
|
||||
isNewPeer = (itemIter == m_peerItems.end());
|
||||
if (isNewPeer)
|
||||
{
|
||||
// new item
|
||||
const int row = m_listModel->rowCount();
|
||||
m_listModel->insertRow(row);
|
||||
|
||||
setModelData(row, PeerListColumns::IP, peerIp, peerIp, {}, peerIp);
|
||||
setModelData(row, PeerListColumns::PORT, QString::number(peer.address().port), peer.address().port, intDataTextAlignment);
|
||||
setModelData(row, PeerListColumns::IP_HIDDEN, peerIp, peerIp);
|
||||
|
||||
itemIter = m_peerItems.insert(peerEndpoint, m_listModel->item(row, PeerListColumns::IP));
|
||||
m_itemsByIP[peerEndpoint.address.ip].insert(itemIter.value());
|
||||
}
|
||||
|
||||
const int row = (*itemIter)->row();
|
||||
const bool hideValues = Preferences::instance()->getHideZeroValues();
|
||||
|
||||
setModelData(row, PeerListColumns::CONNECTION, peer.connectionType(), peer.connectionType());
|
||||
setModelData(row, PeerListColumns::FLAGS, peer.flags(), peer.flags(), {}, peer.flagsDescription());
|
||||
const QString client = peer.client().toHtmlEscaped();
|
||||
setModelData(row, PeerListColumns::CLIENT, client, client, {}, client);
|
||||
setModelData(m_listModel, row, PeerListColumns::CLIENT, client, client, {}, client);
|
||||
|
||||
const QString peerIdClient = peer.peerIdClient().toHtmlEscaped();
|
||||
setModelData(row, PeerListColumns::PEERID_CLIENT, peerIdClient, peerIdClient);
|
||||
setModelData(row, PeerListColumns::PROGRESS, (Utils::String::fromDouble(peer.progress() * 100, 1) + u'%'), peer.progress(), intDataTextAlignment);
|
||||
const QString downSpeed = (hideValues && (peer.payloadDownSpeed() <= 0)) ? QString {} : Utils::Misc::friendlyUnit(peer.payloadDownSpeed(), true);
|
||||
setModelData(row, PeerListColumns::DOWN_SPEED, downSpeed, peer.payloadDownSpeed(), intDataTextAlignment);
|
||||
const QString upSpeed = (hideValues && (peer.payloadUpSpeed() <= 0)) ? QString {} : Utils::Misc::friendlyUnit(peer.payloadUpSpeed(), true);
|
||||
setModelData(row, PeerListColumns::UP_SPEED, upSpeed, peer.payloadUpSpeed(), intDataTextAlignment);
|
||||
const QString totalDown = (hideValues && (peer.totalDownload() <= 0)) ? QString {} : Utils::Misc::friendlyUnit(peer.totalDownload());
|
||||
setModelData(row, PeerListColumns::TOT_DOWN, totalDown, peer.totalDownload(), intDataTextAlignment);
|
||||
const QString totalUp = (hideValues && (peer.totalUpload() <= 0)) ? QString {} : Utils::Misc::friendlyUnit(peer.totalUpload());
|
||||
setModelData(row, PeerListColumns::TOT_UP, totalUp, peer.totalUpload(), intDataTextAlignment);
|
||||
setModelData(row, PeerListColumns::RELEVANCE, (Utils::String::fromDouble(peer.relevance() * 100, 1) + u'%'), peer.relevance(), intDataTextAlignment);
|
||||
setModelData(m_listModel, row, PeerListColumns::PEERID_CLIENT, peerIdClient, peerIdClient);
|
||||
|
||||
const QString downSpeed = (hideZeroValues && (peer.payloadDownSpeed() <= 0))
|
||||
? QString() : Utils::Misc::friendlyUnit(peer.payloadDownSpeed(), true);
|
||||
setModelData(m_listModel, row, PeerListColumns::DOWN_SPEED, downSpeed, peer.payloadDownSpeed(), intDataTextAlignment);
|
||||
|
||||
const QString upSpeed = (hideZeroValues && (peer.payloadUpSpeed() <= 0))
|
||||
? QString() : Utils::Misc::friendlyUnit(peer.payloadUpSpeed(), true);
|
||||
setModelData(m_listModel, row, PeerListColumns::UP_SPEED, upSpeed, peer.payloadUpSpeed(), intDataTextAlignment);
|
||||
|
||||
const QString totalDown = (hideZeroValues && (peer.totalDownload() <= 0))
|
||||
? QString() : Utils::Misc::friendlyUnit(peer.totalDownload());
|
||||
setModelData(m_listModel, row, PeerListColumns::TOT_DOWN, totalDown, peer.totalDownload(), intDataTextAlignment);
|
||||
|
||||
const QString totalUp = (hideZeroValues && (peer.totalUpload() <= 0))
|
||||
? QString() : Utils::Misc::friendlyUnit(peer.totalUpload());
|
||||
setModelData(m_listModel, row, PeerListColumns::TOT_UP, totalUp, peer.totalUpload(), intDataTextAlignment);
|
||||
|
||||
setModelData(m_listModel, row, PeerListColumns::CONNECTION, peer.connectionType(), peer.connectionType());
|
||||
setModelData(m_listModel, row, PeerListColumns::FLAGS, peer.flags(), peer.flags(), {}, peer.flagsDescription());
|
||||
setModelData(m_listModel, row, PeerListColumns::PROGRESS, (Utils::String::fromDouble(peer.progress() * 100, 1) + u'%')
|
||||
, peer.progress(), intDataTextAlignment);
|
||||
setModelData(m_listModel, row, PeerListColumns::RELEVANCE, (Utils::String::fromDouble(peer.relevance() * 100, 1) + u'%')
|
||||
, peer.relevance(), intDataTextAlignment);
|
||||
|
||||
const PathList filePaths = torrent->info().filesForPiece(peer.downloadingPieceIndex());
|
||||
QStringList downloadingFiles;
|
||||
downloadingFiles.reserve(filePaths.size());
|
||||
for (const Path &filePath : filePaths)
|
||||
downloadingFiles.append(filePath.toString());
|
||||
const QString downloadingFilesDisplayValue = downloadingFiles.join(u';');
|
||||
setModelData(row, PeerListColumns::DOWNLOADING_PIECE, downloadingFilesDisplayValue, downloadingFilesDisplayValue, {}, downloadingFiles.join(u'\n'));
|
||||
|
||||
if (m_resolver)
|
||||
m_resolver->resolve(peerEndpoint.address.ip);
|
||||
const QString downloadingFilesDisplayValue = downloadingFiles.join(u';');
|
||||
setModelData(m_listModel, row, PeerListColumns::DOWNLOADING_PIECE, downloadingFilesDisplayValue
|
||||
, downloadingFilesDisplayValue, {}, downloadingFiles.join(u'\n'));
|
||||
|
||||
if (!peer.useI2PSocket() && m_resolver)
|
||||
m_resolver->resolve(peer.address().ip);
|
||||
|
||||
if (m_resolveCountries)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user