From 682377ff669b53015e3564a3838b57d213a290d5 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sat, 5 Jun 2010 13:43:36 +0000 Subject: [PATCH] Merge msvc compilation fixes from stable branch --- src/bittorrent.cpp | 9 +- src/engineselectdlg.cpp | 5 +- src/feeddownloader.h | 2 +- src/misc.cpp | 2 - src/peerlistwidget.cpp | 10 +- src/propertieswidget.cpp | 10 +- src/src.pro | 63 ++++-- src/supportedengines.h | 10 +- src/torrentadditiondlg.h | 9 +- src/trackerlist.cpp | 383 +++++++++++++++++++++++++++++++++++++ src/trackerlist.h | 363 ++--------------------------------- src/transferlistwidget.cpp | 15 +- 12 files changed, 487 insertions(+), 394 deletions(-) create mode 100644 src/trackerlist.cpp diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index 17879aee0..939138e56 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -1345,6 +1345,7 @@ void Bittorrent::enableLSD(bool b) { void Bittorrent::loadSessionState() { const QString state_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("ses_state"); + if(!QFile::exists(state_path)) return; #ifdef LIBTORRENT_0_15 std::vector in; if (load_file(state_path.toLocal8Bit().constData(), in) == 0) @@ -1865,12 +1866,12 @@ void Bittorrent::addConsoleMessage(QString msg, QString) { } // We need this for urllib in search engine plugins #ifdef Q_WS_WIN - char proxystr[512]; + QString proxyStr; if(proxySettings.type == proxy_settings::socks5 || proxySettings.type == proxy_settings::socks5_pw) - snprintf(proxystr, 512, "sock_proxy=%s", proxy_str.toLocal8Bit().constData()); + proxyStr = "sock_proxy=" + proxy_str; else - snprintf(proxystr, 512, "http_proxy=%s", proxy_str.toLocal8Bit().constData()); - putenv(proxystr); + proxyStr = "http_proxy=" + proxy_str; + putenv(proxyStr.toLocal8Bit().constData()); #else qDebug("HTTP communications proxy string: %s", qPrintable(proxy_str)); if(proxySettings.type == proxy_settings::socks5 || proxySettings.type == proxy_settings::socks5_pw) diff --git a/src/engineselectdlg.cpp b/src/engineselectdlg.cpp index e0a30ae85..1407877ed 100644 --- a/src/engineselectdlg.cpp +++ b/src/engineselectdlg.cpp @@ -125,18 +125,17 @@ void engineSelectDlg::toggleEngineState(QTreeWidgetItem *item, int) { void engineSelectDlg::displayContextMenu(const QPoint&) { QMenu myContextMenu(this); - QModelIndex index; // Enable/disable pause/start action given the DL state QList items = pluginsTree->selectedItems(); bool has_enable = false, has_disable = false; QTreeWidgetItem *item; foreach(item, items) { QString id = item->text(ENGINE_ID); - if(supported_engines->value(id)->isEnabled() and !has_disable) { + if(supported_engines->value(id)->isEnabled() && !has_disable) { myContextMenu.addAction(actionDisable); has_disable = true; } - if(!supported_engines->value(id)->isEnabled() and !has_enable) { + if(!supported_engines->value(id)->isEnabled() && !has_enable) { myContextMenu.addAction(actionEnable); has_enable = true; } diff --git a/src/feeddownloader.h b/src/feeddownloader.h index 49914d9e6..b033f82a9 100644 --- a/src/feeddownloader.h +++ b/src/feeddownloader.h @@ -297,7 +297,7 @@ protected slots: default_path = QDir::homePath(); } QString dir = QFileDialog::getExistingDirectory(this, tr("Choose save path"), QDir::homePath()); - if(!dir.isNull() and QDir(dir).exists()) { + if(!dir.isNull() && QDir(dir).exists()) { savepath_line->setText(dir); } } diff --git a/src/misc.cpp b/src/misc.cpp index 3a5194201..48753d344 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -370,8 +370,6 @@ QString misc::cacheLocation() { return location; } -long long misc::freeDiskSpaceOnPath(QString path); - // return best userfriendly storage unit (B, KiB, MiB, GiB, TiB) // use Binary prefix standards from IEC 60027-2 // see http://en.wikipedia.org/wiki/Kilobyte diff --git a/src/peerlistwidget.cpp b/src/peerlistwidget.cpp index 8403a84b6..fead64b9d 100644 --- a/src/peerlistwidget.cpp +++ b/src/peerlistwidget.cpp @@ -44,6 +44,8 @@ #include #include +Q_DECLARE_METATYPE(QList) + PeerListWidget::PeerListWidget(PropertiesWidget *parent): properties(parent), display_flags(false) { // Visual settings setRootIsDecorated(false); @@ -244,10 +246,10 @@ void PeerListWidget::clear() { void PeerListWidget::loadSettings() { QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QVariantList contentColsWidths = settings.value(QString::fromUtf8("TorrentProperties/Peers/peersColsWidth"), QVariantList()).toList(); + QList contentColsWidths = settings.value(QString::fromUtf8("TorrentProperties/Peers/peersColsWidth"), QVariantList()).value >(); if(!contentColsWidths.empty()) { for(int i=0; i contentColsWidths; for(int i=0; icolumnCount(); ++i) { contentColsWidths.append(columnWidth(i)); } - settings.setValue(QString::fromUtf8("TorrentProperties/Peers/peersColsWidth"), contentColsWidths); + settings.setValue(QString::fromUtf8("TorrentProperties/Peers/peersColsWidth"), QVariant::fromValue >(contentColsWidths)); // Save sorted column Qt::SortOrder sortOrder = header()->sortIndicatorOrder(); QString sortOrderLetter; diff --git a/src/propertieswidget.cpp b/src/propertieswidget.cpp index 89a3b659e..bb3e36a46 100644 --- a/src/propertieswidget.cpp +++ b/src/propertieswidget.cpp @@ -52,6 +52,8 @@ #include "downloadedpiecesbar.h" #include "pieceavailabilitybar.h" +Q_DECLARE_METATYPE(QList) + #ifdef Q_WS_MAC #define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px; margin-left: 8px; margin-right: 8px;}" #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: 8px; margin-right: 8px;}" @@ -265,12 +267,12 @@ void PropertiesWidget::loadTorrentInfos(QTorrentHandle &_h) { void PropertiesWidget::readSettings() { QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QVariantList contentColsWidths = settings.value(QString::fromUtf8("TorrentProperties/filesColsWidth"), QVariantList()).toList(); + QList contentColsWidths = settings.value(QString::fromUtf8("TorrentProperties/filesColsWidth"), QVariantList()).value >(); if(contentColsWidths.empty()) { filesList->header()->resizeSection(0, 300); } else { for(int i=0; isetColumnWidth(i, contentColsWidths.at(i).toInt()); + filesList->setColumnWidth(i, contentColsWidths.at(i)); } } // Restore splitter sizes @@ -292,11 +294,11 @@ void PropertiesWidget::readSettings() { void PropertiesWidget::saveSettings() { QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); settings.setValue("TorrentProperties/Visible", state==VISIBLE); - QVariantList contentColsWidths; + QList contentColsWidths; for(int i=0; icolumnCount(); ++i) { contentColsWidths.append(filesList->columnWidth(i)); } - settings.setValue(QString::fromUtf8("TorrentProperties/filesColsWidth"), contentColsWidths); + settings.setValue(QString::fromUtf8("TorrentProperties/filesColsWidth"), QVariant::fromValue >(contentColsWidths)); // Splitter sizes QSplitter *hSplitter = static_cast(parentWidget()); QList sizes; diff --git a/src/src.pro b/src/src.pro index bb2652f62..561f92190 100644 --- a/src/src.pro +++ b/src/src.pro @@ -22,14 +22,22 @@ DEFINES += VERSION_BUGFIX=0 win32 { # Adapt these paths on Windows - INCLUDEPATH += $$quote(C:/qbittorrent/boost_1_42_0) - INCLUDEPATH += $$quote(C:/qbittorrent/libtorrent-rasterbar-0.14.10/include) - INCLUDEPATH += $$quote(C:/qbittorrent/libtorrent-rasterbar-0.14.10/zlib) - LIBS += -LC:/OpenSSL/ + INCLUDEPATH += $$quote(C:/qbittorrent/msvc/boost_1_42_0) + #INCLUDEPATH += $$quote(C:/qbittorrent/msvc/libtorrent-rasterbar-0.14.10/include) + #INCLUDEPATH += $$quote(C:/qbittorrent/msvc/libtorrent-rasterbar-0.14.10/zlib) + INCLUDEPATH += $$quote(C:/qbittorrent/msvc/RC_0_15/include) + INCLUDEPATH += $$quote(C:/qbittorrent/msvc/RC_0_15/zlib) + #DEFINES += LIBTORRENT_0_15 + + LIBS += -LC:/OpenSSL/lib/VC + LIBS += -LC:/qbittorrent/msvc/boost_1_42_0/stage/lib DEFINES += _WIN32_WINNT=0x0601 DEFINES += _WIN32_IE=0x0400 DEFINES += _WIN32_WINDOWS + + QMAKE_CXXFLAGS_STL_ON = -EHa + QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHa } # NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL @@ -136,13 +144,25 @@ DEFINES += QT_USE_FAST_CONCATENATION QT_USE_FAST_OPERATOR_PLUS win32 { RC_FILE = qbittorrent.rc + LIBS += "/nodefaultlib:"msvcrt.lib" + LIBS += "/nodefaultlib:"msvcrtd.lib" + contains(DEBUG_MODE, 1) { + LIBS += "/nodefaultlib:"libcmt.lib" + } + # Adapt these paths on Windows - LIBS += C:/qbittorrent/libs/libtorrent.lib \ - C:/qbittorrent/libs/libboost_system-mgw44-mt-s.lib \ - C:/qbittorrent/libs/libboost_filesystem-mgw44-mt-s.lib \ - C:/qbittorrent/libs/libboost_thread-mgw44-mt-s.lib \ - C:/Qt/2010.02.1/mingw/lib/libwsock32.a \ - C:/Qt/2010.02.1/mingw/lib/libws2_32.a #\ + contains(DEBUG_MODE, 1) { + LIBS += C:/qbittorrent/msvc/libs/libtorrent-0.15d.lib + } else { + LIBS += C:/qbittorrent/msvc/libs/libtorrent.lib + } + #LIBS += C:/qbittorrent/msvc/libs/libtorrent.lib #\ + #C:/qbittorrent/msvc/libs/libboost_system-vc90-mt-s.lib \ + #C:/qbittorrent/msvc/libs/libboost_filesystem-vc90-mt-s.lib \ + #C:/qbittorrent/msvc/libs/libboost_thread-vc90-mt-s.lib \ + #C:/qbittorrent/msvc/libs/libboost_date_time-vc90-mt-s.lib \ + #C:/Qt/2010.02.1/mingw/lib/libwsock32.a \ + #C:/Qt/2010.02.1/mingw/lib/libws2_32.a \ # C:/OpenSSL/lib/MinGW/ssleay32.a \ # C:/OpenSSL/lib/MinGW/libeay32.a \ # -LC:/Qt/2010.02.1/mingw/lib/ @@ -151,12 +171,18 @@ win32 { # C:/Qt/2010.02.1/mingw/lib/libgdi32.a \ # Dynamic linking against SSL since QtNetwork requires it at runtime anyway - LIBS += -lssleay32 \ - -leay32 #\ -# -lws2_32 \ -# -lwsock32 \ -# -ladvapi32 \ -# -lwinmm + #LIBS += -lws2_32 \ + # -lwsock32 \ + # -ladvapi32 \ + # -lwinmm \ + # -lssleay32MT \ + # -llibeay32MT + # -lshell32 \ + + #LIBS += gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib advapi32.lib shell32.lib kernel32.lib uuid.lib + LIBS += advapi32.lib shell32.lib + LIBS += libeay32MT.lib ssleay32MT.lib + } os2:LIBS += -ltorrent-rasterbar \ @@ -336,11 +362,12 @@ SOURCES += main.cpp \ engineselectdlg.cpp \ searchtab.cpp \ ico.cpp \ - rss.cpp \ + rss.cpp \ transferlistwidget.cpp \ propertieswidget.cpp \ peerlistwidget.cpp \ - cookiesdlg.cpp + cookiesdlg.cpp \ + trackerlist.cpp DESTDIR = . diff --git a/src/supportedengines.h b/src/supportedengines.h index 6befad83d..3bf188d2a 100644 --- a/src/supportedengines.h +++ b/src/supportedengines.h @@ -75,8 +75,8 @@ public: url = engine_elem.elementsByTagName("url").at(0).toElement().text(); supported_categories = engine_elem.elementsByTagName("categories").at(0).toElement().text().split(" "); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QVariantList disabled_engines = settings.value(QString::fromUtf8("SearchEngines/disabledEngines"), QVariantList()).toList(); - enabled = !disabled_engines.contains(QVariant(name)); + QStringList disabled_engines = settings.value(QString::fromUtf8("SearchEngines/disabledEngines"), QStringList()).toStringList(); + enabled = !disabled_engines.contains(name); } QString getName() const { return name; } @@ -88,11 +88,11 @@ public: enabled = _enabled; // Save to Hard disk QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QVariantList disabled_engines = settings.value(QString::fromUtf8("SearchEngines/disabledEngines"), QVariantList()).toList(); + QStringList disabled_engines = settings.value(QString::fromUtf8("SearchEngines/disabledEngines"), QStringList()).toStringList(); if(enabled) { - disabled_engines.removeAll(QVariant(name)); + disabled_engines.removeAll(name); } else { - disabled_engines.append(QVariant(name)); + disabled_engines.append(name); } settings.setValue("SearchEngines/disabledEngines", disabled_engines); } diff --git a/src/torrentadditiondlg.h b/src/torrentadditiondlg.h index cf831a002..714bb6477 100644 --- a/src/torrentadditiondlg.h +++ b/src/torrentadditiondlg.h @@ -56,6 +56,7 @@ #include "transferlistwidget.h" using namespace libtorrent; +Q_DECLARE_METATYPE(QList) class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{ Q_OBJECT @@ -125,12 +126,12 @@ public: resize(settings.value(QString::fromUtf8("TorrentAdditionDlg/size"), size()).toSize()); move(settings.value(QString::fromUtf8("TorrentAdditionDlg/pos"), misc::screenCenter(this)).toPoint()); // Restore column width - const QVariantList &contentColsWidths = settings.value(QString::fromUtf8("TorrentAdditionDlg/filesColsWidth"), QVariantList()).toList(); + const QList &contentColsWidths = settings.value(QString::fromUtf8("TorrentAdditionDlg/filesColsWidth")).value >(); if(contentColsWidths.empty()) { torrentContentList->header()->resizeSection(0, 200); } else { for(int i=0; isetColumnWidth(i, contentColsWidths.at(i).toInt()); + torrentContentList->setColumnWidth(i, contentColsWidths.at(i)); } } } @@ -138,12 +139,12 @@ public: void saveSettings() { if(is_magnet) return; QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QVariantList contentColsWidths; + QList contentColsWidths; // -1 because we hid PROGRESS column for(int i=0; icolumnCount()-1; ++i) { contentColsWidths.append(torrentContentList->columnWidth(i)); } - settings.setValue(QString::fromUtf8("TorrentAdditionDlg/filesColsWidth"), contentColsWidths); + settings.setValue(QString::fromUtf8("TorrentAdditionDlg/filesColsWidth"), QVariant::fromValue >(contentColsWidths)); settings.setValue("TorrentAdditionDlg/size", size()); settings.setValue("TorrentAdditionDlg/pos", pos()); } diff --git a/src/trackerlist.cpp b/src/trackerlist.cpp new file mode 100644 index 000000000..d0343d82b --- /dev/null +++ b/src/trackerlist.cpp @@ -0,0 +1,383 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include "trackerlist.h" +#include "propertieswidget.h" +#include "trackersadditiondlg.h" +#include "misc.h" +#include "bittorrent.h" + +Q_DECLARE_METATYPE(QList) + +TrackerList::TrackerList(PropertiesWidget *properties): QTreeWidget(), properties(properties) { + // Graphical settings + setRootIsDecorated(false); + setAllColumnsShowFocus(true); + setItemsExpandable(false); + setSelectionMode(QAbstractItemView::ExtendedSelection); + // Context menu + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint))); + // Set header + QStringList header; + header << tr("URL"); + header << tr("Status"); + header << tr("Peers"); + header << tr("Message"); + setHeaderItem(new QTreeWidgetItem(header)); + dht_item = new QTreeWidgetItem(QStringList("** "+tr("[DHT]")+" **")); + insertTopLevelItem(0, dht_item); + setRowColor(0, QColor("grey")); + pex_item = new QTreeWidgetItem(QStringList("** "+tr("[PeX]")+" **")); + insertTopLevelItem(1, pex_item); + setRowColor(1, QColor("grey")); + lsd_item = new QTreeWidgetItem(QStringList("** "+tr("[LSD]")+" **")); + insertTopLevelItem(2, lsd_item); + setRowColor(2, QColor("grey")); + loadSettings(); +} + +TrackerList::~TrackerList() { + saveSettings(); +} + +QList TrackerList::getSelectedTrackerItems() const { + QList selected_items = selectedItems(); + QList selected_trackers; + foreach(QTreeWidgetItem *item, selectedItems()) { + if(indexOfTopLevelItem(item) >= NB_STICKY_ITEM) { // Ignore STICKY ITEMS + selected_trackers << item; + } + } + return selected_trackers; +} + +void TrackerList::setRowColor(int row, QColor color) { + unsigned int nbColumns = columnCount(); + QTreeWidgetItem *item = topLevelItem(row); + for(unsigned int i=0; isetData(i, Qt::ForegroundRole, color); + } +} + +#ifndef LIBTORRENT_0_15 +void TrackerList::moveSelectionUp() { + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) { + clear(); + return; + } + QList selected_items = getSelectedTrackerItems(); + if(selected_items.isEmpty()) return; + bool change = false; + foreach(QTreeWidgetItem *item, selected_items){ + int index = indexOfTopLevelItem(item); + if(index > NB_STICKY_ITEM) { + insertTopLevelItem(index-1, takeTopLevelItem(index)); + change = true; + } + } + if(!change) return; + // Restore selection + QItemSelectionModel *selection = selectionModel(); + foreach(QTreeWidgetItem *item, selected_items) { + selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select); + } + setSelectionModel(selection); + // Update torrent trackers + std::vector trackers; + for(int i=NB_STICKY_ITEM; idata(COL_URL, Qt::DisplayRole).toString(); + announce_entry e(tracker_url.toStdString()); + e.tier = i-NB_STICKY_ITEM; + trackers.push_back(e); + } + h.replace_trackers(trackers); + // Reannounce + h.force_reannounce(); +} + +void TrackerList::moveSelectionDown() { + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) { + clear(); + return; + } + QList selected_items = getSelectedTrackerItems(); + if(selected_items.isEmpty()) return; + bool change = false; + for(int i=selectedItems().size()-1; i>= 0; --i) { + int index = indexOfTopLevelItem(selected_items.at(i)); + if(index < topLevelItemCount()-1) { + insertTopLevelItem(index+1, takeTopLevelItem(index)); + change = true; + } + } + if(!change) return; + // Restore selection + QItemSelectionModel *selection = selectionModel(); + foreach(QTreeWidgetItem *item, selected_items) { + selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select); + } + setSelectionModel(selection); + // Update torrent trackers + std::vector trackers; + for(int i=NB_STICKY_ITEM; idata(COL_URL, Qt::DisplayRole).toString(); + announce_entry e(tracker_url.toStdString()); + e.tier = i-NB_STICKY_ITEM; + trackers.push_back(e); + } + h.replace_trackers(trackers); + // Reannounce + h.force_reannounce(); +} +#endif + +void TrackerList::clear() { + qDeleteAll(tracker_items.values()); + tracker_items.clear(); + dht_item->setText(COL_PEERS, ""); + dht_item->setText(COL_STATUS, ""); + dht_item->setText(COL_MSG, ""); + pex_item->setText(COL_PEERS, ""); + pex_item->setText(COL_STATUS, ""); + pex_item->setText(COL_MSG, ""); + lsd_item->setText(COL_PEERS, ""); + lsd_item->setText(COL_STATUS, ""); + lsd_item->setText(COL_MSG, ""); +} + +void TrackerList::loadStickyItems(const QTorrentHandle &h) { + // XXX: libtorrent should provide this info... + // Count peers from DHT, LSD, PeX + uint nb_dht=0, nb_lsd=0, nb_pex=0; + std::vector peers; + h.get_peer_info(peers); + std::vector::iterator it; + for(it=peers.begin(); it!=peers.end(); it++) { + if(it->source & peer_info::dht) + ++nb_dht; + if(it->source & peer_info::lsd) + ++nb_lsd; + if(it->source & peer_info::pex) + ++nb_pex; + } + // load DHT information + if(properties->getBTSession()->isDHTEnabled() && h.has_metadata() && !h.priv()) { + dht_item->setText(COL_STATUS, tr("Working")); + } else { + dht_item->setText(COL_STATUS, tr("Disabled")); + } + dht_item->setText(COL_PEERS, QString::number(nb_dht)); + if(h.has_metadata() && h.priv()) { + dht_item->setText(COL_MSG, tr("This torrent is private")); + } + // Load PeX Information + pex_item->setText(COL_STATUS, tr("Working")); + pex_item->setText(COL_PEERS, QString::number(nb_pex)); + // Load LSD Information + if(properties->getBTSession()->isLSDEnabled()) + lsd_item->setText(COL_STATUS, tr("Working")); + else + lsd_item->setText(COL_STATUS, tr("Disabled")); + lsd_item->setText(COL_PEERS, QString::number(nb_lsd)); +} + +void TrackerList::loadTrackers() { + // Load trackers from torrent handle + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + loadStickyItems(h); + // Load actual trackers information + QHash trackers_data = properties->getBTSession()->getTrackersInfo(h.hash()); + QStringList old_trackers_urls = tracker_items.keys(); + std::vector trackers = h.trackers(); + std::vector::iterator it; + for(it = trackers.begin(); it != trackers.end(); it++) { + QStringList item_list; + QString tracker_url = misc::toQString(it->url); + QTreeWidgetItem *item = tracker_items.value(tracker_url, 0); + if(!item) { + item = new QTreeWidgetItem(); + item->setText(COL_URL, tracker_url); + addTopLevelItem(item); + tracker_items[tracker_url] = item; + } else { + old_trackers_urls.removeOne(tracker_url); + } + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + QString error_message = data.last_message.trimmed(); +#ifdef LIBTORRENT_0_15 + if(it->verified) { + item->setText(COL_STATUS, tr("Working")); + item->setText(COL_MSG, ""); + } else { + if(it->updating && it->fails == 0) { + item->setText(COL_STATUS, tr("Updating...")); + item->setText(COL_MSG, ""); + } else { + if(it->fails > 0) { + item->setText(COL_STATUS, tr("Not working")); + item->setText(COL_MSG, error_message); + } else { + item->setText(COL_STATUS, tr("Not contacted yet")); + item->setText(COL_MSG, ""); + } + } + } +#else + if(data.verified) { + item->setText(COL_STATUS, tr("Working")); + item->setText(COL_MSG, ""); + } else { + if(data.fail_count > 0) { + item->setText(COL_STATUS, tr("Not working")); + item->setText(COL_MSG, error_message); + } else { + item->setText(COL_STATUS, tr("Not contacted yet")); + item->setText(COL_MSG, ""); + } + } +#endif + item->setText(COL_PEERS, QString::number(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers)); + } + // Remove old trackers + foreach(const QString &tracker, old_trackers_urls) { + delete tracker_items.take(tracker); + } +} + +// Ask the user for new trackers and add them to the torrent +void TrackerList::askForTrackers(){ + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + QStringList trackers = TrackersAdditionDlg::askForTrackers(h); + if(!trackers.empty()) { + foreach(const QString& tracker, trackers) { + announce_entry url(tracker.toStdString()); + url.tier = 0; + h.add_tracker(url); + } + // Reannounce to new trackers + h.force_reannounce(); + // Reload tracker list + loadTrackers(); + // XXX: I don't think this is necessary now + //BTSession->saveTrackerFile(h.hash()); + } +} + +void TrackerList::deleteSelectedTrackers(){ + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) { + clear(); + return; + } + QList selected_items = getSelectedTrackerItems(); + if(selected_items.isEmpty()) return; + QStringList urls_to_remove; + foreach(QTreeWidgetItem *item, selected_items){ + QString tracker_url = item->data(COL_URL, Qt::DisplayRole).toString(); + urls_to_remove << tracker_url; + tracker_items.remove(tracker_url); + delete item; + } + // Iterate of trackers and remove selected ones + std::vector trackers = h.trackers(); + std::vector::iterator it = trackers.begin(); + while(it != trackers.end()) { + int index = urls_to_remove.indexOf(misc::toQString((*it).url)); + if(index >= 0) { + trackers.erase(it); + urls_to_remove.removeAt(index); + } else { + it++; + } + } + h.replace_trackers(trackers); + h.force_reannounce(); + // Reload Trackers + loadTrackers(); + //XXX: I don't think this is necessary + //BTSession->saveTrackerFile(h.hash()); +} + +void TrackerList::showTrackerListMenu(QPoint) { + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid() || !h.has_metadata()) return; + QList selected_items = getSelectedTrackerItems(); + QMenu menu; + // Add actions + QAction *addAct = menu.addAction(QIcon(":/Icons/oxygen/list-add.png"), tr("Add a new tracker")); + QAction *delAct = 0; + if(!getSelectedTrackerItems().isEmpty()) { + delAct = menu.addAction(QIcon(":/Icons/oxygen/list-remove.png"), "Remove tracker"); + } + QAction *act = menu.exec(QCursor::pos()); + if(act == 0) return; + if(act == addAct) { + askForTrackers(); + return; + } + if(act == delAct) { + deleteSelectedTrackers(); + return; + } +} + +void TrackerList::loadSettings() { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + QList contentColsWidths = settings.value(QString::fromUtf8("TorrentProperties/Trackers/trackersColsWidth")).value >(); + if(!contentColsWidths.empty()) { + for(int i=0; i contentColsWidths; + for(int i=0; i >(contentColsWidths)); +} diff --git a/src/trackerlist.h b/src/trackerlist.h index ee376fa7d..45ec383fe 100644 --- a/src/trackerlist.h +++ b/src/trackerlist.h @@ -32,21 +32,16 @@ #define TRACKERLIST_H #include -#include -#include -#include -#include -#include -#include -#include -#include "propertieswidget.h" -#include "trackersadditiondlg.h" -#include "misc.h" -#include "bittorrent.h" +#include + +#include "qtorrenthandle.h" enum TrackerListColumn {COL_URL, COL_STATUS, COL_PEERS, COL_MSG}; #define NB_STICKY_ITEM 3 +struct QTreeWidgetItem; +struct PropertiesWidget; + class TrackerList: public QTreeWidget { Q_OBJECT @@ -58,346 +53,28 @@ private: QTreeWidgetItem* lsd_item; public: - TrackerList(PropertiesWidget *properties): QTreeWidget(), properties(properties) { - // Graphical settings - setRootIsDecorated(false); - setAllColumnsShowFocus(true); - setItemsExpandable(false); - setSelectionMode(QAbstractItemView::ExtendedSelection); - // Context menu - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint))); - // Set header - QStringList header; - header << tr("URL"); - header << tr("Status"); - header << tr("Peers"); - header << tr("Message"); - setHeaderItem(new QTreeWidgetItem(header)); - dht_item = new QTreeWidgetItem(QStringList("** "+tr("[DHT]")+" **")); - insertTopLevelItem(0, dht_item); - setRowColor(0, QColor("grey")); - pex_item = new QTreeWidgetItem(QStringList("** "+tr("[PeX]")+" **")); - insertTopLevelItem(1, pex_item); - setRowColor(1, QColor("grey")); - lsd_item = new QTreeWidgetItem(QStringList("** "+tr("[LSD]")+" **")); - insertTopLevelItem(2, lsd_item); - setRowColor(2, QColor("grey")); - loadSettings(); - } - - ~TrackerList() { - saveSettings(); - } + TrackerList(PropertiesWidget *properties); + ~TrackerList(); protected: - QList getSelectedTrackerItems() const { - QList selected_items = selectedItems(); - QList selected_trackers; - foreach(QTreeWidgetItem *item, selectedItems()) { - if(indexOfTopLevelItem(item) >= NB_STICKY_ITEM) { // Ignore STICKY ITEMS - selected_trackers << item; - } - } - return selected_trackers; - } + QList getSelectedTrackerItems() const; public slots: - - void setRowColor(int row, QColor color) { - unsigned int nbColumns = columnCount(); - QTreeWidgetItem *item = topLevelItem(row); - for(unsigned int i=0; isetData(i, Qt::ForegroundRole, color); - } - } + void setRowColor(int row, QColor color); #ifndef LIBTORRENT_0_15 - void moveSelectionUp() { - QTorrentHandle h = properties->getCurrentTorrent(); - if(!h.is_valid()) { - clear(); - return; - } - QList selected_items = getSelectedTrackerItems(); - if(selected_items.isEmpty()) return; - bool change = false; - foreach(QTreeWidgetItem *item, selected_items){ - int index = indexOfTopLevelItem(item); - if(index > NB_STICKY_ITEM) { - insertTopLevelItem(index-1, takeTopLevelItem(index)); - change = true; - } - } - if(!change) return; - // Restore selection - QItemSelectionModel *selection = selectionModel(); - foreach(QTreeWidgetItem *item, selected_items) { - selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select); - } - setSelectionModel(selection); - // Update torrent trackers - std::vector trackers; - for(int i=NB_STICKY_ITEM; idata(COL_URL, Qt::DisplayRole).toString(); - announce_entry e(tracker_url.toStdString()); - e.tier = i-NB_STICKY_ITEM; - trackers.push_back(e); - } - h.replace_trackers(trackers); - // Reannounce - h.force_reannounce(); - } - - void moveSelectionDown() { - QTorrentHandle h = properties->getCurrentTorrent(); - if(!h.is_valid()) { - clear(); - return; - } - QList selected_items = getSelectedTrackerItems(); - if(selected_items.isEmpty()) return; - bool change = false; - for(int i=selectedItems().size()-1; i>= 0; --i) { - int index = indexOfTopLevelItem(selected_items.at(i)); - if(index < topLevelItemCount()-1) { - insertTopLevelItem(index+1, takeTopLevelItem(index)); - change = true; - } - } - if(!change) return; - // Restore selection - QItemSelectionModel *selection = selectionModel(); - foreach(QTreeWidgetItem *item, selected_items) { - selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select); - } - setSelectionModel(selection); - // Update torrent trackers - std::vector trackers; - for(int i=NB_STICKY_ITEM; idata(COL_URL, Qt::DisplayRole).toString(); - announce_entry e(tracker_url.toStdString()); - e.tier = i-NB_STICKY_ITEM; - trackers.push_back(e); - } - h.replace_trackers(trackers); - // Reannounce - h.force_reannounce(); - } + void moveSelectionUp(); + void moveSelectionDown(); #endif - void clear() { - qDeleteAll(tracker_items.values()); - tracker_items.clear(); - dht_item->setText(COL_PEERS, ""); - dht_item->setText(COL_STATUS, ""); - dht_item->setText(COL_MSG, ""); - pex_item->setText(COL_PEERS, ""); - pex_item->setText(COL_STATUS, ""); - pex_item->setText(COL_MSG, ""); - lsd_item->setText(COL_PEERS, ""); - lsd_item->setText(COL_STATUS, ""); - lsd_item->setText(COL_MSG, ""); - } - - void loadStickyItems(const QTorrentHandle &h) { - // XXX: libtorrent should provide this info... - // Count peers from DHT, LSD, PeX - uint nb_dht=0, nb_lsd=0, nb_pex=0; - std::vector peers; - h.get_peer_info(peers); - std::vector::iterator it; - for(it=peers.begin(); it!=peers.end(); it++) { - if(it->source & peer_info::dht) - ++nb_dht; - if(it->source & peer_info::lsd) - ++nb_lsd; - if(it->source & peer_info::pex) - ++nb_pex; - } - // load DHT information - if(properties->getBTSession()->isDHTEnabled() && h.has_metadata() && !h.priv()) { - dht_item->setText(COL_STATUS, tr("Working")); - } else { - dht_item->setText(COL_STATUS, tr("Disabled")); - } - dht_item->setText(COL_PEERS, QString::number(nb_dht)); - if(h.has_metadata() && h.priv()) { - dht_item->setText(COL_MSG, tr("This torrent is private")); - } - // Load PeX Information - pex_item->setText(COL_STATUS, tr("Working")); - pex_item->setText(COL_PEERS, QString::number(nb_pex)); - // Load LSD Information - if(properties->getBTSession()->isLSDEnabled()) - lsd_item->setText(COL_STATUS, tr("Working")); - else - lsd_item->setText(COL_STATUS, tr("Disabled")); - lsd_item->setText(COL_PEERS, QString::number(nb_lsd)); - } - - void loadTrackers() { - // Load trackers from torrent handle - QTorrentHandle h = properties->getCurrentTorrent(); - if(!h.is_valid()) return; - loadStickyItems(h); - // Load actual trackers information - QHash trackers_data = properties->getBTSession()->getTrackersInfo(h.hash()); - QStringList old_trackers_urls = tracker_items.keys(); - std::vector trackers = h.trackers(); - std::vector::iterator it; - for(it = trackers.begin(); it != trackers.end(); it++) { - QStringList item_list; - QString tracker_url = misc::toQString(it->url); - QTreeWidgetItem *item = tracker_items.value(tracker_url, 0); - if(!item) { - item = new QTreeWidgetItem(); - item->setText(COL_URL, tracker_url); - addTopLevelItem(item); - tracker_items[tracker_url] = item; - } else { - old_trackers_urls.removeOne(tracker_url); - } - TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); - QString error_message = data.last_message.trimmed(); -#ifdef LIBTORRENT_0_15 - if(it->verified) { - item->setText(COL_STATUS, tr("Working")); - item->setText(COL_MSG, ""); - } else { - if(it->updating && it->fails == 0) { - item->setText(COL_STATUS, tr("Updating...")); - item->setText(COL_MSG, ""); - } else { - if(it->fails > 0) { - item->setText(COL_STATUS, tr("Not working")); - item->setText(COL_MSG, error_message); - } else { - item->setText(COL_STATUS, tr("Not contacted yet")); - item->setText(COL_MSG, ""); - } - } - } -#else - if(data.verified) { - item->setText(COL_STATUS, tr("Working")); - item->setText(COL_MSG, ""); - } else { - if(data.fail_count > 0) { - item->setText(COL_STATUS, tr("Not working")); - item->setText(COL_MSG, error_message); - } else { - item->setText(COL_STATUS, tr("Not contacted yet")); - item->setText(COL_MSG, ""); - } - } -#endif - item->setText(COL_PEERS, QString::number(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers)); - } - // Remove old trackers - foreach(const QString &tracker, old_trackers_urls) { - delete tracker_items.take(tracker); - } - } - - // Ask the user for new trackers and add them to the torrent - void askForTrackers(){ - QTorrentHandle h = properties->getCurrentTorrent(); - if(!h.is_valid()) return; - QStringList trackers = TrackersAdditionDlg::askForTrackers(h); - if(!trackers.empty()) { - foreach(const QString& tracker, trackers) { - announce_entry url(tracker.toStdString()); - url.tier = 0; - h.add_tracker(url); - } - // Reannounce to new trackers - h.force_reannounce(); - // Reload tracker list - loadTrackers(); - // XXX: I don't think this is necessary now - //BTSession->saveTrackerFile(h.hash()); - } - } - - void deleteSelectedTrackers(){ - QTorrentHandle h = properties->getCurrentTorrent(); - if(!h.is_valid()) { - clear(); - return; - } - QList selected_items = getSelectedTrackerItems(); - if(selected_items.isEmpty()) return; - QStringList urls_to_remove; - foreach(QTreeWidgetItem *item, selected_items){ - QString tracker_url = item->data(COL_URL, Qt::DisplayRole).toString(); - urls_to_remove << tracker_url; - tracker_items.remove(tracker_url); - delete item; - } - // Iterate of trackers and remove selected ones - std::vector trackers = h.trackers(); - std::vector::iterator it = trackers.begin(); - while(it != trackers.end()) { - int index = urls_to_remove.indexOf(misc::toQString((*it).url)); - if(index >= 0) { - trackers.erase(it); - urls_to_remove.removeAt(index); - } else { - it++; - } - } - h.replace_trackers(trackers); - h.force_reannounce(); - // Reload Trackers - loadTrackers(); - //XXX: I don't think this is necessary - //BTSession->saveTrackerFile(h.hash()); - } - - void showTrackerListMenu(QPoint) { - QTorrentHandle h = properties->getCurrentTorrent(); - if(!h.is_valid() || !h.has_metadata()) return; - QList selected_items = getSelectedTrackerItems(); - QMenu menu; - // Add actions - QAction *addAct = menu.addAction(QIcon(":/Icons/oxygen/list-add.png"), tr("Add a new tracker")); - QAction *delAct = 0; - if(!getSelectedTrackerItems().isEmpty()) { - delAct = menu.addAction(QIcon(":/Icons/oxygen/list-remove.png"), "Remove tracker"); - } - QAction *act = menu.exec(QCursor::pos()); - if(act == 0) return; - if(act == addAct) { - askForTrackers(); - return; - } - if(act == delAct) { - deleteSelectedTrackers(); - return; - } - } - - void loadSettings() { - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QVariantList contentColsWidths = settings.value(QString::fromUtf8("TorrentProperties/Trackers/trackersColsWidth"), QVariantList()).toList(); - if(!contentColsWidths.empty()) { - for(int i=0; i #include +Q_DECLARE_METATYPE(QList) + TransferListWidget::TransferListWidget(QWidget *parent, GUI *main_window, Bittorrent *_BTSession): QTreeView(parent), BTSession(_BTSession), main_window(main_window) { QSettings settings("qBittorrent", "qBittorrent"); @@ -1242,6 +1244,7 @@ void TransferListWidget::saveColWidthList() { QStringList width_list; QStringList new_width_list; const short nbColumns = listModel->columnCount()-1; // HASH is hidden + if(nbColumns <= 0) return; const QString &line = settings.value("TransferListColsWidth", QString()).toString(); if(!line.isEmpty()) { width_list = line.split(' '); @@ -1260,11 +1263,11 @@ void TransferListWidget::saveColWidthList() { } } settings.setValue(QString::fromUtf8("TransferListColsWidth"), new_width_list.join(QString::fromUtf8(" "))); - QVariantList visualIndexes; + QList visualIndexes; for(int i=0; ivisualIndex(i)); } - settings.setValue(QString::fromUtf8("TransferListVisualIndexes"), visualIndexes); + settings.setValue(QString::fromUtf8("TransferListVisualIndexes"), QVariant::fromValue< QList >(visualIndexes)); qDebug("Download list columns width saved"); } @@ -1272,10 +1275,10 @@ void TransferListWidget::saveColWidthList() { bool TransferListWidget::loadColWidthList() { qDebug("Loading columns width for download list"); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - const QString &line = settings.value(QString::fromUtf8("TransferListColsWidth"), QString()).toString(); + QString line = settings.value(QString::fromUtf8("TransferListColsWidth"), QString()).toString(); if(line.isEmpty()) return false; - const QStringList &width_list = line.split(QString::fromUtf8(" ")); + const QStringList width_list = line.split(" "); if(width_list.size() != listModel->columnCount()-1) { qDebug("Corrupted values for transfer list columns sizes"); return false; @@ -1284,7 +1287,7 @@ bool TransferListWidget::loadColWidthList() { for(unsigned int i=0; iresizeSection(i, width_list.at(i).toInt()); } - const QVariantList& visualIndexes = settings.value(QString::fromUtf8("TransferListVisualIndexes"), QVariantList()).toList(); + const QList visualIndexes = settings.value(QString::fromUtf8("TransferListVisualIndexes")).value >(); if(visualIndexes.size() != listModel->columnCount()-1) { qDebug("Corrupted values for transfer list columns indexes"); return false; @@ -1293,7 +1296,7 @@ bool TransferListWidget::loadColWidthList() { do { change = false; for(int i=0;ilogicalIndex(i)).toInt(); + const int new_visual_index = visualIndexes.at(header()->logicalIndex(i)); if(i != new_visual_index) { qDebug("Moving column from %d to %d", header()->logicalIndex(i), new_visual_index); header()->moveSection(i, new_visual_index);