1
0
mirror of https://github.com/d47081/qBittorrent.git synced 2025-01-25 14:04:23 +00:00

- Web interface by Ishan Arora

This commit is contained in:
Christophe Dumez 2008-05-16 07:10:50 +00:00
parent 0dd84c37a1
commit 5af8bddc16
10 changed files with 538 additions and 167 deletions

View File

@ -280,7 +280,8 @@ int FinishedTorrents::getRowFromHash(QString hash) const{
// Note: does not actually pause the torrent in BT Session // Note: does not actually pause the torrent in BT Session
void FinishedTorrents::pauseTorrent(QString hash) { void FinishedTorrents::pauseTorrent(QString hash) {
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
Q_ASSERT(row != -1); if(row == -1)
return;
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0)); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0));
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant(QString::fromUtf8("0"))); finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant(QString::fromUtf8("0")));

View File

@ -31,6 +31,7 @@
#include <QModelIndex> #include <QModelIndex>
#include "GUI.h" #include "GUI.h"
#include "httpserver.h"
#include "downloadingTorrents.h" #include "downloadingTorrents.h"
#include "misc.h" #include "misc.h"
#include "createtorrent_imp.h" #include "createtorrent_imp.h"
@ -119,7 +120,9 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
connect(BTSession, SIGNAL(scanDirFoundTorrents(const QStringList&)), this, SLOT(processScannedFiles(const QStringList&))); connect(BTSession, SIGNAL(scanDirFoundTorrents(const QStringList&)), this, SLOT(processScannedFiles(const QStringList&)));
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString))); connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString))); connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString)));
connect(BTSession, SIGNAL(torrent_deleted(QString, QString, bool)), this, SLOT(deleteTorrent(QString, QString, bool))); connect(BTSession, SIGNAL(deletedTorrent(QString)), this, SLOT(deleteTorrent(QString)));
connect(BTSession, SIGNAL(torrent_ratio_deleted(QString)), this, SLOT(deleteRatioTorrent(QString)));
connect(BTSession, SIGNAL(pausedTorrent(QString)), this, SLOT(pauseTorrent(QString)));
qDebug("create tabWidget"); qDebug("create tabWidget");
tabs = new QTabWidget(); tabs = new QTabWidget();
// Download torrents tab // Download torrents tab
@ -158,6 +161,15 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
readSettings(); readSettings();
// Add torrent given on command line // Add torrent given on command line
processParams(torrentCmdLine); processParams(torrentCmdLine);
// Initialize Web UI
httpServer = 0;
if(settings.value("Preferences/WebUI/Enabled", false).toBool())
{
quint16 port = settings.value("Preferences/WebUI/Port", 8080).toUInt();
QString username = settings.value("Preferences/WebUI/Username", "").toString();
QString password = settings.value("Preferences/WebUI/Password", "").toString();
initWebUi(username, password, port);
}
// Use a tcp server to allow only one instance of qBittorrent // Use a tcp server to allow only one instance of qBittorrent
tcpServer = new QTcpServer(); tcpServer = new QTcpServer();
if (!tcpServer->listen(QHostAddress::LocalHost, 1666)) { if (!tcpServer->listen(QHostAddress::LocalHost, 1666)) {
@ -196,6 +208,9 @@ GUI::~GUI() {
delete tcpServer; delete tcpServer;
delete connecStatusLblIcon; delete connecStatusLblIcon;
delete tabs; delete tabs;
// HTTP Server
if(httpServer)
delete httpServer;
// Keyboard shortcuts // Keyboard shortcuts
delete switchSearchShortcut; delete switchSearchShortcut;
delete switchSearchShortcut2; delete switchSearchShortcut2;
@ -687,27 +702,22 @@ void GUI::on_actionDelete_Permanently_triggered() {
QString fileName = h.name(); QString fileName = h.name();
// Remove the torrent // Remove the torrent
BTSession->deleteTorrent(hash, true); BTSession->deleteTorrent(hash, true);
// Delete item from list
if(inDownloadList) {
downloadingTorrentTab->deleteTorrent(hash);
} else {
finishedTorrentTab->deleteTorrent(hash);
}
// Update info bar // Update info bar
downloadingTorrentTab->setInfoBar(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName)); downloadingTorrentTab->setInfoBar(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName));
} }
} }
void GUI::deleteTorrent(QString hash, QString fileName, bool finished) { void GUI::deleteRatioTorrent(QString fileName) {
if(finished) {
finishedTorrentTab->deleteTorrent(hash);
} else {
downloadingTorrentTab->deleteTorrent(hash);
}
// Update info bar // Update info bar
downloadingTorrentTab->setInfoBar(tr("'%1' was removed because its ratio reached the maximum value you set.", "%1 is a file name").arg(fileName)); downloadingTorrentTab->setInfoBar(tr("'%1' was removed because its ratio reached the maximum value you set.", "%1 is a file name").arg(fileName));
} }
void GUI::deleteTorrent(QString hash) {
// Delete item from list
downloadingTorrentTab->deleteTorrent(hash);
finishedTorrentTab->deleteTorrent(hash);
}
// delete selected items in the list // delete selected items in the list
void GUI::on_actionDelete_triggered() { void GUI::on_actionDelete_triggered() {
QStringList hashes; QStringList hashes;
@ -752,12 +762,6 @@ void GUI::on_actionDelete_triggered() {
QString fileName = h.name(); QString fileName = h.name();
// Remove the torrent // Remove the torrent
BTSession->deleteTorrent(hash, false); BTSession->deleteTorrent(hash, false);
// Delete item from list
if(inDownloadList) {
downloadingTorrentTab->deleteTorrent(hash);
} else {
finishedTorrentTab->deleteTorrent(hash);
}
// Update info bar // Update info bar
downloadingTorrentTab->setInfoBar(tr("'%1' was removed.", "'xxx.avi' was removed.").arg(fileName)); downloadingTorrentTab->setInfoBar(tr("'%1' was removed.", "'xxx.avi' was removed.").arg(fileName));
} }
@ -1127,6 +1131,11 @@ void GUI::on_actionPause_triggered() {
} }
} }
void GUI::pauseTorrent(QString hash) {
downloadingTorrentTab->pauseTorrent(hash);
finishedTorrentTab->pauseTorrent(hash);
}
// Resume All Downloads in DL list // Resume All Downloads in DL list
void GUI::on_actionStart_All_triggered() { void GUI::on_actionStart_All_triggered() {
bool change = false; bool change = false;
@ -1344,10 +1353,40 @@ void GUI::OptionsSaved(QString info, bool deleteOptions) {
systrayIntegration = newSystrayIntegration; systrayIntegration = newSystrayIntegration;
// Update info bar // Update info bar
downloadingTorrentTab->setInfoBar(info); downloadingTorrentTab->setInfoBar(info);
// Update Web UI
if (options->isWebUiEnabled())
{
quint16 port = options->webUiPort();
QString username = options->webUiUsername();
QString password = options->webUiPassword();
initWebUi(username, password, port);
}
else if(httpServer)
{
delete httpServer;
httpServer = 0;
}
// Update session // Update session
configureSession(deleteOptions); configureSession(deleteOptions);
} }
bool GUI::initWebUi(QString username, QString password, int port)
{
if(httpServer)
{
httpServer->close();
}
else
httpServer = new HttpServer(BTSession, 500, this);
httpServer->setAuthorization(username, password);
bool success = httpServer->listen(QHostAddress::Any, port);
if (success)
qDebug()<<"Web UI listening on port "<<port;
else
QMessageBox::critical(this, "Web User Interface Error", "Unable to initialize HTTP Server on port " + port);
return success;
}
/***************************************************** /*****************************************************
* * * *
* HTTP Downloader * * HTTP Downloader *

View File

@ -46,6 +46,7 @@ class options_imp;
class QTabWidget; class QTabWidget;
class QLabel; class QLabel;
class QModelIndex; class QModelIndex;
class HttpServer;
class GUI : public QMainWindow, private Ui::MainWindow{ class GUI : public QMainWindow, private Ui::MainWindow{
Q_OBJECT Q_OBJECT
@ -79,6 +80,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
SearchEngine *searchEngine; SearchEngine *searchEngine;
// RSS // RSS
RSSImp *rssWidget; RSSImp *rssWidget;
// Web UI
HttpServer *httpServer;
// Misc // Misc
QTcpServer *tcpServer; QTcpServer *tcpServer;
QTcpSocket *clientConnection; QTcpSocket *clientConnection;
@ -134,10 +137,13 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void processScannedFiles(const QStringList& params); void processScannedFiles(const QStringList& params);
void processDownloadedFiles(QString path, QString url); void processDownloadedFiles(QString path, QString url);
void downloadFromURLList(const QStringList& urls); void downloadFromURLList(const QStringList& urls);
void deleteTorrent(QString hash, QString fileName, bool finished); void deleteTorrent(QString hash);
void deleteRatioTorrent(QString fileName);
void finishedTorrent(QTorrentHandle& h) const; void finishedTorrent(QTorrentHandle& h) const;
void torrentChecked(QString hash) const; void torrentChecked(QString hash) const;
void updateLists(); void updateLists();
bool initWebUi(QString username, QString password, int port);
void pauseTorrent(QString hash);
// Options slots // Options slots
void on_actionOptions_triggered(); void on_actionOptions_triggered();
void OptionsSaved(QString info, bool deleteOptions); void OptionsSaved(QString info, bool deleteOptions);

View File

@ -123,7 +123,7 @@ void bittorrent::deleteBigRatios() {
if(getRealRatio(hash) > max_ratio) { if(getRealRatio(hash) > max_ratio) {
QString fileName = h.name(); QString fileName = h.name();
deleteTorrent(hash); deleteTorrent(hash);
emit torrent_deleted(hash, fileName, true); emit torrent_ratio_deleted(fileName);
} }
} }
} }
@ -249,6 +249,7 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
// Deleting in a thread to avoid GUI freeze // Deleting in a thread to avoid GUI freeze
deleter->deleteTorrent(savePath, files_arb); deleter->deleteTorrent(savePath, files_arb);
} }
emit deletedTorrent(hash);
} }
// Return a list of hashes for the finished torrents // Return a list of hashes for the finished torrents
@ -312,6 +313,7 @@ bool bittorrent::pauseTorrent(QString hash) {
// Save fast resume data // Save fast resume data
saveFastResumeAndRatioData(hash); saveFastResumeAndRatioData(hash);
qDebug("Torrent paused successfully"); qDebug("Torrent paused successfully");
emit pausedTorrent(hash);
}else{ }else{
if(!h.is_valid()) { if(!h.is_valid()) {
qDebug("Could not pause torrent %s, reason: invalid", hash.toUtf8().data()); qDebug("Could not pause torrent %s, reason: invalid", hash.toUtf8().data());
@ -341,6 +343,7 @@ bool bittorrent::resumeTorrent(QString hash) {
TorrentsStartTime[hash] = QDateTime::currentDateTime(); TorrentsStartTime[hash] = QDateTime::currentDateTime();
h.resume(); h.resume();
success = true; success = true;
emit resumedTorrent(hash);
} }
// Delete .paused file // Delete .paused file
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused"))
@ -353,6 +356,18 @@ bool bittorrent::resumeTorrent(QString hash) {
return success; return success;
} }
void bittorrent::pauseAllTorrents() {
QStringList list = getUnfinishedTorrents() + getFinishedTorrents();
foreach(QString hash, list)
pauseTorrent(hash);
}
void bittorrent::resumeAllTorrents() {
QStringList list = getUnfinishedTorrents() + getFinishedTorrents();
foreach(QString hash, list)
resumeTorrent(hash);
}
void bittorrent::loadWebSeeds(QString hash) { void bittorrent::loadWebSeeds(QString hash) {
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds"); QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return; if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
@ -698,12 +713,12 @@ bool bittorrent::enableDHT(bool b) {
dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>()); dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>());
}catch (std::exception&) {} }catch (std::exception&) {}
try { try {
s->start_dht(dht_state); s->start_dht(dht_state);
s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));
s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));
s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881)); s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));
DHTEnabled = true; DHTEnabled = true;
qDebug("DHT enabled"); qDebug("DHT enabled");
}catch(std::exception e) { }catch(std::exception e) {
qDebug("Could not enable DHT, reason: %s", e.what()); qDebug("Could not enable DHT, reason: %s", e.what());
return false; return false;
@ -1166,7 +1181,7 @@ void bittorrent::readAlerts() {
// Authentication // Authentication
if(p->status_code != 401) { if(p->status_code != 401) {
QString hash = h.hash(); QString hash = h.hash();
qDebug("Received a tracker error for %s", (const char*)h.current_tracker().toUtf8()); qDebug("Received a tracker error for %s", (const char*)misc::toQString(p->url).toUtf8());
QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>()); QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>());
// p->url requires at least libtorrent v0.13.1 // p->url requires at least libtorrent v0.13.1
errors[misc::toQString(p->url)] = QString::fromUtf8(a->msg().c_str()); errors[misc::toQString(p->url)] = QString::fromUtf8(a->msg().c_str());

View File

@ -99,6 +99,8 @@ class bittorrent : public QObject{
void deleteTorrent(QString hash, bool permanent = false); void deleteTorrent(QString hash, bool permanent = false);
bool pauseTorrent(QString hash); bool pauseTorrent(QString hash);
bool resumeTorrent(QString hash); bool resumeTorrent(QString hash);
void pauseAllTorrents();
void resumeAllTorrents();
void saveDHTEntry(); void saveDHTEntry();
void preAllocateAllFiles(bool b); void preAllocateAllFiles(bool b);
void saveFastResumeAndRatioData(); void saveFastResumeAndRatioData();
@ -153,6 +155,9 @@ class bittorrent : public QObject{
void invalidTorrent(QString path); void invalidTorrent(QString path);
void duplicateTorrent(QString path); void duplicateTorrent(QString path);
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume); void addedTorrent(QString path, QTorrentHandle& h, bool fastResume);
void deletedTorrent(QString hash);
void pausedTorrent(QString hash);
void resumedTorrent(QString hash);
void finishedTorrent(QTorrentHandle& h); void finishedTorrent(QTorrentHandle& h);
void fullDiskError(QTorrentHandle& h); void fullDiskError(QTorrentHandle& h);
void trackerError(QString hash, QString time, QString msg); void trackerError(QString hash, QString time, QString msg);
@ -167,7 +172,7 @@ class bittorrent : public QObject{
void fastResumeDataRejected(QString name); void fastResumeDataRejected(QString name);
void urlSeedProblem(QString url, QString msg); void urlSeedProblem(QString url, QString msg);
void torrentFinishedChecking(QString hash); void torrentFinishedChecking(QString hash);
void torrent_deleted(QString hash, QString fileName, bool finished); void torrent_ratio_deleted(QString fileName);
void UPnPError(QString msg); void UPnPError(QString msg);
void UPnPSuccess(QString msg); void UPnPSuccess(QString msg);
}; };

View File

@ -147,7 +147,8 @@ unsigned int DownloadingTorrents::getNbTorrentsInList() const {
// Note: do not actually pause the torrent in BT session // Note: do not actually pause the torrent in BT session
void DownloadingTorrents::pauseTorrent(QString hash) { void DownloadingTorrents::pauseTorrent(QString hash) {
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
Q_ASSERT(row != -1); if(row == -1)
return;
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));

View File

@ -1383,132 +1383,131 @@
<property name="title" > <property name="title" >
<string>Share ratio settings</string> <string>Share ratio settings</string>
</property> </property>
<widget class="QWidget" name="layoutWidget" > <layout class="QVBoxLayout" >
<property name="geometry" > <item>
<rect> <layout class="QHBoxLayout" >
<x>11</x> <item>
<y>30</y> <widget class="QCheckBox" name="checkRatioLimit" >
<width>535</width> <property name="text" >
<height>31</height> <string>Desired ratio:</string>
</rect> </property>
</property> </widget>
<layout class="QHBoxLayout" > </item>
<item> <item>
<widget class="QCheckBox" name="checkRatioLimit" > <widget class="QDoubleSpinBox" name="spinRatio" >
<property name="text" > <property name="enabled" >
<string>Desired ratio:</string> <bool>false</bool>
</property> </property>
</widget> <property name="font" >
</item> <font>
<item> <pointsize>8</pointsize>
<widget class="QDoubleSpinBox" name="spinRatio" > </font>
<property name="enabled" > </property>
<bool>false</bool> <property name="alignment" >
</property> <set>Qt::AlignHCenter</set>
<property name="font" > </property>
<font> <property name="decimals" >
<pointsize>8</pointsize> <number>1</number>
</font> </property>
</property> <property name="minimum" >
<property name="alignment" > <double>1.000000000000000</double>
<set>Qt::AlignHCenter</set> </property>
</property> <property name="maximum" >
<property name="decimals" > <double>10.000000000000000</double>
<number>1</number> </property>
</property> <property name="singleStep" >
<property name="minimum" > <double>0.100000000000000</double>
<double>1.000000000000000</double> </property>
</property> <property name="value" >
<property name="maximum" > <double>1.000000000000000</double>
<double>10.000000000000000</double> </property>
</property> </widget>
<property name="singleStep" > </item>
<double>0.100000000000000</double> <item>
</property> <spacer>
<property name="value" > <property name="orientation" >
<double>1.000000000000000</double> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> <property name="sizeHint" >
</item> <size>
<item> <width>40</width>
<spacer> <height>20</height>
<property name="orientation" > </size>
<enum>Qt::Horizontal</enum> </property>
</property> </spacer>
<property name="sizeHint" > </item>
<size> </layout>
<width>40</width> </item>
<height>20</height> <item>
</size> <layout class="QHBoxLayout" >
</property> <item>
</spacer> <widget class="QCheckBox" name="checkRatioRemove" >
</item> <property name="text" >
</layout> <string>Remove finished torrents when their ratio reaches:</string>
</widget> </property>
<widget class="QWidget" name="layoutWidget" > </widget>
<property name="geometry" > </item>
<rect> <item>
<x>11</x> <widget class="QDoubleSpinBox" name="spinMaxRatio" >
<y>67</y> <property name="enabled" >
<width>535</width> <bool>false</bool>
<height>31</height> </property>
</rect> <property name="font" >
</property> <font>
<layout class="QHBoxLayout" > <pointsize>8</pointsize>
<item> </font>
<widget class="QCheckBox" name="checkRatioRemove" > </property>
<property name="text" > <property name="alignment" >
<string>Remove finished torrents when their ratio reaches:</string> <set>Qt::AlignHCenter</set>
</property> </property>
</widget> <property name="decimals" >
</item> <number>1</number>
<item> </property>
<widget class="QDoubleSpinBox" name="spinMaxRatio" > <property name="minimum" >
<property name="enabled" > <double>1.000000000000000</double>
<bool>false</bool> </property>
</property> <property name="maximum" >
<property name="font" > <double>10.000000000000000</double>
<font> </property>
<pointsize>8</pointsize> <property name="singleStep" >
</font> <double>0.100000000000000</double>
</property> </property>
<property name="alignment" > <property name="value" >
<set>Qt::AlignHCenter</set> <double>1.000000000000000</double>
</property> </property>
<property name="decimals" > </widget>
<number>1</number> </item>
</property> <item>
<property name="minimum" > <spacer>
<double>1.000000000000000</double> <property name="orientation" >
</property> <enum>Qt::Horizontal</enum>
<property name="maximum" > </property>
<double>10.000000000000000</double> <property name="sizeHint" >
</property> <size>
<property name="singleStep" > <width>40</width>
<double>0.100000000000000</double> <height>20</height>
</property> </size>
<property name="value" > </property>
<double>1.000000000000000</double> </spacer>
</property> </item>
</widget> </layout>
</item> </item>
<item> </layout>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_4" > <widget class="QWidget" name="tab_4" >
@ -1845,6 +1844,175 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_2" >
<attribute name="title" >
<string>Web UI</string>
</attribute>
<attribute name="icon" >
<iconset resource="icons.qrc" >:/Icons/password.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<item>
<widget class="QCheckBox" name="checkWebUi" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string>Enable Web User Interface</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupWebUiServer" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="title" >
<string>HTTP Server</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="lblWebUiPort" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string>Port:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinWebUiPort" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="maximum" >
<number>65525</number>
</property>
<property name="value" >
<number>80</number>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>21</width>
<height>29</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupWebUiAuth" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="title" >
<string>Authentication</string>
</property>
<layout class="QHBoxLayout" >
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="lblWebUiUsername" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string>Username:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblWebUiPassword" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string>Password:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QLineEdit" name="textWebUiUsername" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string/>
</property>
<property name="maxLength" >
<number>1000</number>
</property>
<property name="echoMode" >
<enum>QLineEdit::Normal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="textWebUiPassword" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string/>
</property>
<property name="maxLength" >
<number>1000</number>
</property>
<property name="echoMode" >
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>198</width>
<height>57</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>623</width>
<height>41</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item> <item>
@ -1881,6 +2049,74 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<tabstops>
<tabstop>tabOptions</tabstop>
<tabstop>comboI18n</tabstop>
<tabstop>comboStyle</tabstop>
<tabstop>checkConfirmExit</tabstop>
<tabstop>checkSpeedInTitle</tabstop>
<tabstop>spinRefreshInterval</tabstop>
<tabstop>checkNoSystray</tabstop>
<tabstop>checkCloseToSystray</tabstop>
<tabstop>checkMinimizeToSysTray</tabstop>
<tabstop>checkStartMinimized</tabstop>
<tabstop>checkSystrayBalloons</tabstop>
<tabstop>textSavePath</tabstop>
<tabstop>browseSaveDirButton</tabstop>
<tabstop>checkPreallocateAll</tabstop>
<tabstop>checkAdditionDialog</tabstop>
<tabstop>checkStartPaused</tabstop>
<tabstop>checkScanDir</tabstop>
<tabstop>textScanDir</tabstop>
<tabstop>browseScanDirButton</tabstop>
<tabstop>actionTorrentDlOnDblClBox</tabstop>
<tabstop>actionTorrentFnOnDblClBox</tabstop>
<tabstop>spinPortMin</tabstop>
<tabstop>spinPortMax</tabstop>
<tabstop>checkUPnP</tabstop>
<tabstop>checkNATPMP</tabstop>
<tabstop>checkUploadLimit</tabstop>
<tabstop>checkDownloadLimit</tabstop>
<tabstop>spinUploadLimit</tabstop>
<tabstop>spinDownloadLimit</tabstop>
<tabstop>comboProxyType</tabstop>
<tabstop>textProxyIP</tabstop>
<tabstop>spinProxyPort</tabstop>
<tabstop>checkProxyAuth</tabstop>
<tabstop>textProxyUsername</tabstop>
<tabstop>textProxyPassword</tabstop>
<tabstop>checkProxyTrackers</tabstop>
<tabstop>checkProxyPeers</tabstop>
<tabstop>checkProxyDHT</tabstop>
<tabstop>checkProxyWebseeds</tabstop>
<tabstop>checkMaxConnecs</tabstop>
<tabstop>spinMaxConnec</tabstop>
<tabstop>checkMaxConnecsPerTorrent</tabstop>
<tabstop>spinMaxConnecPerTorrent</tabstop>
<tabstop>checkMaxUploadsPerTorrent</tabstop>
<tabstop>spinMaxUploadsPerTorrent</tabstop>
<tabstop>checkDHT</tabstop>
<tabstop>checkPeX</tabstop>
<tabstop>checkLSD</tabstop>
<tabstop>comboEncryption</tabstop>
<tabstop>checkRatioLimit</tabstop>
<tabstop>spinRatio</tabstop>
<tabstop>checkRatioRemove</tabstop>
<tabstop>spinMaxRatio</tabstop>
<tabstop>checkIPFilter</tabstop>
<tabstop>filtersList</tabstop>
<tabstop>addFilterRangeButton</tabstop>
<tabstop>delFilterRangeButton</tabstop>
<tabstop>textFilterPath</tabstop>
<tabstop>browseFilterButton</tabstop>
<tabstop>spinRSSRefresh</tabstop>
<tabstop>spinRSSMaxArticlesPerFeed</tabstop>
<tabstop>checkWebUi</tabstop>
<tabstop>spinWebUiPort</tabstop>
<tabstop>textWebUiUsername</tabstop>
<tabstop>textWebUiPassword</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources> <resources>
<include location="icons.qrc" /> <include location="icons.qrc" />
</resources> </resources>

View File

@ -142,6 +142,8 @@ options_imp::options_imp(QWidget *parent):QDialog(parent){
connect(checkRatioRemove, SIGNAL(stateChanged(int)), this, SLOT(enableDeleteRatio(int))); connect(checkRatioRemove, SIGNAL(stateChanged(int)), this, SLOT(enableDeleteRatio(int)));
// IP Filter tab // IP Filter tab
connect(checkIPFilter, SIGNAL(stateChanged(int)), this, SLOT(enableFilter(int))); connect(checkIPFilter, SIGNAL(stateChanged(int)), this, SLOT(enableFilter(int)));
// Web UI tab
connect(checkWebUi, SIGNAL(toggled(bool)), this, SLOT(enableWebUi(bool)));
// Apply button is activated when a value is changed // Apply button is activated when a value is changed
// General tab // General tab
@ -203,6 +205,11 @@ options_imp::options_imp(QWidget *parent):QDialog(parent){
connect(textFilterPath, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); connect(textFilterPath, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
connect(spinRSSRefresh, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); connect(spinRSSRefresh, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton()));
connect(spinRSSMaxArticlesPerFeed, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); connect(spinRSSMaxArticlesPerFeed, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton()));
// Web UI tab
connect(checkWebUi, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
connect(spinWebUiPort, SIGNAL(valueChanged(int)), this, SLOT(enableApplyButton()));
connect(textWebUiUsername, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
connect(textWebUiPassword, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
// Disable apply Button // Disable apply Button
applyButton->setEnabled(false); applyButton->setEnabled(false);
if(!QSystemTrayIcon::supportsMessages()){ if(!QSystemTrayIcon::supportsMessages()){
@ -335,6 +342,17 @@ void options_imp::saveOptions(){
settings.setValue(QString::fromUtf8("RSSMaxArticlesPerFeed"), spinRSSMaxArticlesPerFeed->value()); settings.setValue(QString::fromUtf8("RSSMaxArticlesPerFeed"), spinRSSMaxArticlesPerFeed->value());
// End RSS preferences // End RSS preferences
settings.endGroup(); settings.endGroup();
// Web UI
settings.beginGroup("WebUI");
settings.setValue("Enabled", isWebUiEnabled());
if(isWebUiEnabled())
{
settings.setValue("Port", webUiPort());
settings.setValue("Username", webUiUsername());
settings.setValue("Password", webUiPassword());
}
// End Web UI
settings.endGroup();
// End preferences // End preferences
settings.endGroup(); settings.endGroup();
} }
@ -586,6 +604,15 @@ void options_imp::loadOptions(){
spinRSSMaxArticlesPerFeed->setValue(settings.value(QString::fromUtf8("RSSMaxArticlesPerFeed"), 50).toInt()); spinRSSMaxArticlesPerFeed->setValue(settings.value(QString::fromUtf8("RSSMaxArticlesPerFeed"), 50).toInt());
// End RSS preferences // End RSS preferences
settings.endGroup(); settings.endGroup();
// Web UI
settings.beginGroup("WebUI");
checkWebUi->setChecked(settings.value("Enabled", false).toBool());
enableWebUi(isWebUiEnabled());
spinWebUiPort->setValue(settings.value("Port", 8080).toInt());
textWebUiUsername->setText(settings.value("Username", "user").toString());
textWebUiPassword->setText(settings.value("Password", "").toString());
// End Web UI
settings.endGroup();
} }
// return min & max ports // return min & max ports
@ -1242,3 +1269,30 @@ void options_imp::on_delFilterRangeButton_clicked(){
} }
ipfilter.close(); ipfilter.close();
} }
// Web UI
void options_imp::enableWebUi(bool checkBoxValue){
groupWebUiServer->setEnabled(checkBoxValue);
groupWebUiAuth->setEnabled(checkBoxValue);
}
bool options_imp::isWebUiEnabled() const
{
return checkWebUi->isChecked();
}
quint16 options_imp::webUiPort() const
{
return spinWebUiPort->value();
}
QString options_imp::webUiUsername() const
{
return textWebUiUsername->text();
}
QString options_imp::webUiPassword() const
{
return textWebUiPassword->text();
}

View File

@ -111,6 +111,10 @@ class options_imp : public QDialog, private Ui::Dialog {
// IP Filter // IP Filter
bool isFilteringEnabled() const; bool isFilteringEnabled() const;
ip_filter getFilter() const; ip_filter getFilter() const;
bool isWebUiEnabled() const;
quint16 webUiPort() const;
QString webUiUsername() const;
QString webUiPassword() const;
protected slots: protected slots:
void enableUploadLimit(int checkBoxValue); void enableUploadLimit(int checkBoxValue);
@ -140,6 +144,7 @@ class options_imp : public QDialog, private Ui::Dialog {
void enableSystrayOptions(); void enableSystrayOptions();
void disableSystrayOptions(); void disableSystrayOptions();
void setSystrayOptionsState(int checkBoxValue); void setSystrayOptionsState(int checkBoxValue);
void enableWebUi(bool checkBoxValue);
public slots: public slots:
void setLocale(QString locale); void setLocale(QString locale);

View File

@ -100,7 +100,8 @@ win32 {
RESOURCES = icons.qrc \ RESOURCES = icons.qrc \
lang.qrc \ lang.qrc \
search.qrc search.qrc \
webui.qrc
# Translations # Translations
TRANSLATIONS = $$LANG_PATH/qbittorrent_fr.ts \ TRANSLATIONS = $$LANG_PATH/qbittorrent_fr.ts \
@ -133,7 +134,7 @@ TRANSLATIONS = $$LANG_PATH/qbittorrent_fr.ts \
HEADERS += GUI.h misc.h options_imp.h about_imp.h \ HEADERS += GUI.h misc.h options_imp.h about_imp.h \
properties_imp.h createtorrent_imp.h \ properties_imp.h createtorrent_imp.h \
DLListDelegate.h SearchListDelegate.h \ DLListDelegate.h SearchListDelegate.h \
PropListDelegate.h previewSelect.h \ PropListDelegate.h previewSelect.h \
PreviewListDelegate.h trackerLogin.h \ PreviewListDelegate.h trackerLogin.h \
downloadThread.h downloadFromURLImp.h \ downloadThread.h downloadFromURLImp.h \
torrentAddition.h deleteThread.h \ torrentAddition.h deleteThread.h \
@ -143,8 +144,10 @@ HEADERS += GUI.h misc.h options_imp.h about_imp.h \
qtorrenthandle.h downloadingTorrents.h \ qtorrenthandle.h downloadingTorrents.h \
engineSelectDlg.h pluginSource.h \ engineSelectDlg.h pluginSource.h \
arborescence.h qgnomelook.h realprogressbar.h \ arborescence.h qgnomelook.h realprogressbar.h \
realprogressbarthread.h \ realprogressbarthread.h qrealarray.h \
qrealarray.h httpserver.h httpconnection.h \
httprequestparser.h httpresponsegenerator.h \
json.h eventmanager.h
FORMS += MainWindow.ui options.ui about.ui \ FORMS += MainWindow.ui options.ui about.ui \
properties.ui createtorrent.ui preview.ui \ properties.ui createtorrent.ui preview.ui \
login.ui downloadFromURL.ui addTorrentDialog.ui \ login.ui downloadFromURL.ui addTorrentDialog.ui \
@ -153,19 +156,25 @@ FORMS += MainWindow.ui options.ui about.ui \
SOURCES += GUI.cpp \ SOURCES += GUI.cpp \
main.cpp \ main.cpp \
options_imp.cpp \ options_imp.cpp \
properties_imp.cpp \ properties_imp.cpp \
createtorrent_imp.cpp \ createtorrent_imp.cpp \
bittorrent.cpp \ bittorrent.cpp \
searchEngine.cpp \ searchEngine.cpp \
rss_imp.cpp \ rss_imp.cpp \
FinishedTorrents.cpp \ FinishedTorrents.cpp \
qtorrenthandle.cpp \ qtorrenthandle.cpp \
downloadingTorrents.cpp \ downloadingTorrents.cpp \
engineSelectDlg.cpp \ engineSelectDlg.cpp \
downloadThread.cpp \ downloadThread.cpp \
realprogressbar.cpp \ realprogressbar.cpp \
realprogressbarthread.cpp \ realprogressbarthread.cpp \
qrealarray.cpp qrealarray.cpp \
httpserver.cpp \
httpconnection.cpp \
httprequestparser.cpp \
httpresponsegenerator.cpp \
json.cpp \
eventmanager.cpp
DESTDIR = . DESTDIR = .