From 94f3323270152a3799cba983a2afa1ab092a9297 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Tue, 17 Nov 2009 11:46:43 +0000 Subject: [PATCH] - New peers can manually be added to a torrent --- Changelog | 1 + src/Icons/oxygen/add_peer.png | Bin 0 -> 644 bytes src/icons.qrc | 1 + src/peer.ui | 109 +++++++++++++++++++++++++++++++++ src/peeraddition.h | 111 ++++++++++++++++++++++++++++++++++ src/peerlistwidget.cpp | 26 ++++++++ src/peerlistwidget.h | 1 + src/qtorrenthandle.cpp | 10 +++ src/qtorrenthandle.h | 2 + src/src.pro | 6 +- 10 files changed, 265 insertions(+), 2 deletions(-) create mode 100644 src/Icons/oxygen/add_peer.png create mode 100644 src/peer.ui create mode 100644 src/peeraddition.h diff --git a/Changelog b/Changelog index 26dd3bc21..95b7e4050 100644 --- a/Changelog +++ b/Changelog @@ -22,6 +22,7 @@ - FEATURE: Make sure torrent files are always sorted by name - FEATURE: Seeds and Peers columns are now sortable - FEATURE: Torrents can be rechecked from Web UI (Stephanos Antaris) + - FEATURE: New peers can manually be added to the torrents - COSMETIC: Merged download / upload lists - COSMETIC: Torrents can be filtered based on their status - COSMETIC: Torrent properties are now displayed in main window diff --git a/src/Icons/oxygen/add_peer.png b/src/Icons/oxygen/add_peer.png new file mode 100644 index 0000000000000000000000000000000000000000..a28a8a2e9b15d06117662dab7e428a05e5af59fe GIT binary patch literal 644 zcmV-~0(Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00FxI00FxJI_%@(00007bV*G`2iXe| z3m^g!PfWuA00IO_L_t(I%Z-w~ixW{4#m~H#$=6IakRgM_AjW8#4Md13QrHQ0TM1%o zr4}n#h}hX~A=n9mU}>Sn7UEwZBG{x!NK(YGX(o`FWM$;BdcnroE!Z1V_hA<2Rf*@q_`TYIO zn$$Tvl-`mg3A5P@VHobr#O0OpZ;yAwSx-LA=Lli|j0M0o$=Sm_V3`1?PSll3l zAP9oJ>-ByA+vfe;3|!YeU9DCS1Oagz|INQXXCKaBd@>#;I2+3_k zgKgU<0G@98ElMOsJ5 zh@$wI5OPnJh*e~R;wWh0t^NNXqvX|4ECuF06088 z#AGu0<$2y)K@>&S?RImFF${-8IF6IpE%^Fpwdw;E2L}h3&1OLgKyJBQqSx!;e>I=a eq3b#Th`#|@1@n@OYG$_p0000Icons/oxygen/unsubscribe.png Icons/oxygen/draw-rectangle.png Icons/oxygen/subscribe16.png + Icons/oxygen/add_peer.png \ No newline at end of file diff --git a/src/peer.ui b/src/peer.ui new file mode 100644 index 000000000..ad92877ed --- /dev/null +++ b/src/peer.ui @@ -0,0 +1,109 @@ + + + addPeerDialog + + + + 0 + 0 + 400 + 112 + + + + + 0 + 0 + + + + Peer addition + + + + + + + + + + + 75 + true + + + + IP + + + Qt::AlignCenter + + + + + + + + + + + + + + + 75 + true + + + + Port + + + Qt::AlignCenter + + + + + + + + 60 + 0 + + + + + 70 + 16777215 + + + + 1000 + + + 65535 + + + 6881 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/src/peeraddition.h b/src/peeraddition.h new file mode 100644 index 000000000..927585b5e --- /dev/null +++ b/src/peeraddition.h @@ -0,0 +1,111 @@ +/* + * 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 PEERADDITION_H +#define PEERADDITION_H + +#include +#include +#include +#include "ui_peer.h" +#include + +class PeerAdditionDlg: public QDialog, private Ui::addPeerDialog { + Q_OBJECT + +private: + bool valid; + +public: + PeerAdditionDlg(QWidget *parent=0): QDialog(parent), valid(false) { + setupUi(this); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(validateInput())); + } + + ~PeerAdditionDlg(){} + + QString getIP() const { + return lineIP->text(); + } + + unsigned short getPort() const { + return spinPort->value(); + } + + bool isValid() const { + return valid; + } + + static boost::asio::ip::tcp::endpoint askForPeerEndpoint() { + boost::asio::ip::tcp::endpoint ep; + PeerAdditionDlg dlg; + dlg.exec(); + if(dlg.isValid()) { + const QRegExp is_ipv6(QString::fromUtf8("[0-9a-f]{4}(:[0-9a-f]{4}){7}"), Qt::CaseInsensitive, QRegExp::RegExp); + const QRegExp is_ipv4(QString::fromUtf8("(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))(\\.(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))){3}"), Qt::CaseInsensitive, QRegExp::RegExp); + QString IP = dlg.getIP(); + if(is_ipv4.exactMatch(IP)) { + // IPv4 + ep = boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string(IP.toLocal8Bit().data()), dlg.getPort()); + } else { + // IPv6 + ep = boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v6::from_string(IP.toLocal8Bit().data()), dlg.getPort()); + } + } + return ep; + } + + +protected slots: + void validateInput() { + const QRegExp is_ipv6(QString::fromUtf8("[0-9a-f]{4}(:[0-9a-f]{4}){7}"), Qt::CaseInsensitive, QRegExp::RegExp); + const QRegExp is_ipv4(QString::fromUtf8("(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))(\\.(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))){3}"), Qt::CaseInsensitive, QRegExp::RegExp); + QString IP = getIP(); + if(is_ipv4.exactMatch(IP)) { + qDebug("Detected IPv4 address: %s", IP.toLocal8Bit().data()); + valid = true; + accept(); + } else { + if(is_ipv6.exactMatch(IP)) { + qDebug("Detected IPv6 address: %s", IP.toLocal8Bit().data()); + valid = true; + accept(); + } else { + QMessageBox::warning(this, tr("Invalid IP"), + tr("The IP you provided is invalid."), + QMessageBox::Ok); + + } + } + } +}; + +#endif // PEERADDITION_H diff --git a/src/peerlistwidget.cpp b/src/peerlistwidget.cpp index c8a0cb789..a3d9b5dfb 100644 --- a/src/peerlistwidget.cpp +++ b/src/peerlistwidget.cpp @@ -34,10 +34,12 @@ #include "preferences.h" #include "propertieswidget.h" #include "geoip.h" +#include "peeraddition.h" #include #include #include #include +#include #include PeerListWidget::PeerListWidget(PropertiesWidget *parent): properties(parent), display_flags(false) { @@ -59,6 +61,9 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent): properties(parent), di proxyModel->setDynamicSortFilter(true); proxyModel->setSourceModel(listModel); setModel(proxyModel); + // Context menu + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showPeerListMenu(QPoint))); // List delegate listDelegate = new PeerListDelegate(this); setItemDelegate(listDelegate); @@ -104,6 +109,27 @@ void PeerListWidget::updatePeerCountryResolutionState() { } } +void PeerListWidget::showPeerListMenu(QPoint) { + QMenu menu; + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + QAction *addPeerAct = 0; + if(!h.is_queued() && !h.is_checking()) { + addPeerAct = menu.addAction(QIcon(":/Icons/oxygen/add_peer.png"), "Add a new peer"); + } + QAction *act = menu.exec(QCursor::pos()); + if(act == addPeerAct) { + boost::asio::ip::tcp::endpoint ep = PeerAdditionDlg::askForPeerEndpoint(); + if(ep != boost::asio::ip::tcp::endpoint()) { + h.connect_peer(ep); + QMessageBox::information(0, tr("Peer addition"), tr("The peer was added to this torrent.")); + } else { + qDebug("No peer was added"); + } + return; + } +} + void PeerListWidget::clear() { qDebug("clearing peer list"); peerItems.clear(); diff --git a/src/peerlistwidget.h b/src/peerlistwidget.h index 4f8f6e7ec..fa0b245ec 100644 --- a/src/peerlistwidget.h +++ b/src/peerlistwidget.h @@ -74,6 +74,7 @@ public slots: protected slots: void loadSettings(); void saveSettings() const; + void showPeerListMenu(QPoint); }; #endif // PEERLISTWIDGET_H diff --git a/src/qtorrenthandle.cpp b/src/qtorrenthandle.cpp index 93fd5876a..253a251a8 100644 --- a/src/qtorrenthandle.cpp +++ b/src/qtorrenthandle.cpp @@ -290,6 +290,11 @@ void QTorrentHandle::file_progress(std::vector& fp) { return h.file_progress(fp); } +bool QTorrentHandle::is_checking() const { + Q_ASSERT(h.is_valid()); + return h.status().state == torrent_status::checking_files || h.status().state == torrent_status::checking_resume_data; +} + size_type QTorrentHandle::all_time_download() { Q_ASSERT(h.is_valid()); return h.status().all_time_download; @@ -498,6 +503,11 @@ void QTorrentHandle::resolve_countries(bool r) { h.resolve_countries(r); } +void QTorrentHandle::connect_peer(asio::ip::tcp::endpoint const& adr, int source) const { + Q_ASSERT(h.is_valid()); + h.connect_peer(adr, source); +} + // // Operators // diff --git a/src/qtorrenthandle.h b/src/qtorrenthandle.h index 71a21b04e..9a9bb0cb1 100644 --- a/src/qtorrenthandle.h +++ b/src/qtorrenthandle.h @@ -109,6 +109,7 @@ class QTorrentHandle { QStringList files_path() const; int num_uploads() const; bool is_seed() const; + bool is_checking() const; bool is_auto_managed() const; qlonglong active_time() const; qlonglong seeding_time() const; @@ -145,6 +146,7 @@ class QTorrentHandle { void move_storage(QString path) const; void super_seeding(bool on) const; void resolve_countries(bool r); + void connect_peer(asio::ip::tcp::endpoint const& adr, int source = 0) const; // // Operators diff --git a/src/src.pro b/src/src.pro index 57e79263a..4cc5210f0 100644 --- a/src/src.pro +++ b/src/src.pro @@ -191,7 +191,8 @@ HEADERS += GUI.h \ peerlistdelegate.h \ reverseresolution.h \ preferences.h \ - geoip.h + geoip.h \ + peeraddition.h FORMS += MainWindow.ui \ options.ui \ about.ui \ @@ -208,7 +209,8 @@ FORMS += MainWindow.ui \ trackersAdd.ui \ console.ui \ FeedDownloader.ui \ - propertiesWidget.ui + propertiesWidget.ui \ + peer.ui SOURCES += GUI.cpp \ main.cpp \ options_imp.cpp \