diff --git a/src/GUI.cpp b/src/GUI.cpp index ae7ae2946..57aefbcee 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -52,7 +52,7 @@ #include "torrentadditiondlg.h" #include "searchengine.h" #include "rss_imp.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "about_imp.h" #include "trackerlogin.h" #include "options_imp.h" diff --git a/src/console_imp.h b/src/console_imp.h index 90a5cda2d..61874735e 100644 --- a/src/console_imp.h +++ b/src/console_imp.h @@ -31,7 +31,7 @@ #ifndef CONSOLE_H #define CONSOLE_H -#include "bittorrent.h" +#include "qbtsession.h" #include "ui_console.h" using namespace libtorrent; diff --git a/src/feeddownloader.h b/src/feeddownloader.h index 15777ef71..1b58b39f6 100644 --- a/src/feeddownloader.h +++ b/src/feeddownloader.h @@ -42,7 +42,7 @@ #include #include -#include "bittorrent.h" +#include "qbtsession.h" #include "ui_feeddownloader.h" #include "qinisettings.h" diff --git a/src/headlessloader.h b/src/headlessloader.h index 702d23f07..803ad2413 100644 --- a/src/headlessloader.h +++ b/src/headlessloader.h @@ -34,7 +34,7 @@ #include #include #include "preferences.h" -#include "bittorrent.h" +#include "qbtsession.h" class HeadlessLoader: public QObject { Q_OBJECT diff --git a/src/propertieswidget.cpp b/src/propertieswidget.cpp index 880a6f4cb..8af788370 100644 --- a/src/propertieswidget.cpp +++ b/src/propertieswidget.cpp @@ -44,7 +44,7 @@ #include "propertieswidget.h" #include "transferlistwidget.h" #include "torrentpersistentdata.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "proplistdelegate.h" #include "torrentfilesmodel.h" #include "peerlistwidget.h" diff --git a/src/bittorrent.cpp b/src/qtlibtorrent/qbtsession.cpp similarity index 99% rename from src/bittorrent.cpp rename to src/qtlibtorrent/qbtsession.cpp index 49bff2681..ceb3997ba 100644 --- a/src/bittorrent.cpp +++ b/src/qtlibtorrent/qbtsession.cpp @@ -39,7 +39,7 @@ #include "smtp.h" #include "filesystemwatcher.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "misc.h" #include "downloadthread.h" #include "filterparserthread.h" diff --git a/src/bittorrent.h b/src/qtlibtorrent/qbtsession.h similarity index 100% rename from src/bittorrent.h rename to src/qtlibtorrent/qbtsession.h diff --git a/src/qtlibtorrent/qtlibtorrent.pri b/src/qtlibtorrent/qtlibtorrent.pri new file mode 100644 index 000000000..daaa762f3 --- /dev/null +++ b/src/qtlibtorrent/qtlibtorrent.pri @@ -0,0 +1,7 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/qbtsession.h \ + $$PWD/qtorrenthandle.h + +SOURCES += $$PWD/qbtsession.cpp \ + $$PWD/qtorrenthandle.cpp diff --git a/src/qtorrenthandle.cpp b/src/qtlibtorrent/qtorrenthandle.cpp similarity index 100% rename from src/qtorrenthandle.cpp rename to src/qtlibtorrent/qtorrenthandle.cpp diff --git a/src/qtorrenthandle.h b/src/qtlibtorrent/qtorrenthandle.h similarity index 100% rename from src/qtorrenthandle.h rename to src/qtlibtorrent/qtorrenthandle.h diff --git a/src/rss.h b/src/rss.h index b81b06378..472f309c2 100644 --- a/src/rss.h +++ b/src/rss.h @@ -45,7 +45,7 @@ #include "misc.h" #include "feeddownloader.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "downloadthread.h" #if QT_VERSION >= 0x040500 diff --git a/src/rss_imp.cpp b/src/rss_imp.cpp index 4345dfb26..c39d10ee9 100644 --- a/src/rss_imp.cpp +++ b/src/rss_imp.cpp @@ -40,7 +40,7 @@ #include "rss_imp.h" #include "feeddownloader.h" #include "feedList.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "cookiesdlg.h" #include "preferences.h" #include "rsssettings.h" diff --git a/src/searchengine.cpp b/src/searchengine.cpp index 6afd36bed..f72b7e8f2 100644 --- a/src/searchengine.cpp +++ b/src/searchengine.cpp @@ -48,7 +48,7 @@ #endif #include "searchengine.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "downloadthread.h" #include "misc.h" #include "preferences.h" diff --git a/src/speedlimitdlg.h b/src/speedlimitdlg.h index 3e18588aa..05956bf0f 100644 --- a/src/speedlimitdlg.h +++ b/src/speedlimitdlg.h @@ -35,7 +35,7 @@ #include #include "ui_bandwidth_limit.h" #include "misc.h" -#include "bittorrent.h" +#include "qbtsession.h" using namespace libtorrent; diff --git a/src/src.pro b/src/src.pro index ad90e7582..d70277de1 100644 --- a/src/src.pro +++ b/src/src.pro @@ -220,10 +220,9 @@ os2 { } # Resource files -RESOURCES = icons.qrc \ +RESOURCES += icons.qrc \ lang.qrc \ search.qrc \ - webui.qrc \ about.qrc # Add GeoIP resource file if the GeoIP database @@ -276,14 +275,6 @@ TRANSLATIONS = $$LANG_PATH/qbittorrent_fr.ts \ # Source code HEADERS += misc.h \ downloadthread.h \ - bittorrent.h \ - qtorrenthandle.h \ - httpserver.h \ - httpconnection.h \ - httprequestparser.h \ - httpresponsegenerator.h \ - json.h \ - eventmanager.h \ filterparserthread.h \ stacktrace.h \ torrentpersistentdata.h \ @@ -367,6 +358,9 @@ contains(DEFINES, USE_SYSTEM_QTSINGLEAPPLICATION) { include(lineedit/lineedit.pri) } +include(qtlibtorrent/qtlibtorrent.pri) +include(webui/webui.pri) + !contains(DEFINES, DISABLE_GUI) { FORMS += ui/mainwindow.ui \ ui/options.ui \ @@ -391,15 +385,8 @@ contains(DEFINES, USE_SYSTEM_QTSINGLEAPPLICATION) { ui/rsssettings.ui } -SOURCES += main.cpp \ - bittorrent.cpp \ - qtorrenthandle.cpp \ +SOURCES += main.cpp \ downloadthread.cpp \ - httpserver.cpp \ - httpconnection.cpp \ - httprequestparser.cpp \ - httpresponsegenerator.cpp \ - eventmanager.cpp \ scannedfoldersmodel.cpp \ misc.cpp \ smtp.cpp diff --git a/src/statusbar.h b/src/statusbar.h index 64269311b..0dde1b2bd 100644 --- a/src/statusbar.h +++ b/src/statusbar.h @@ -38,7 +38,7 @@ #include #include #include -#include "bittorrent.h" +#include "qbtsession.h" #include "speedlimitdlg.h" #include "preferences.h" #include "misc.h" diff --git a/src/torrentadditiondlg.h b/src/torrentadditiondlg.h index e3d1aba6f..40c79a21a 100644 --- a/src/torrentadditiondlg.h +++ b/src/torrentadditiondlg.h @@ -45,7 +45,7 @@ #include #include #include -#include "bittorrent.h" +#include "qbtsession.h" #include "misc.h" #include "proplistdelegate.h" #include "ui_torrentadditiondlg.h" diff --git a/src/trackerlist.cpp b/src/trackerlist.cpp index 0783ca711..39a070ddc 100644 --- a/src/trackerlist.cpp +++ b/src/trackerlist.cpp @@ -1,391 +1,391 @@ -/* - * 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" -#include "qinisettings.h" - -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); - } -} - -void TrackerList::moveSelectionUp() { -#if LIBTORRENT_VERSION_MINOR < 15 - 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(); -#endif -} - -void TrackerList::moveSelectionDown() { -#if LIBTORRENT_VERSION_MINOR < 15 - 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 - if(properties->getBTSession()->isPexEnabled()) - pex_item->setText(COL_STATUS, tr("Working")); - else - pex_item->setText(COL_STATUS, tr("Disabled")); - 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(); - const std::vector trackers = h.trackers(); - for(std::vector::const_iterator it = trackers.begin(); it != trackers.end(); it++) { - 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(); -#if LIBTORRENT_VERSION_MINOR > 14 - 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"), tr("Remove tracker")); - } - menu.addSeparator(); - QAction *reannounceAct = menu.addAction(QIcon(":/Icons/oxygen/run-build.png"), tr("Force reannounce")); - QAction *act = menu.exec(QCursor::pos()); - if(act == 0) return; - if(act == addAct) { - askForTrackers(); - return; - } - if(act == delAct) { - deleteSelectedTrackers(); - return; - } - if(act == reannounceAct) { - properties->getCurrentTorrent().force_reannounce(); - return; - } -} - -void TrackerList::loadSettings() { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QList contentColsWidths = misc::intListfromStringList(settings.value(QString::fromUtf8("TorrentProperties/Trackers/trackersColsWidth")).toStringList()); - if(!contentColsWidths.empty()) { - for(int i=0; i +#include +#include +#include +#include +#include +#include + +#include "trackerlist.h" +#include "propertieswidget.h" +#include "trackersadditiondlg.h" +#include "misc.h" +#include "qbtsession.h" +#include "qinisettings.h" + +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); + } +} + +void TrackerList::moveSelectionUp() { +#if LIBTORRENT_VERSION_MINOR < 15 + 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(); +#endif +} + +void TrackerList::moveSelectionDown() { +#if LIBTORRENT_VERSION_MINOR < 15 + 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 + if(properties->getBTSession()->isPexEnabled()) + pex_item->setText(COL_STATUS, tr("Working")); + else + pex_item->setText(COL_STATUS, tr("Disabled")); + 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(); + const std::vector trackers = h.trackers(); + for(std::vector::const_iterator it = trackers.begin(); it != trackers.end(); it++) { + 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(); +#if LIBTORRENT_VERSION_MINOR > 14 + 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"), tr("Remove tracker")); + } + menu.addSeparator(); + QAction *reannounceAct = menu.addAction(QIcon(":/Icons/oxygen/run-build.png"), tr("Force reannounce")); + QAction *act = menu.exec(QCursor::pos()); + if(act == 0) return; + if(act == addAct) { + askForTrackers(); + return; + } + if(act == delAct) { + deleteSelectedTrackers(); + return; + } + if(act == reannounceAct) { + properties->getCurrentTorrent().force_reannounce(); + return; + } +} + +void TrackerList::loadSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + QList contentColsWidths = misc::intListfromStringList(settings.value(QString::fromUtf8("TorrentProperties/Trackers/trackersColsWidth")).toStringList()); + if(!contentColsWidths.empty()) { + for(int i=0; i - - webui/index.html - webui/download.html - webui/addtrackers.html - webui/upload.html - webui/uploadframe.html - webui/about.html - webui/filters.html - webui/transferlist.html - webui/prop-general.html - webui/prop-trackers.html - webui/prop-files.html - webui/properties.html - webui/uploadlimit.html - webui/downloadlimit.html - webui/preferences.html - webui/preferences_content.html - webui/css/Core.css - webui/css/Layout.css - webui/css/Window.css - webui/css/Tabs.css - webui/css/dynamicTable.css - webui/css/style.css - webui/scripts/excanvas-compressed.js - webui/scripts/mocha-yc.js - webui/scripts/mocha-init.js - webui/scripts/mootools-1.2-core-yc.js - webui/scripts/mootools-1.2-more.js - webui/scripts/dynamicTable.js - webui/scripts/client.js - webui/scripts/download.js - webui/scripts/progressbar.js - webui/scripts/contextmenu.js - webui/scripts/parametrics.js - - diff --git a/src/eventmanager.cpp b/src/webui/eventmanager.cpp similarity index 99% rename from src/eventmanager.cpp rename to src/webui/eventmanager.cpp index 858f3b4e2..a3581e9a8 100644 --- a/src/eventmanager.cpp +++ b/src/webui/eventmanager.cpp @@ -31,7 +31,7 @@ #include #include "eventmanager.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "scannedfoldersmodel.h" #include "misc.h" #include "preferences.h" diff --git a/src/eventmanager.h b/src/webui/eventmanager.h similarity index 100% rename from src/eventmanager.h rename to src/webui/eventmanager.h diff --git a/src/webui/about.html b/src/webui/html/about.html similarity index 100% rename from src/webui/about.html rename to src/webui/html/about.html diff --git a/src/webui/addtrackers.html b/src/webui/html/addtrackers.html similarity index 100% rename from src/webui/addtrackers.html rename to src/webui/html/addtrackers.html diff --git a/src/webui/download.html b/src/webui/html/download.html similarity index 100% rename from src/webui/download.html rename to src/webui/html/download.html diff --git a/src/webui/downloadlimit.html b/src/webui/html/downloadlimit.html similarity index 100% rename from src/webui/downloadlimit.html rename to src/webui/html/downloadlimit.html diff --git a/src/webui/filters.html b/src/webui/html/filters.html similarity index 100% rename from src/webui/filters.html rename to src/webui/html/filters.html diff --git a/src/webui/index.html b/src/webui/html/index.html similarity index 100% rename from src/webui/index.html rename to src/webui/html/index.html diff --git a/src/webui/preferences.html b/src/webui/html/preferences.html similarity index 100% rename from src/webui/preferences.html rename to src/webui/html/preferences.html diff --git a/src/webui/preferences_content.html b/src/webui/html/preferences_content.html similarity index 100% rename from src/webui/preferences_content.html rename to src/webui/html/preferences_content.html diff --git a/src/webui/prop-files.html b/src/webui/html/prop-files.html similarity index 100% rename from src/webui/prop-files.html rename to src/webui/html/prop-files.html diff --git a/src/webui/prop-general.html b/src/webui/html/prop-general.html similarity index 100% rename from src/webui/prop-general.html rename to src/webui/html/prop-general.html diff --git a/src/webui/prop-trackers.html b/src/webui/html/prop-trackers.html similarity index 100% rename from src/webui/prop-trackers.html rename to src/webui/html/prop-trackers.html diff --git a/src/webui/properties.html b/src/webui/html/properties.html similarity index 100% rename from src/webui/properties.html rename to src/webui/html/properties.html diff --git a/src/webui/transferlist.html b/src/webui/html/transferlist.html similarity index 100% rename from src/webui/transferlist.html rename to src/webui/html/transferlist.html diff --git a/src/webui/upload.html b/src/webui/html/upload.html similarity index 100% rename from src/webui/upload.html rename to src/webui/html/upload.html diff --git a/src/webui/uploadframe.html b/src/webui/html/uploadframe.html similarity index 100% rename from src/webui/uploadframe.html rename to src/webui/html/uploadframe.html diff --git a/src/webui/uploadlimit.html b/src/webui/html/uploadlimit.html similarity index 100% rename from src/webui/uploadlimit.html rename to src/webui/html/uploadlimit.html diff --git a/src/httpconnection.cpp b/src/webui/httpconnection.cpp similarity index 98% rename from src/httpconnection.cpp rename to src/webui/httpconnection.cpp index 99acfd855..f633d2dfa 100644 --- a/src/httpconnection.cpp +++ b/src/webui/httpconnection.cpp @@ -34,7 +34,7 @@ #include "eventmanager.h" #include "preferences.h" #include "json.h" -#include "bittorrent.h" +#include "qbtsession.h" #include "misc.h" #include #include @@ -47,7 +47,7 @@ #include HttpConnection::HttpConnection(QTcpSocket *socket, Bittorrent *BTSession, HttpServer *parent) - : QObject(parent), socket(socket), parent(parent), BTSession(BTSession) + : QObject(parent), socket(socket), parent(parent), BTSession(BTSession) { socket->setParent(this); connect(socket, SIGNAL(readyRead()), this, SLOT(read())); @@ -231,10 +231,13 @@ void HttpConnection::respond() { return; } } - if (list[0] == "images") + if (list[0] == "images") { list[0] = "Icons"; - else + } else { + if(list.last().endsWith(".html")) + list.prepend("html"); list.prepend("webui"); + } url = ":/" + list.join("/"); QFile file(url); if(!file.open(QIODevice::ReadOnly)) diff --git a/src/httpconnection.h b/src/webui/httpconnection.h similarity index 100% rename from src/httpconnection.h rename to src/webui/httpconnection.h diff --git a/src/httprequestparser.cpp b/src/webui/httprequestparser.cpp similarity index 100% rename from src/httprequestparser.cpp rename to src/webui/httprequestparser.cpp diff --git a/src/httprequestparser.h b/src/webui/httprequestparser.h similarity index 100% rename from src/httprequestparser.h rename to src/webui/httprequestparser.h diff --git a/src/httpresponsegenerator.cpp b/src/webui/httpresponsegenerator.cpp similarity index 100% rename from src/httpresponsegenerator.cpp rename to src/webui/httpresponsegenerator.cpp diff --git a/src/httpresponsegenerator.h b/src/webui/httpresponsegenerator.h similarity index 100% rename from src/httpresponsegenerator.h rename to src/webui/httpresponsegenerator.h diff --git a/src/httpserver.cpp b/src/webui/httpserver.cpp similarity index 99% rename from src/httpserver.cpp rename to src/webui/httpserver.cpp index 4e74a3869..44b1885e1 100644 --- a/src/httpserver.cpp +++ b/src/webui/httpserver.cpp @@ -32,7 +32,7 @@ #include "httpserver.h" #include "httpconnection.h" #include "eventmanager.h" -#include "bittorrent.h" +#include "qbtsession.h" #include #include #include diff --git a/src/httpserver.h b/src/webui/httpserver.h similarity index 100% rename from src/httpserver.h rename to src/webui/httpserver.h diff --git a/src/json.h b/src/webui/json.h similarity index 100% rename from src/json.h rename to src/webui/json.h diff --git a/src/webui/webui.pri b/src/webui/webui.pri new file mode 100644 index 000000000..da7eea482 --- /dev/null +++ b/src/webui/webui.pri @@ -0,0 +1,16 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/httpserver.h \ + $$PWD/httpconnection.h \ + $$PWD/httprequestparser.h \ + $$PWD/httpresponsegenerator.h \ + $$PWD/eventmanager.h \ + $$PWD/json.h + +SOURCES += $$PWD/httpserver.cpp \ + $$PWD/httpconnection.cpp \ + $$PWD/httprequestparser.cpp \ + $$PWD/httpresponsegenerator.cpp \ + $$PWD/eventmanager.cpp + +RESOURCES += $$PWD/webui.qrc \ No newline at end of file diff --git a/src/webui/webui.qrc b/src/webui/webui.qrc new file mode 100644 index 000000000..366c981d3 --- /dev/null +++ b/src/webui/webui.qrc @@ -0,0 +1,37 @@ + + + html/index.html + html/download.html + html/addtrackers.html + html/upload.html + html/uploadframe.html + html/about.html + html/filters.html + html/transferlist.html + html/prop-general.html + html/prop-trackers.html + html/prop-files.html + html/properties.html + html/uploadlimit.html + html/downloadlimit.html + html/preferences.html + html/preferences_content.html + css/Core.css + css/Layout.css + css/Window.css + css/Tabs.css + css/dynamicTable.css + css/style.css + scripts/excanvas-compressed.js + scripts/mocha-yc.js + scripts/mocha-init.js + scripts/mootools-1.2-core-yc.js + scripts/mootools-1.2-more.js + scripts/dynamicTable.js + scripts/client.js + scripts/download.js + scripts/progressbar.js + scripts/contextmenu.js + scripts/parametrics.js + +