From 8260159ca466e2eeb62cac18d9eb2afcffbd11a2 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sat, 14 Nov 2009 10:37:45 +0000 Subject: [PATCH] - Initial implementation of Peer list --- src/TransferListDelegate.h | 6 +- src/TransferListWidget.cpp | 6 +- src/peerlistdelegate.h | 75 +++++++++++++++++++++++ src/peerlistwidget.cpp | 120 +++++++++++++++++++++++++++++++++++++ src/peerlistwidget.h | 61 +++++++++++++++++++ src/propertiesWidget.ui | 54 +---------------- src/propertieswidget.cpp | 8 ++- src/propertieswidget.h | 2 + src/qtorrenthandle.cpp | 5 ++ src/qtorrenthandle.h | 1 + src/src.pro | 7 ++- 11 files changed, 283 insertions(+), 62 deletions(-) create mode 100644 src/peerlistdelegate.h create mode 100644 src/peerlistwidget.cpp create mode 100644 src/peerlistwidget.h diff --git a/src/TransferListDelegate.h b/src/TransferListDelegate.h index 8f386a04e..79cd57635 100644 --- a/src/TransferListDelegate.h +++ b/src/TransferListDelegate.h @@ -65,7 +65,7 @@ public: case DLSPEED:{ QItemDelegate::drawBackground(painter, opt, index); double speed = index.data().toDouble(); - QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(speed/1024., 'f', 1))+QString::fromUtf8(" ")+tr("KiB/s")); + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(speed/1024., 'f', 1)+" "+tr("KiB/s")); break; } case RATIO:{ @@ -74,7 +74,7 @@ public: if(ratio > 100.) QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞")); else - QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1))); + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 1)); break; } case PRIORITY: { @@ -91,7 +91,7 @@ public: QStyleOptionProgressBarV2 newopt; double progress = index.data().toDouble()*100.; newopt.rect = opt.rect; - newopt.text = QString(QByteArray::number(progress, 'f', 1))+QString::fromUtf8("%"); + newopt.text = QString::number(progress, 'f', 1)+"%"; newopt.progress = (int)progress; newopt.maximum = 100; newopt.minimum = 0; diff --git a/src/TransferListWidget.cpp b/src/TransferListWidget.cpp index e5d9d84d1..7f95a94a3 100644 --- a/src/TransferListWidget.cpp +++ b/src/TransferListWidget.cpp @@ -59,9 +59,9 @@ TransferListWidget::TransferListWidget(QWidget *parent, bittorrent *_BTSession): listModel = new QStandardItemModel(0,11); listModel->setHeaderData(NAME, Qt::Horizontal, tr("Name", "i.e: file name")); listModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); - listModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded")); - listModel->setHeaderData(DLSPEED, Qt::Horizontal, tr("DL Speed", "i.e: Download speed")); - listModel->setHeaderData(UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed")); + listModel->setHeaderData(PROGRESS, Qt::Horizontal, "%"); + listModel->setHeaderData(DLSPEED, Qt::Horizontal, tr("Down Speed", "i.e: Download speed")); + listModel->setHeaderData(UPSPEED, Qt::Horizontal, tr("Up Speed", "i.e: Upload speed")); listModel->setHeaderData(SEEDSLEECH, Qt::Horizontal, tr("Seeds/Leechers", "i.e: full/partial sources")); listModel->setHeaderData(RATIO, Qt::Horizontal, tr("Ratio")); listModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left")); diff --git a/src/peerlistdelegate.h b/src/peerlistdelegate.h new file mode 100644 index 000000000..7a7889287 --- /dev/null +++ b/src/peerlistdelegate.h @@ -0,0 +1,75 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * 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 : chris@qbittorrent.org + */ + +#ifndef PEERLISTDELEGATE_H +#define PEERLISTDELEGATE_H + +#include +#include "misc.h" + +enum PeerListColumns {IP, CLIENT, PROGRESS, DOWN_SPEED, UP_SPEED, TOT_DOWN, TOT_UP}; + +class PeerListDelegate: public QItemDelegate { + Q_OBJECT + +public: + PeerListDelegate(QObject *parent) : QItemDelegate(parent){} + + ~PeerListDelegate(){} + + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{ + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + switch(index.column()){ + case TOT_DOWN: + case TOT_UP: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); + break; + case DOWN_SPEED: + case UP_SPEED:{ + QItemDelegate::drawBackground(painter, opt, index); + double speed = index.data().toDouble(); + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(speed/1024., 'f', 1)+" "+tr("KiB/s")); + break; + } + case PROGRESS:{ + QItemDelegate::drawBackground(painter, opt, index); + double progress = index.data().toDouble(); + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(progress*100., 'f', 1)+"%"); + break; + } + default: + QItemDelegate::paint(painter, option, index); + } + } + +}; + +#endif // PEERLISTDELEGATE_H diff --git a/src/peerlistwidget.cpp b/src/peerlistwidget.cpp new file mode 100644 index 000000000..6e2d52372 --- /dev/null +++ b/src/peerlistwidget.cpp @@ -0,0 +1,120 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * 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 : chris@qbittorrent.org + */ + +#include "peerlistwidget.h" +#include "peerlistdelegate.h" +#include "misc.h" +#include +#include +#include +#include + +PeerListWidget::PeerListWidget() { + // Visual settings + setRootIsDecorated(false); + setItemsExpandable(false); + setAllColumnsShowFocus(true); + // List Model + listModel = new QStandardItemModel(0, 7); + listModel->setHeaderData(IP, Qt::Horizontal, tr("IP")); + listModel->setHeaderData(CLIENT, Qt::Horizontal, tr("Client", "i.e.: Client application")); + listModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded")); + listModel->setHeaderData(DOWN_SPEED, Qt::Horizontal, tr("Down Speed", "i.e: Download speed")); + listModel->setHeaderData(UP_SPEED, Qt::Horizontal, tr("Up Speed", "i.e: Upload speed")); + listModel->setHeaderData(TOT_DOWN, Qt::Horizontal, tr("Downloaded", "i.e: total data downloaded")); + listModel->setHeaderData(TOT_UP, Qt::Horizontal, tr("Uploaded", "i.e: total data uploaded")); + // Proxy model to support sorting without actually altering the underlying model + proxyModel = new QSortFilterProxyModel(); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSourceModel(listModel); + setModel(proxyModel); + // List delegate + listDelegate = new PeerListDelegate(this); + setItemDelegate(listDelegate); + // Enable sorting + setSortingEnabled(true); +} + +PeerListWidget::~PeerListWidget() { + delete proxyModel; + delete listModel; + delete listDelegate; +} + +void PeerListWidget::loadPeers(QTorrentHandle &h) { + std::vector peers; + h.get_peer_info(peers); + std::vector::iterator itr; + QSet old_peers_set = peerItems.keys().toSet(); + for(itr = peers.begin(); itr != peers.end(); itr++) { + peer_info peer = *itr; + QString peer_ip = misc::toQString(peer.ip.address().to_string()); + if(peerItems.contains(peer_ip)) { + // Update existing peer + updatePeer(peer_ip, peer); + old_peers_set.remove(peer_ip); + } else { + // Add new peer + peerItems[peer_ip] = addPeer(peer_ip, peer); + } + } + // Delete peers that are gone + QSetIterator it(old_peers_set); + while(it.hasNext()) { + QStandardItem *item = peerItems.take(it.next()); + listModel->removeRow(item->row()); + } +} + +QStandardItem* PeerListWidget::addPeer(QString ip, peer_info peer) { + int row = listModel->rowCount(); + // Adding Peer to peer list + listModel->insertRow(row); + listModel->setData(listModel->index(row, IP), ip); + listModel->setData(listModel->index(row, CLIENT), misc::toQString(peer.client)); + listModel->setData(listModel->index(row, PROGRESS), peer.progress); + listModel->setData(listModel->index(row, DOWN_SPEED), peer.payload_down_speed); + listModel->setData(listModel->index(row, UP_SPEED), peer.payload_up_speed); + listModel->setData(listModel->index(row, TOT_DOWN), peer.total_download); + listModel->setData(listModel->index(row, TOT_UP), peer.total_upload); + return listModel->item(row, 0); +} + +void PeerListWidget::updatePeer(QString ip, peer_info peer) { + QStandardItem *item = peerItems.value(ip); + int row = item->row(); + listModel->setData(listModel->index(row, IP), ip); + listModel->setData(listModel->index(row, CLIENT), misc::toQString(peer.client)); + listModel->setData(listModel->index(row, PROGRESS), peer.progress); + listModel->setData(listModel->index(row, DOWN_SPEED), peer.payload_down_speed); + listModel->setData(listModel->index(row, UP_SPEED), peer.payload_up_speed); + listModel->setData(listModel->index(row, TOT_DOWN), peer.total_download); + listModel->setData(listModel->index(row, TOT_UP), peer.total_upload); +} diff --git a/src/peerlistwidget.h b/src/peerlistwidget.h new file mode 100644 index 000000000..51d9ff03f --- /dev/null +++ b/src/peerlistwidget.h @@ -0,0 +1,61 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * 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 : chris@qbittorrent.org + */ + +#ifndef PEERLISTWIDGET_H +#define PEERLISTWIDGET_H + +#include +#include +#include "qtorrenthandle.h" + +class QStandardItemModel; +class QStandardItem; +class QSortFilterProxyModel; +class PeerListDelegate; + +class PeerListWidget : public QTreeView { + +private: + QStandardItemModel *listModel; + PeerListDelegate *listDelegate; + QSortFilterProxyModel * proxyModel; + QHash peerItems; + +public: + PeerListWidget(); + ~PeerListWidget(); + + public slots: + void loadPeers(QTorrentHandle &h); + QStandardItem* addPeer(QString ip, peer_info peer); + void updatePeer(QString ip, peer_info peer); +}; + +#endif // PEERLISTWIDGET_H diff --git a/src/propertiesWidget.ui b/src/propertiesWidget.ui index fc74259d0..cfaff1c6d 100644 --- a/src/propertiesWidget.ui +++ b/src/propertiesWidget.ui @@ -730,59 +730,7 @@ - - - - - false - - - false - - - true - - - false - - - - IP - - - - - Client - - - - - Progress - - - - - Down speed - - - - - Up speed - - - - - Downloaded - - - - - Uploaded - - - - - + diff --git a/src/propertieswidget.cpp b/src/propertieswidget.cpp index 9f0367746..213eab4d8 100644 --- a/src/propertieswidget.cpp +++ b/src/propertieswidget.cpp @@ -47,6 +47,7 @@ #include "PropListDelegate.h" #include "TrackersAdditionDlg.h" #include "TorrentFilesModel.h" +#include "peerlistwidget.h" #define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px; margin-left: 3px; margin-right: 3px;}" #define SELECTED_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px;background-color: rgb(255, 208, 105);margin-left: 3px; margin-right: 3px;}" @@ -90,7 +91,9 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, TransferListWidget *transfer progressBar = new RealProgressBar(this); progressBar->setForegroundColor(Qt::blue); ProgressHLayout->insertWidget(1, progressBar); - //progressBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + // Peers list + peersList = new PeerListWidget(); + peerpage_layout->addWidget(peersList); // Pointers init progressBarUpdater = 0; // Dynamic data refresher @@ -104,6 +107,7 @@ PropertiesWidget::~PropertiesWidget() { delete refreshTimer; if(progressBarUpdater) delete progressBarUpdater; + delete peersList; delete progressBar; delete PropListModel; // Delete QActions @@ -271,6 +275,8 @@ void PropertiesWidget::loadDynamicData() { } lbl_elapsed->setText(elapsed_txt); lbl_connections->setText(QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")"); + // Load peers + peersList->loadPeers(h); // Update ratio info float ratio; if(h.total_payload_download() == 0){ diff --git a/src/propertieswidget.h b/src/propertieswidget.h index 2fa87273d..9e57e46ac 100644 --- a/src/propertieswidget.h +++ b/src/propertieswidget.h @@ -45,6 +45,7 @@ class TorrentFilesModel; class PropListDelegate; class QAction; class torrent_file; +class PeerListWidget; enum Tab {MAIN_TAB, TRACKERS_TAB, PEERS_TAB, URLSEEDS_TAB, FILES_TAB}; enum SlideState {REDUCED, VISIBLE}; @@ -62,6 +63,7 @@ private: SlideState state; TorrentFilesModel *PropListModel; PropListDelegate *PropDelegate; + PeerListWidget *peersList; QAction *actionIgnored; QAction *actionNormal; QAction *actionMaximum; diff --git a/src/qtorrenthandle.cpp b/src/qtorrenthandle.cpp index 8fb03c89a..f863dedfa 100644 --- a/src/qtorrenthandle.cpp +++ b/src/qtorrenthandle.cpp @@ -129,6 +129,11 @@ int QTorrentHandle::num_pieces() const { return h.get_torrent_info().num_pieces(); } +void QTorrentHandle::get_peer_info(std::vector& v) const { + Q_ASSERT(h.is_valid()); + h.get_peer_info(v); +} + size_type QTorrentHandle::total_wanted_done() const { Q_ASSERT(h.is_valid()); return h.status().total_wanted_done; diff --git a/src/qtorrenthandle.h b/src/qtorrenthandle.h index cd76c26cf..8e6d301bd 100644 --- a/src/qtorrenthandle.h +++ b/src/qtorrenthandle.h @@ -116,6 +116,7 @@ class QTorrentHandle { bool is_sequential_download() const; bool super_seeding() const; QString creation_date() const; + void get_peer_info(std::vector&) const; // // Setters diff --git a/src/src.pro b/src/src.pro index efb0a8227..94e31f7e0 100644 --- a/src/src.pro +++ b/src/src.pro @@ -185,7 +185,9 @@ HEADERS += GUI.h \ TransferListFiltersWidget.h \ propertieswidget.h \ TorrentFilesModel.h \ - filesystemwatcher.h + filesystemwatcher.h \ + peerlistwidget.h \ + peerlistdelegate.h FORMS += MainWindow.ui \ options.ui \ about.ui \ @@ -225,5 +227,6 @@ SOURCES += GUI.cpp \ ico.cpp \ rss.cpp \ TransferListWidget.cpp \ - propertieswidget.cpp + propertieswidget.cpp \ + peerlistwidget.cpp DESTDIR = .