Browse Source

Merge pull request #748 from Gelmir/peersort

Allow to sort peer list either by country or by IP
adaptive-webui-19844
sledgehammer999 12 years ago
parent
commit
f1845813a0
  1. 4
      src/properties/peerlistdelegate.h
  2. 70
      src/properties/peerlistsortmodel.h
  3. 23
      src/properties/peerlistwidget.cpp
  4. 3
      src/properties/peerlistwidget.h
  5. 1
      src/properties/properties.pri

4
src/properties/peerlistdelegate.h

@ -39,8 +39,8 @@ class PeerListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
enum PeerListColumns {IP, CONNECTION, FLAGS, CLIENT, PROGRESS, DOWN_SPEED, UP_SPEED, enum PeerListColumns {COUNTRY, IP, CONNECTION, FLAGS, CLIENT, PROGRESS, DOWN_SPEED, UP_SPEED,
TOT_DOWN, TOT_UP, IP_HIDDEN, COL_COUNT}; TOT_DOWN, TOT_UP, COL_COUNT};
public: public:
PeerListDelegate(QObject *parent) : QItemDelegate(parent) {} PeerListDelegate(QObject *parent) : QItemDelegate(parent) {}

70
src/properties/peerlistsortmodel.h

@ -0,0 +1,70 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2013 Nick Tiskov
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : daymansmail@gmail.com
*/
#ifndef PEERLISTSORTMODEL_H
#define PEERLISTSORTMODEL_H
#include <QStringList>
#include <QSortFilterProxyModel>
#include "peerlistdelegate.h"
class PeerListSortModel : public QSortFilterProxyModel {
Q_OBJECT
public:
PeerListSortModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {}
protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const {
if (sortColumn() == PeerListDelegate::IP) {
const QStringList ipLeft = sourceModel()->data(left).toString().split('.');
const QStringList ipRight = sourceModel()->data(right).toString().split('.');
if ((ipRight.size() & ipLeft.size()) != 4) // One row in model
return false;
Q_ASSERT(ipLeft.size() == 4);
Q_ASSERT(ipRight.size() == 4);
int i = 0;
while (i < 4) {
int l = ipLeft.at(i).toInt();
int r = ipRight.at(i).toInt();
if (l < r)
return true;
else if (l > r)
return false;
++i;
}
return false;
}
return QSortFilterProxyModel::lessThan(left, right);
}
};
#endif // PEERLISTSORTMODEL_H

23
src/properties/peerlistwidget.cpp

@ -61,6 +61,7 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent):
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::IP, Qt::Horizontal, tr("IP")); m_listModel->setHeaderData(PeerListDelegate::IP, Qt::Horizontal, tr("IP"));
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"));
@ -71,21 +72,22 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent):
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"));
// 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 QSortFilterProxyModel(); m_proxyModel = new PeerListSortModel();
m_proxyModel->setDynamicSortFilter(true); m_proxyModel->setDynamicSortFilter(true);
m_proxyModel->setSourceModel(m_listModel); m_proxyModel->setSourceModel(m_listModel);
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::COL_COUNT; i++)
showColumn(i); showColumn(i);
hideColumn(PeerListDelegate::IP_HIDDEN);
hideColumn(PeerListDelegate::COL_COUNT); hideColumn(PeerListDelegate::COL_COUNT);
if (!Preferences().resolvePeerCountries())
hideColumn(PeerListDelegate::COUNTRY);
//To also migitate the above issue, we have to resize each column when //To also migitate the above issue, we have to resize each column when
//its size is 0, because explicitely 'showing' the column isn't enough //its size is 0, because explicitely '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::COL_COUNT; i++)
if (!columnWidth(i)) if (!columnWidth(i))
resizeColumnToContents(i); resizeColumnToContents(i);
// Context menu // Context menu
@ -146,7 +148,7 @@ void PeerListWidget::showPeerListMenu(const QPoint&)
QStringList selectedPeerIPs; QStringList selectedPeerIPs;
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 myip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString(); QString myip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP)).toString();
selectedPeerIPs << myip; selectedPeerIPs << myip;
} }
// Add Peer Action // Add Peer Action
@ -366,13 +368,12 @@ QStandardItem* PeerListWidget::addPeer(const QString& ip, const peer_info& peer)
// Adding Peer to peer list // Adding Peer to peer list
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), ip);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP_HIDDEN), ip);
if (m_displayFlags) { if (m_displayFlags) {
const QIcon ico = GeoIPManager::CountryISOCodeToIcon(peer.country); const QIcon ico = GeoIPManager::CountryISOCodeToIcon(peer.country);
if (!ico.isNull()) { if (!ico.isNull()) {
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ico, Qt::DecorationRole); m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), ico, Qt::DecorationRole);
const QString country_name = GeoIPManager::CountryISOCodeToName(peer.country); const QString country_name = GeoIPManager::CountryISOCodeToName(peer.country);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), country_name, Qt::ToolTipRole); m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), country_name, Qt::ToolTipRole);
} else { } else {
m_missingFlags.insert(ip); m_missingFlags.insert(ip);
} }
@ -394,9 +395,9 @@ void PeerListWidget::updatePeer(const QString& ip, const peer_info& peer) {
if (m_displayFlags) { if (m_displayFlags) {
const QIcon ico = GeoIPManager::CountryISOCodeToIcon(peer.country); const QIcon ico = GeoIPManager::CountryISOCodeToIcon(peer.country);
if (!ico.isNull()) { if (!ico.isNull()) {
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), ico, Qt::DecorationRole); m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), ico, Qt::DecorationRole);
const QString country_name = GeoIPManager::CountryISOCodeToName(peer.country); const QString country_name = GeoIPManager::CountryISOCodeToName(peer.country);
m_listModel->setData(m_listModel->index(row, PeerListDelegate::IP), country_name, Qt::ToolTipRole); m_listModel->setData(m_listModel->index(row, PeerListDelegate::COUNTRY), country_name, Qt::ToolTipRole);
m_missingFlags.remove(ip); m_missingFlags.remove(ip);
} }
} }
@ -420,7 +421,7 @@ void PeerListWidget::handleResolved(const QString &ip, const QString &hostname)
void PeerListWidget::handleSortColumnChanged(int col) void PeerListWidget::handleSortColumnChanged(int col)
{ {
if (col == 0) { if (col == PeerListDelegate::COUNTRY) {
qDebug("Sorting by decoration"); qDebug("Sorting by decoration");
m_proxyModel->setSortRole(Qt::ToolTipRole); m_proxyModel->setSortRole(Qt::ToolTipRole);
} else { } else {

3
src/properties/peerlistwidget.h

@ -36,6 +36,7 @@
#include <QPointer> #include <QPointer>
#include <QSet> #include <QSet>
#include <libtorrent/peer_info.hpp> #include <libtorrent/peer_info.hpp>
#include "peerlistsortmodel.h"
#include "qtorrenthandle.h" #include "qtorrenthandle.h"
#include "misc.h" #include "misc.h"
@ -88,7 +89,7 @@ private:
private: private:
QStandardItemModel *m_listModel; QStandardItemModel *m_listModel;
PeerListDelegate *m_listDelegate; PeerListDelegate *m_listDelegate;
QSortFilterProxyModel *m_proxyModel; PeerListSortModel *m_proxyModel;
QHash<QString, QStandardItem*> m_peerItems; QHash<QString, QStandardItem*> m_peerItems;
QHash<QString, boost::asio::ip::tcp::endpoint> m_peerEndpoints; QHash<QString, boost::asio::ip::tcp::endpoint> m_peerEndpoints;
QSet<QString> m_missingFlags; QSet<QString> m_missingFlags;

1
src/properties/properties.pri

@ -10,6 +10,7 @@ HEADERS += $$PWD/propertieswidget.h \
$$PWD/trackerlist.h \ $$PWD/trackerlist.h \
$$PWD/downloadedpiecesbar.h \ $$PWD/downloadedpiecesbar.h \
$$PWD/peerlistdelegate.h \ $$PWD/peerlistdelegate.h \
$$PWD/peerlistsortmodel.h \
$$PWD/peeraddition.h \ $$PWD/peeraddition.h \
$$PWD/trackersadditiondlg.h \ $$PWD/trackersadditiondlg.h \
$$PWD/pieceavailabilitybar.h \ $$PWD/pieceavailabilitybar.h \

Loading…
Cancel
Save