mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-01 01:16:01 +00:00
FEATURE: Support for multiple scan folders
* Patch by Christian Kandeler (Thanks!)
This commit is contained in:
parent
4d5001d18d
commit
7710c88797
@ -12,6 +12,7 @@
|
||||
- FEATURE: Trackers can be added from Web UI
|
||||
- FEATURE: Global transfer information are displayed in the new Web UI status bar
|
||||
- FEATURE: Allow to change the priority of several files at once
|
||||
- FEATURE: Support for multiple scan folders (Patch by Christian Kandeler)
|
||||
- COSMETIC: Improved style management
|
||||
|
||||
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "downloadthread.h"
|
||||
#include "filterparserthread.h"
|
||||
#include "preferences.h"
|
||||
#include "scannedfoldersmodel.h"
|
||||
#ifndef DISABLE_GUI
|
||||
#include "geoip.h"
|
||||
#endif
|
||||
@ -68,7 +69,13 @@ enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5};
|
||||
enum VersionType { NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL };
|
||||
|
||||
// Main constructor
|
||||
Bittorrent::Bittorrent() : preAllocateAll(false), addInPause(false), ratio_limit(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), DHTEnabled(false), current_dht_port(0), queueingEnabled(false), torrentExport(false), exiting(false) {
|
||||
Bittorrent::Bittorrent()
|
||||
: m_scanFolders(ScanFoldersModel::instance(this)),
|
||||
preAllocateAll(false), addInPause(false), ratio_limit(-1),
|
||||
UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false),
|
||||
DHTEnabled(false), current_dht_port(0), queueingEnabled(false),
|
||||
torrentExport(false), exiting(false)
|
||||
{
|
||||
#ifndef DISABLE_GUI
|
||||
geoipDBLoaded = false;
|
||||
resolve_countries = false;
|
||||
@ -136,6 +143,7 @@ Bittorrent::Bittorrent() : preAllocateAll(false), addInPause(false), ratio_limit
|
||||
#endif
|
||||
// Apply user settings to Bittorrent session
|
||||
configureSession();
|
||||
connect(m_scanFolders, SIGNAL(torrentsAdded(QStringList&)), this, SLOT(addTorrentsFromScanFolder(QStringList&)));
|
||||
qDebug("* BTSession constructed");
|
||||
}
|
||||
|
||||
@ -165,8 +173,6 @@ Bittorrent::~Bittorrent() {
|
||||
session_proxy sp = s->abort();
|
||||
delete s;
|
||||
}
|
||||
// Disable directory scanning
|
||||
disableDirectoryScanning();
|
||||
// Delete our objects
|
||||
delete timerAlerts;
|
||||
if(BigRatioTimer)
|
||||
@ -174,8 +180,6 @@ Bittorrent::~Bittorrent() {
|
||||
if(filterParser)
|
||||
delete filterParser;
|
||||
delete downloader;
|
||||
if(FSWatcher)
|
||||
delete FSWatcher;
|
||||
if(bd_scheduler)
|
||||
delete bd_scheduler;
|
||||
// HTTP Server
|
||||
@ -272,13 +276,14 @@ void Bittorrent::configureSession() {
|
||||
#endif
|
||||
preAllocateAllFiles(Preferences::preAllocateAllFiles());
|
||||
startTorrentsInPause(Preferences::addTorrentsInPause());
|
||||
// * Scan dir
|
||||
QString scan_dir = Preferences::getScanDir();
|
||||
if(scan_dir.isEmpty()) {
|
||||
disableDirectoryScanning();
|
||||
}else{
|
||||
//Interval first
|
||||
enableDirectoryScanning(scan_dir);
|
||||
// * Scan dirs
|
||||
const QStringList &scan_dirs = Preferences::getScanDirs();
|
||||
foreach (const QString &dir, scan_dirs) {
|
||||
m_scanFolders->addPath(dir);
|
||||
}
|
||||
const QVariantList &downloadInDirList = Preferences::getDownloadInScanDirs();
|
||||
for (int i = 0; i < downloadInDirList.count(); ++i) {
|
||||
m_scanFolders->setDownloadAtPath(i, downloadInDirList.at(i).toBool());
|
||||
}
|
||||
// * Export Dir
|
||||
bool newTorrentExport = Preferences::isTorrentExportEnabled();
|
||||
@ -1039,7 +1044,7 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||
// Enforcing the save path defined before URL download (from RSS for example)
|
||||
savePath = savepath_fromurl.take(QUrl::fromEncoded(from_url.toLocal8Bit()));
|
||||
} else {
|
||||
savePath = getSavePath(hash);
|
||||
savePath = getSavePath(hash, fromScanDir, path);
|
||||
}
|
||||
if(!defaultTempPath.isEmpty() && resumed && !TorrentPersistentData::isSeed(hash)) {
|
||||
qDebug("addTorrent::Temp folder is enabled.");
|
||||
@ -1495,14 +1500,13 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
|
||||
}
|
||||
|
||||
void Bittorrent::addTorrentsFromScanFolder(QStringList &pathList) {
|
||||
QString dir_path = FSWatcher->directories().first();
|
||||
foreach(const QString &file, pathList) {
|
||||
QString fullPath = dir_path+QDir::separator()+file;
|
||||
qDebug("File %s added", qPrintable(file));
|
||||
try {
|
||||
torrent_info t(fullPath.toLocal8Bit().data());
|
||||
addTorrent(fullPath, true);
|
||||
torrent_info t(file.toLocal8Bit().data());
|
||||
addTorrent(file, true);
|
||||
} catch(std::exception&) {
|
||||
qDebug("Ignoring incomplete torrent file: %s", fullPath.toLocal8Bit().data());
|
||||
qDebug("Ignoring incomplete torrent file: %s", file.toLocal8Bit().data());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1647,39 +1651,6 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Enable directory scanning
|
||||
void Bittorrent::enableDirectoryScanning(QString scan_dir) {
|
||||
if(!scan_dir.isEmpty()) {
|
||||
QDir newDir(scan_dir);
|
||||
if(!newDir.exists()) {
|
||||
qDebug("Scan dir %s does not exist, create it", scan_dir.toUtf8().data());
|
||||
newDir.mkpath(scan_dir);
|
||||
}
|
||||
if(FSWatcher == 0) {
|
||||
// Set up folder watching
|
||||
FSWatcher = new FileSystemWatcher(this);
|
||||
connect(FSWatcher, SIGNAL(torrentsAdded(QStringList&)), this, SLOT(addTorrentsFromScanFolder(QStringList&)));
|
||||
FSWatcher->addPath(scan_dir);
|
||||
} else {
|
||||
QString old_scan_dir = "";
|
||||
if(!FSWatcher->directories().empty())
|
||||
old_scan_dir = FSWatcher->directories().first();
|
||||
if(QDir(old_scan_dir) != QDir(scan_dir)) {
|
||||
if(!old_scan_dir.isEmpty())
|
||||
FSWatcher->removePath(old_scan_dir);
|
||||
FSWatcher->addPath(scan_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable directory scanning
|
||||
void Bittorrent::disableDirectoryScanning() {
|
||||
if(FSWatcher) {
|
||||
delete FSWatcher;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the ports range in which is chosen the port the Bittorrent
|
||||
// session will listen to
|
||||
void Bittorrent::setListeningPort(int port) {
|
||||
@ -2133,12 +2104,13 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
|
||||
return s->status();
|
||||
}
|
||||
|
||||
QString Bittorrent::getSavePath(QString hash) {
|
||||
QString Bittorrent::getSavePath(QString hash, bool fromScanDir, QString filePath) {
|
||||
QString savePath;
|
||||
if(TorrentTempData::hasTempData(hash)) {
|
||||
savePath = TorrentTempData::getSavePath(hash);
|
||||
if(savePath.isEmpty())
|
||||
savePath = defaultSavePath;
|
||||
if(savePath.isEmpty()) {
|
||||
savePath = defaultSavePath;
|
||||
}
|
||||
if(appendLabelToSavePath) {
|
||||
qDebug("appendLabelToSavePath is true");
|
||||
QString label = TorrentTempData::getLabel(hash);
|
||||
@ -2152,9 +2124,13 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
|
||||
qDebug("getSavePath, got save_path from temp data: %s", savePath.toLocal8Bit().data());
|
||||
} else {
|
||||
savePath = TorrentPersistentData::getSavePath(hash);
|
||||
if(savePath.isEmpty())
|
||||
savePath = defaultSavePath;
|
||||
if(appendLabelToSavePath) {
|
||||
if(savePath.isEmpty()) {
|
||||
if(fromScanDir && m_scanFolders->downloadInTorrentFolder(filePath))
|
||||
savePath = QFileInfo(filePath).dir().path();
|
||||
else
|
||||
savePath = defaultSavePath;
|
||||
}
|
||||
if(!fromScanDir && appendLabelToSavePath) {
|
||||
QString label = TorrentPersistentData::getLabel(hash);
|
||||
if(!label.isEmpty()) {
|
||||
QDir save_dir(savePath);
|
||||
|
@ -52,10 +52,10 @@ using namespace libtorrent;
|
||||
|
||||
class downloadThread;
|
||||
class QTimer;
|
||||
class FileSystemWatcher;
|
||||
class FilterParserThread;
|
||||
class HttpServer;
|
||||
class BandwidthScheduler;
|
||||
class ScanFoldersModel;
|
||||
|
||||
class TrackerInfos {
|
||||
public:
|
||||
@ -102,7 +102,7 @@ private:
|
||||
// HTTP
|
||||
QPointer<downloadThread> downloader;
|
||||
// File System
|
||||
QPointer<FileSystemWatcher> FSWatcher;
|
||||
ScanFoldersModel *m_scanFolders;
|
||||
// Console / Log
|
||||
QStringList consoleMessages;
|
||||
QStringList peerBanMessages;
|
||||
@ -142,7 +142,7 @@ private:
|
||||
bool exiting;
|
||||
|
||||
protected:
|
||||
QString getSavePath(QString hash);
|
||||
QString getSavePath(QString hash, bool fromScanDir = false, QString filePath = QString());
|
||||
bool initWebUi(QString username, QString password, int port);
|
||||
|
||||
public:
|
||||
@ -195,8 +195,6 @@ public slots:
|
||||
void saveDHTEntry();
|
||||
void preAllocateAllFiles(bool b);
|
||||
void saveFastResumeData();
|
||||
void enableDirectoryScanning(QString scan_dir);
|
||||
void disableDirectoryScanning();
|
||||
void enableIPFilter(QString filter);
|
||||
void disableIPFilter();
|
||||
void setQueueingEnabled(bool enable);
|
||||
|
@ -129,8 +129,10 @@ void EventManager::setGlobalPreferences(QVariantMap m) const {
|
||||
Preferences::setTempPathEnabled(m["temp_path_enabled"].toBool());
|
||||
if(m.contains("temp_path"))
|
||||
Preferences::setTempPath(m["temp_path"].toString());
|
||||
if(m.contains("scan_dir"))
|
||||
Preferences::setScanDir(m["scan_dir"].toString());
|
||||
if(m.contains("scan_dirs"))
|
||||
Preferences::setScanDirs(m["scan_dirs"].toStringList());
|
||||
if(m.contains("download_in_scan_dirs"))
|
||||
Preferences::setDownloadInScanDirs(m["download_in_scan_dirs"].toList());
|
||||
if(m.contains("export_dir"))
|
||||
Preferences::setExportDir(m["export_dir"].toString());
|
||||
if(m.contains("preallocate_all"))
|
||||
@ -229,8 +231,8 @@ QVariantMap EventManager::getGlobalPreferences() const {
|
||||
data["save_path"] = Preferences::getSavePath();
|
||||
data["temp_path_enabled"] = Preferences::isTempPathEnabled();
|
||||
data["temp_path"] = Preferences::getTempPath();
|
||||
data["scan_dir_enabled"] = Preferences::isDirScanEnabled();
|
||||
data["scan_dir"] = Preferences::getScanDir();
|
||||
data["scan_dirs"] = Preferences::getScanDirs();
|
||||
data["download_in_scan_dirs"] = Preferences::getDownloadInScanDirs();
|
||||
data["export_dir_enabled"] = Preferences::isTorrentExportEnabled();
|
||||
data["export_dir"] = Preferences::getExportDir();
|
||||
data["preallocate_all"] = Preferences::preAllocateAllFiles();
|
||||
|
@ -34,12 +34,14 @@
|
||||
class FileSystemWatcher: public QFileSystemWatcher {
|
||||
Q_OBJECT
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
private:
|
||||
QDir watched_folder;
|
||||
#ifndef Q_WS_WIN
|
||||
QList<QDir> watched_folders;
|
||||
QPointer<QTimer> watch_timer;
|
||||
#endif
|
||||
QStringList filters;
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
protected:
|
||||
bool isNetworkFileSystem(QString path) {
|
||||
QString file = path;
|
||||
@ -98,12 +100,12 @@ protected:
|
||||
public:
|
||||
FileSystemWatcher(QObject *parent): QFileSystemWatcher(parent) {
|
||||
filters << "*.torrent";
|
||||
connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanFolder()));
|
||||
connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanLocalFolder(QString)));
|
||||
}
|
||||
|
||||
FileSystemWatcher(QString path, QObject *parent): QFileSystemWatcher(parent) {
|
||||
filters << "*.torrent";
|
||||
connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanFolder()));
|
||||
connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanLocalFolder(QString)));
|
||||
addPath(path);
|
||||
}
|
||||
|
||||
@ -115,33 +117,40 @@ public:
|
||||
}
|
||||
|
||||
QStringList directories() const {
|
||||
QStringList dirs;
|
||||
#ifndef Q_WS_WIN
|
||||
if(watch_timer)
|
||||
return QStringList(watched_folder.path());
|
||||
if(watch_timer) {
|
||||
foreach (const QDir &dir, watched_folders)
|
||||
dirs << dir.canonicalPath();
|
||||
}
|
||||
#endif
|
||||
return QFileSystemWatcher::directories();
|
||||
dirs << QFileSystemWatcher::directories();
|
||||
return dirs;
|
||||
}
|
||||
|
||||
void addPath(const QString & path) {
|
||||
#ifndef Q_WS_WIN
|
||||
watched_folder = QDir(path);
|
||||
if(!watched_folder.exists()) return;
|
||||
QDir dir(path);
|
||||
if (!dir.exists())
|
||||
return;
|
||||
// Check if the path points to a network file system or not
|
||||
if(isNetworkFileSystem(path)) {
|
||||
// Network mode
|
||||
Q_ASSERT(!watch_timer);
|
||||
qDebug("Network folder detected: %s", path.toLocal8Bit().data());
|
||||
qDebug("Network folder detected: %s", qPrintable(path));
|
||||
qDebug("Using file polling mode instead of inotify...");
|
||||
watched_folders << dir;
|
||||
// Set up the watch timer
|
||||
watch_timer = new QTimer(this);
|
||||
connect(watch_timer, SIGNAL(timeout()), this, SLOT(scanFolder()));
|
||||
watch_timer->start(5000); // 5 sec
|
||||
if (!watch_timer) {
|
||||
watch_timer = new QTimer(this);
|
||||
connect(watch_timer, SIGNAL(timeout()), this, SLOT(scanNetworkFolders()));
|
||||
watch_timer->start(5000); // 5 sec
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
// Normal mode
|
||||
qDebug("FS Watching is watching %s in normal mode", path.toLocal8Bit().data());
|
||||
QFileSystemWatcher::addPath(path);
|
||||
scanFolder();
|
||||
scanLocalFolder(path);
|
||||
#ifndef Q_WS_WIN
|
||||
}
|
||||
#endif
|
||||
@ -149,38 +158,58 @@ public:
|
||||
|
||||
void removePath(const QString & path) {
|
||||
#ifndef Q_WS_WIN
|
||||
if(watch_timer) {
|
||||
// Network mode
|
||||
if(QDir(path) == watched_folder) {
|
||||
delete watch_timer;
|
||||
QDir dir(path);
|
||||
for (int i = 0; i < watched_folders.count(); ++i) {
|
||||
if (QDir(watched_folders.at(i)) == dir) {
|
||||
watched_folders.removeAt(i);
|
||||
if (watched_folders.isEmpty())
|
||||
delete watch_timer;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
// Normal mode
|
||||
QFileSystemWatcher::removePath(path);
|
||||
#ifndef Q_WS_WIN
|
||||
}
|
||||
#endif
|
||||
// Normal mode
|
||||
QFileSystemWatcher::removePath(path);
|
||||
}
|
||||
|
||||
protected slots:
|
||||
// XXX: Does not detect file size changes to improve performance.
|
||||
void scanFolder() {
|
||||
qDebug("Scan folder was called");
|
||||
void scanLocalFolder(QString path) {
|
||||
qDebug("scanLocalFolder(%s) called", qPrintable(path));
|
||||
QStringList torrents;
|
||||
if(watch_timer) {
|
||||
torrents = watched_folder.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
} else {
|
||||
torrents = QDir(QFileSystemWatcher::directories().first()).entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
qDebug("FSWatcher: Polling manually folder %s", QFileSystemWatcher::directories().first().toLocal8Bit().data());
|
||||
}
|
||||
if(!torrents.empty())
|
||||
// Local folders scan
|
||||
addTorrentsFromDir(QDir(path), torrents);
|
||||
// Report detected torrent files
|
||||
if(!torrents.empty()) {
|
||||
qDebug("The following files are being reported: %s", qPrintable(torrents.join("\n")));
|
||||
emit torrentsAdded(torrents);
|
||||
}
|
||||
}
|
||||
|
||||
void scanNetworkFolders() {
|
||||
qDebug("scanNetworkFolders() called");
|
||||
QStringList torrents;
|
||||
// Network folders scan
|
||||
foreach (const QDir &dir, watched_folders) {
|
||||
qDebug("FSWatcher: Polling manually folder %s", qPrintable(dir.path()));
|
||||
addTorrentsFromDir(dir, torrents);
|
||||
}
|
||||
// Report detected torrent files
|
||||
if(!torrents.empty()) {
|
||||
qDebug("The following files are being reported: %s", qPrintable(torrents.join("\n")));
|
||||
emit torrentsAdded(torrents);
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void torrentsAdded(QStringList &pathList);
|
||||
|
||||
private:
|
||||
void addTorrentsFromDir(const QDir &dir, QStringList &torrents) {
|
||||
const QStringList &files = dir.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
foreach(const QString &file, files)
|
||||
torrents << dir.canonicalPath() + '/' + file;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // FILESYSTEMWATCHER_H
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "preferences.h"
|
||||
#include "misc.h"
|
||||
#include "advancedsettings.h"
|
||||
#include "scannedfoldersmodel.h"
|
||||
|
||||
// Constructor
|
||||
options_imp::options_imp(QWidget *parent):QDialog(parent){
|
||||
@ -62,6 +63,12 @@ options_imp::options_imp(QWidget *parent):QDialog(parent){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scanFoldersView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
||||
scanFoldersView->setModel(ScanFoldersModel::instance());
|
||||
connect(ScanFoldersModel::instance(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(enableApplyButton()));
|
||||
connect(scanFoldersView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(handleScanFolderViewSelectionChanged()));
|
||||
|
||||
connect(buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(applySettings(QAbstractButton*)));
|
||||
comboStyle->addItems(QStyleFactory::keys());
|
||||
// Languages supported
|
||||
@ -139,7 +146,6 @@ options_imp::options_imp(QWidget *parent):QDialog(parent){
|
||||
connect(checkNoSystray, SIGNAL(toggled(bool)), this, SLOT(setSystrayOptionsState(bool)));
|
||||
// Downloads tab
|
||||
connect(checkTempFolder, SIGNAL(toggled(bool)), this, SLOT(enableTempPathInput(bool)));
|
||||
connect(checkScanDir, SIGNAL(toggled(bool)), this, SLOT(enableDirScan(bool)));
|
||||
connect(checkExportDir, SIGNAL(toggled(bool)), this, SLOT(enableTorrentExport(bool)));
|
||||
// Connection tab
|
||||
connect(checkUploadLimit, SIGNAL(toggled(bool)), this, SLOT(enableUploadLimit(bool)));
|
||||
@ -187,8 +193,6 @@ options_imp::options_imp(QWidget *parent):QDialog(parent){
|
||||
connect(checkPreallocateAll, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
|
||||
connect(checkAdditionDialog, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
|
||||
connect(checkStartPaused, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
|
||||
connect(checkScanDir, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
|
||||
connect(textScanDir, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
|
||||
connect(checkExportDir, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton()));
|
||||
connect(textExportDir, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
|
||||
connect(actionTorrentDlOnDblClBox, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton()));
|
||||
@ -280,6 +284,8 @@ options_imp::options_imp(QWidget *parent):QDialog(parent){
|
||||
// Main destructor
|
||||
options_imp::~options_imp(){
|
||||
qDebug("-> destructing Options");
|
||||
foreach (const QString &path, addedScanDirs)
|
||||
ScanFoldersModel::instance()->removePath(path);
|
||||
delete scrollArea_advanced->layout();
|
||||
delete advancedSettings;
|
||||
}
|
||||
@ -366,7 +372,8 @@ void options_imp::saveOptions(){
|
||||
settings.setValue(QString::fromUtf8("PreAllocation"), preAllocateAllFiles());
|
||||
settings.setValue(QString::fromUtf8("AdditionDialog"), useAdditionDialog());
|
||||
settings.setValue(QString::fromUtf8("StartInPause"), addTorrentsInPause());
|
||||
settings.setValue(QString::fromUtf8("ScanDir"), getScanDir());
|
||||
ScanFoldersModel::instance()->makePersistent(settings);
|
||||
addedScanDirs.clear();
|
||||
Preferences::setExportDir(getExportDir());
|
||||
settings.setValue(QString::fromUtf8("DblClOnTorDl"), getActionOnDblClOnTorrentDl());
|
||||
settings.setValue(QString::fromUtf8("DblClOnTorFn"), getActionOnDblClOnTorrentFn());
|
||||
@ -589,17 +596,6 @@ void options_imp::loadOptions(){
|
||||
checkPreallocateAll->setChecked(Preferences::preAllocateAllFiles());
|
||||
checkAdditionDialog->setChecked(Preferences::useAdditionDialog());
|
||||
checkStartPaused->setChecked(Preferences::addTorrentsInPause());
|
||||
strValue = Preferences::getScanDir();
|
||||
if(strValue.isEmpty()) {
|
||||
// Disable
|
||||
checkScanDir->setChecked(false);
|
||||
enableDirScan(checkScanDir->isChecked());
|
||||
} else {
|
||||
// enable
|
||||
checkScanDir->setChecked(true);
|
||||
textScanDir->setText(strValue);
|
||||
enableDirScan(checkScanDir->isChecked());
|
||||
}
|
||||
|
||||
strValue = Preferences::getExportDir();
|
||||
if(strValue.isEmpty()) {
|
||||
@ -923,10 +919,6 @@ bool options_imp::confirmOnExit() const{
|
||||
return checkConfirmExit->isChecked();
|
||||
}
|
||||
|
||||
bool options_imp::isDirScanEnabled() const {
|
||||
return checkScanDir->isChecked();
|
||||
}
|
||||
|
||||
bool options_imp::isQueueingSystemEnabled() const {
|
||||
return checkEnableQueueing->isChecked();
|
||||
}
|
||||
@ -1241,11 +1233,6 @@ void options_imp::enableHTTPProxyAuth(bool checked){
|
||||
textProxyPassword_http->setEnabled(checked);
|
||||
}
|
||||
|
||||
void options_imp::enableDirScan(bool checked){
|
||||
textScanDir->setEnabled(checked);
|
||||
browseScanDirButton->setEnabled(checked);
|
||||
}
|
||||
|
||||
void options_imp::enableTorrentExport(bool checked) {
|
||||
textExportDir->setEnabled(checked);
|
||||
browseExportDirButton->setEnabled(checked);
|
||||
@ -1340,15 +1327,6 @@ void options_imp::setLocale(QString locale){
|
||||
}
|
||||
}
|
||||
|
||||
// Return scan dir set in options
|
||||
QString options_imp::getScanDir() const {
|
||||
if(checkScanDir->isChecked()){
|
||||
return misc::expandPath(textScanDir->text());
|
||||
}else{
|
||||
return QString::null;
|
||||
}
|
||||
}
|
||||
|
||||
QString options_imp::getExportDir() const {
|
||||
if(checkExportDir->isChecked()){
|
||||
return misc::expandPath(textExportDir->text());
|
||||
@ -1371,21 +1349,45 @@ int options_imp::getActionOnDblClOnTorrentFn() const {
|
||||
return actionTorrentFnOnDblClBox->currentIndex();
|
||||
}
|
||||
|
||||
// Display dialog to choose scan dir
|
||||
void options_imp::on_browseScanDirButton_clicked() {
|
||||
QString scan_path = misc::expandPath(textScanDir->text());
|
||||
QDir scanDir(scan_path);
|
||||
QString dir;
|
||||
if(!scan_path.isEmpty() && scanDir.exists()) {
|
||||
dir = QFileDialog::getExistingDirectory(this, tr("Choose scan directory"), scanDir.absolutePath());
|
||||
} else {
|
||||
dir = QFileDialog::getExistingDirectory(this, tr("Choose scan directory"), QDir::homePath());
|
||||
}
|
||||
if(!dir.isNull()){
|
||||
textScanDir->setText(dir);
|
||||
void options_imp::on_addScanFolderButton_clicked() {
|
||||
const QString dir = QFileDialog::getExistingDirectory(this, tr("Add directory to scan"));
|
||||
if (!dir.isEmpty()) {
|
||||
const ScanFoldersModel::PathStatus status = ScanFoldersModel::instance()->addPath(dir);
|
||||
QString error;
|
||||
switch (status) {
|
||||
case ScanFoldersModel::AlreadyInList:
|
||||
error = tr("Folder is already being watched.").arg(dir);
|
||||
break;
|
||||
case ScanFoldersModel::DoesNotExist:
|
||||
error = tr("Folder does not exist.");
|
||||
break;
|
||||
case ScanFoldersModel::CannotRead:
|
||||
error = tr("Folder is not readable.");
|
||||
break;
|
||||
default:
|
||||
addedScanDirs << dir;
|
||||
enableApplyButton();
|
||||
}
|
||||
|
||||
if (!error.isEmpty()) {
|
||||
QMessageBox::warning(this, tr("Failure"), tr("Failed to add Scan Folder '%1': %2").arg(dir).arg(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void options_imp::on_removeScanFolderButton_clicked() {
|
||||
const QModelIndexList &selected
|
||||
= scanFoldersView->selectionModel()->selectedIndexes();
|
||||
if (selected.isEmpty())
|
||||
return;
|
||||
Q_ASSERT(selected.count() == ScanFoldersModel::instance()->columnCount());
|
||||
ScanFoldersModel::instance()->removePath(selected.first().row());
|
||||
}
|
||||
|
||||
void options_imp::handleScanFolderViewSelectionChanged() {
|
||||
removeScanFolderButton->setEnabled(!scanFoldersView->selectionModel()->selectedIndexes().isEmpty());
|
||||
}
|
||||
|
||||
void options_imp::on_browseExportDirButton_clicked() {
|
||||
QString export_path = misc::expandPath(textExportDir->text());
|
||||
QDir exportDir(export_path);
|
||||
|
@ -52,6 +52,7 @@ private:
|
||||
QStringList locales;
|
||||
QAbstractButton *applyButton;
|
||||
AdvancedSettings *advancedSettings;
|
||||
QList<QString> addedScanDirs;
|
||||
|
||||
public:
|
||||
// Contructor / Destructor
|
||||
@ -82,8 +83,6 @@ protected:
|
||||
bool preAllocateAllFiles() const;
|
||||
bool useAdditionDialog() const;
|
||||
bool addTorrentsInPause() const;
|
||||
bool isDirScanEnabled() const;
|
||||
QString getScanDir() const;
|
||||
QString getExportDir() const;
|
||||
int getActionOnDblClOnTorrentDl() const;
|
||||
int getActionOnDblClOnTorrentFn() const;
|
||||
@ -136,7 +135,6 @@ protected slots:
|
||||
void enableUploadLimit(bool checked);
|
||||
void enableDownloadLimit(bool checked);
|
||||
void enableTempPathInput(bool checked);
|
||||
void enableDirScan(bool checked);
|
||||
void enableTorrentExport(bool checked);
|
||||
void enablePeerProxy(int comboIndex);
|
||||
void enablePeerProxyAuth(bool checked);
|
||||
@ -159,7 +157,6 @@ protected slots:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void on_buttonBox_rejected();
|
||||
void applySettings(QAbstractButton* button);
|
||||
void on_browseScanDirButton_clicked();
|
||||
void on_browseExportDirButton_clicked();
|
||||
void on_browseFilterButton_clicked();
|
||||
void on_browseSaveDirButton_clicked();
|
||||
@ -173,6 +170,9 @@ protected slots:
|
||||
void loadWindowState();
|
||||
void saveWindowState() const;
|
||||
void on_randomButton_clicked();
|
||||
void on_addScanFolderButton_clicked();
|
||||
void on_removeScanFolderButton_clicked();
|
||||
void handleScanFolderViewSelectionChanged();
|
||||
|
||||
public slots:
|
||||
void setLocale(QString locale);
|
||||
|
@ -191,22 +191,25 @@ public:
|
||||
return settings.value(QString::fromUtf8("Preferences/Downloads/StartInPause"), false).toBool();
|
||||
}
|
||||
|
||||
static bool isDirScanEnabled() {
|
||||
static QStringList getScanDirs() {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
return !settings.value(QString::fromUtf8("Preferences/Downloads/ScanDir"), QString()).toString().isEmpty();
|
||||
return settings.value(QString::fromUtf8("Preferences/Downloads/ScanDirs"), QStringList()).toStringList();
|
||||
}
|
||||
|
||||
static QString getScanDir() {
|
||||
// This must be called somewhere with data from the model
|
||||
static void setScanDirs(const QStringList &dirs) {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
return settings.value(QString::fromUtf8("Preferences/Downloads/ScanDir"), QString()).toString();
|
||||
settings.setValue(QString::fromUtf8("Preferences/Downloads/ScanDirs"), dirs);
|
||||
}
|
||||
|
||||
static void setScanDir(QString path) {
|
||||
path = path.trimmed();
|
||||
if(path.isEmpty())
|
||||
path = QString();
|
||||
static QVariantList getDownloadInScanDirs() {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
settings.setValue(QString::fromUtf8("Preferences/Downloads/ScanDir"), path);
|
||||
return settings.value(QString::fromUtf8("Preferences/Downloads/DownloadInScanDirs"), QVariantList()).toList();
|
||||
}
|
||||
|
||||
static void setDownloadInScanDirs(const QVariantList &list) {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
settings.setValue(QString::fromUtf8("Preferences/Downloads/DownloadInScanDirs"), list);
|
||||
}
|
||||
|
||||
static bool isTorrentExportEnabled() {
|
||||
|
@ -432,7 +432,7 @@ void RSSImp::refreshNewsList(QTreeWidgetItem* item) {
|
||||
QList<RssItem*> news;
|
||||
if(rss_item == rssmanager)
|
||||
news = RssManager::sortNewsList(rss_item->getUnreadNewsList());
|
||||
else
|
||||
else if(rss_item)
|
||||
news = RssManager::sortNewsList(rss_item->getNewsList());
|
||||
// Clear the list first
|
||||
textBrowser->clear();
|
||||
|
191
src/scannedfoldersmodel.cpp
Normal file
191
src/scannedfoldersmodel.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2010 Christian Kandeler, 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 "scannedfoldersmodel.h"
|
||||
|
||||
#include "filesystemwatcher.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
namespace {
|
||||
const int PathColumn = 0;
|
||||
const int DownloadAtTorrentColumn = 1;
|
||||
}
|
||||
|
||||
class ScanFoldersModel::PathData {
|
||||
public:
|
||||
PathData(const QString &path) : path(path), downloadAtPath(false) {}
|
||||
const QString path;
|
||||
bool downloadAtPath;
|
||||
};
|
||||
|
||||
ScanFoldersModel *ScanFoldersModel::instance(QObject *parent) {
|
||||
Q_ASSERT(!parent != !m_instance);
|
||||
if (!m_instance)
|
||||
m_instance = new ScanFoldersModel(parent);
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
ScanFoldersModel::ScanFoldersModel(QObject *parent) :
|
||||
QAbstractTableModel(parent), m_fsWatcher(0)
|
||||
{ }
|
||||
|
||||
ScanFoldersModel::~ScanFoldersModel() { }
|
||||
|
||||
int ScanFoldersModel::rowCount(const QModelIndex &parent) const {
|
||||
return parent.isValid() ? 0 : m_pathList.count();
|
||||
}
|
||||
|
||||
int ScanFoldersModel::columnCount(const QModelIndex &parent) const {
|
||||
Q_UNUSED(parent);
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant ScanFoldersModel::data(const QModelIndex &index, int role) const {
|
||||
if (!index.isValid() || index.row() >= rowCount())
|
||||
return QVariant();
|
||||
|
||||
const QSharedPointer<PathData> &pathData = m_pathList.at(index.row());
|
||||
if (index.column() == PathColumn && role == Qt::DisplayRole)
|
||||
return pathData->path;
|
||||
if (index.column() == DownloadAtTorrentColumn && role == Qt::CheckStateRole)
|
||||
return pathData->downloadAtPath ? Qt::Checked : Qt::Unchecked;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant ScanFoldersModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||
if (orientation != Qt::Horizontal || role != Qt::DisplayRole || section < 0 || section >= columnCount())
|
||||
return QVariant();
|
||||
|
||||
if (section == PathColumn)
|
||||
return tr("Watched Folder");
|
||||
return tr("Download here");
|
||||
}
|
||||
|
||||
Qt::ItemFlags ScanFoldersModel::flags(const QModelIndex &index) const {
|
||||
if (!index.isValid() || index.row() >= rowCount() || index.column() != DownloadAtTorrentColumn)
|
||||
return QAbstractTableModel::flags(index);
|
||||
return QAbstractTableModel::flags(index) | Qt::ItemIsUserCheckable;
|
||||
}
|
||||
|
||||
bool ScanFoldersModel::setData(const QModelIndex &index, const QVariant &value, int role) {
|
||||
if (!index.isValid() || index.row() >= rowCount() || index.column() > DownloadAtTorrentColumn || role != Qt::CheckStateRole)
|
||||
return false;
|
||||
Q_ASSERT(index.column() == DownloadAtTorrentColumn);
|
||||
m_pathList[index.row()]->downloadAtPath = (value.toInt() == Qt::Checked);
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
ScanFoldersModel::PathStatus ScanFoldersModel::addPath(const QString &path) {
|
||||
QDir dir(path);
|
||||
if (!dir.exists())
|
||||
return DoesNotExist;
|
||||
if (!dir.isReadable())
|
||||
return CannotRead;
|
||||
const QString &canonicalPath = dir.canonicalPath();
|
||||
if (findPathData(canonicalPath) != -1)
|
||||
return AlreadyInList;
|
||||
if (!m_fsWatcher) {
|
||||
m_fsWatcher = new FileSystemWatcher(this);
|
||||
connect(m_fsWatcher, SIGNAL(torrentsAdded(QStringList&)), this, SIGNAL(torrentsAdded(QStringList&)));
|
||||
}
|
||||
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
||||
m_pathList << QSharedPointer<PathData>(new PathData(canonicalPath));
|
||||
endInsertRows();
|
||||
m_fsWatcher->addPath(canonicalPath);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
void ScanFoldersModel::removePath(int row) {
|
||||
Q_ASSERT(row >= 0 && row < rowCount());
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_fsWatcher->removePath(m_pathList.at(row)->path);
|
||||
m_pathList.removeAt(row);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
bool ScanFoldersModel::removePath(const QString &path) {
|
||||
const int row = findPathData(path);
|
||||
if (row == -1)
|
||||
return false;
|
||||
removePath(row);
|
||||
return true;
|
||||
}
|
||||
|
||||
ScanFoldersModel::PathStatus ScanFoldersModel::setDownloadAtPath(int row, bool downloadAtPath) {
|
||||
Q_ASSERT(row >= 0 && row < rowCount());
|
||||
|
||||
bool &oldValue = m_pathList[row]->downloadAtPath;
|
||||
if (oldValue != downloadAtPath) {
|
||||
if (downloadAtPath) {
|
||||
QTemporaryFile testFile(m_pathList[row]->path + "/tmpFile");
|
||||
if (!testFile.open())
|
||||
return CannotWrite;
|
||||
}
|
||||
oldValue = downloadAtPath;
|
||||
const QModelIndex &changedIndex = index(row, DownloadAtTorrentColumn);
|
||||
emit dataChanged(changedIndex, changedIndex);
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
||||
bool ScanFoldersModel::downloadInTorrentFolder(const QString &filePath) const {
|
||||
const int row = findPathData(QFileInfo(filePath).dir().path());
|
||||
Q_ASSERT(row != -1);
|
||||
return m_pathList.at(row)->downloadAtPath;
|
||||
}
|
||||
|
||||
int ScanFoldersModel::findPathData(const QString &path) const {
|
||||
for (int i = 0; i < m_pathList.count(); ++i) {
|
||||
const QSharedPointer<PathData> &pathData = m_pathList.at(i);
|
||||
if (pathData->path == path)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ScanFoldersModel::makePersistent(QSettings &settings) {
|
||||
QStringList paths;
|
||||
QList<QVariant> downloadInFolderInfo;
|
||||
foreach (const QSharedPointer<PathData> &pathData, m_pathList) {
|
||||
paths << pathData->path;
|
||||
downloadInFolderInfo << pathData->downloadAtPath;
|
||||
}
|
||||
settings.setValue(QString::fromUtf8("ScanDirs"), paths);
|
||||
settings.setValue(QString::fromUtf8("DownloadInScanDirs"), downloadInFolderInfo);
|
||||
}
|
||||
|
||||
ScanFoldersModel *ScanFoldersModel::m_instance = 0;
|
82
src/scannedfoldersmodel.h
Normal file
82
src/scannedfoldersmodel.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2010 Christian Kandeler, Christophe Dumez
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#ifndef SCANNEDFOLDERSMODEL_H
|
||||
#define SCANNEDFOLDERSMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
#include <QStringList>
|
||||
|
||||
class FileSystemWatcher;
|
||||
class QSettings;
|
||||
|
||||
class ScanFoldersModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(ScanFoldersModel)
|
||||
|
||||
public:
|
||||
enum PathStatus { Ok, DoesNotExist, CannotRead, CannotWrite, AlreadyInList };
|
||||
static ScanFoldersModel *instance(QObject *parent = 0);
|
||||
~ScanFoldersModel();
|
||||
|
||||
virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
// TODO: removePaths(); singular version becomes private helper functions;
|
||||
// also: remove functions should take modelindexes
|
||||
PathStatus addPath(const QString &path);
|
||||
void removePath(int row);
|
||||
bool removePath(const QString &path);
|
||||
PathStatus setDownloadAtPath(int row, bool downloadAtPath);
|
||||
|
||||
bool downloadInTorrentFolder(const QString &filePath) const;
|
||||
void makePersistent(QSettings &settings);
|
||||
|
||||
signals:
|
||||
// The absolute paths of new torrent files in the scanned directories.
|
||||
void torrentsAdded(QStringList &pathList);
|
||||
|
||||
private:
|
||||
explicit ScanFoldersModel(QObject *parent);
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||
static ScanFoldersModel *m_instance;
|
||||
class PathData;
|
||||
int findPathData(const QString &path) const;
|
||||
|
||||
QList<QSharedPointer<PathData> > m_pathList;
|
||||
FileSystemWatcher *m_fsWatcher;
|
||||
};
|
||||
|
||||
#endif // SCANNEDFOLDERSMODEL_H
|
67
src/src.pro
67
src/src.pro
@ -15,6 +15,7 @@ DEFINES += VERSION=\\\"v2.2.0beta4\\\"
|
||||
DEFINES += VERSION_MAJOR=2
|
||||
DEFINES += VERSION_MINOR=2
|
||||
DEFINES += VERSION_BUGFIX=0
|
||||
|
||||
# NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL
|
||||
DEFINES += VERSION_TYPE=BETA
|
||||
|
||||
@ -38,17 +39,14 @@ contains(DEBUG_MODE, 0) {
|
||||
include(../conf.pri)
|
||||
|
||||
# Target
|
||||
#target.path = $$BINDIR
|
||||
# target.path = $$BINDIR
|
||||
target.path = $$PREFIX/bin/
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
# Man page
|
||||
contains(DEFINES, DISABLE_GUI) {
|
||||
man.files = ../doc/qbittorrent-nox.1
|
||||
} else {
|
||||
man.files = ../doc/qbittorrent.1
|
||||
}
|
||||
contains(DEFINES, DISABLE_GUI):man.files = ../doc/qbittorrent-nox.1
|
||||
else:man.files = ../doc/qbittorrent.1
|
||||
man.path = $$PREFIX/share/man/man1/
|
||||
INSTALLS += man
|
||||
|
||||
@ -94,11 +92,10 @@ contains(DEFINES, DISABLE_GUI) {
|
||||
}
|
||||
|
||||
contains(DEFINES, DISABLE_GUI) {
|
||||
QT=core
|
||||
QT = core
|
||||
TARGET = qbittorrent-nox
|
||||
} else {
|
||||
TARGET = qbittorrent
|
||||
}
|
||||
else:TARGET = qbittorrent
|
||||
|
||||
# QMAKE_CXXFLAGS_RELEASE += -fwrapv
|
||||
# QMAKE_CXXFLAGS_DEBUG += -fwrapv
|
||||
@ -107,9 +104,8 @@ CONFIG += link_pkgconfig
|
||||
PKGCONFIG += "libtorrent-rasterbar"
|
||||
|
||||
QT += network
|
||||
!contains(DEFINES, DISABLE_GUI) {
|
||||
QT += xml
|
||||
}
|
||||
!contains(DEFINES, DISABLE_GUI):QT += xml
|
||||
|
||||
DEFINES += QT_NO_CAST_TO_ASCII
|
||||
|
||||
# Windows
|
||||
@ -127,31 +123,25 @@ win32:LIBS += -lssl32 \
|
||||
DEFINES += WITH_GEOIP_EMBEDDED
|
||||
message("On Windows, GeoIP database must be embedded.")
|
||||
}
|
||||
|
||||
macx {
|
||||
DEFINES += WITH_GEOIP_EMBEDDED
|
||||
message("On Mac OS X, GeoIP database must be embedded.")
|
||||
}
|
||||
|
||||
unix:!macx {
|
||||
contains(DEFINES, WITH_GEOIP_EMBEDDED) {
|
||||
message("You chose to embed GeoIP database in qBittorrent executable.")
|
||||
}
|
||||
}
|
||||
unix:!macx:contains(DEFINES, WITH_GEOIP_EMBEDDED):message("You chose to embed GeoIP database in qBittorrent executable.")
|
||||
|
||||
# Add GeoIP resource file if the GeoIP database
|
||||
# should be embedded in qBittorrent executable
|
||||
contains(DEFINES, WITH_GEOIP_EMBEDDED) {
|
||||
exists("geoip/GeoIP.dat") {
|
||||
message("GeoIP.dat was found in src/geoip/.")
|
||||
RESOURCES += geoip.qrc
|
||||
} else {
|
||||
DEFINES -= WITH_GEOIP_EMBEDDED
|
||||
error("GeoIP.dat was not found in src/geoip/ folder, please follow instructions in src/geoip/README.")
|
||||
}
|
||||
} else {
|
||||
message("GeoIP database will not be embedded in qBittorrent executable.")
|
||||
exists("geoip/GeoIP.dat") {
|
||||
message("GeoIP.dat was found in src/geoip/.")
|
||||
RESOURCES += geoip.qrc
|
||||
}
|
||||
else {
|
||||
DEFINES -= WITH_GEOIP_EMBEDDED
|
||||
error("GeoIP.dat was not found in src/geoip/ folder, please follow instructions in src/geoip/README.")
|
||||
}
|
||||
}
|
||||
else:message("GeoIP database will not be embedded in qBittorrent executable.")
|
||||
}
|
||||
|
||||
# Resource files
|
||||
@ -206,12 +196,11 @@ HEADERS += misc.h \
|
||||
torrentpersistentdata.h \
|
||||
filesystemwatcher.h \
|
||||
preferences.h \
|
||||
bandwidthscheduler.h
|
||||
bandwidthscheduler.h \
|
||||
scannedfoldersmodel.h
|
||||
|
||||
contains(DEFINES, DISABLE_GUI) {
|
||||
HEADERS += headlessloader.h
|
||||
} else {
|
||||
HEADERS += GUI.h \
|
||||
contains(DEFINES, DISABLE_GUI):HEADERS += headlessloader.h
|
||||
else:HEADERS += GUI.h \
|
||||
feedList.h \
|
||||
supportedengines.h \
|
||||
transferlistwidget.h \
|
||||
@ -252,10 +241,8 @@ contains(DEFINES, DISABLE_GUI) {
|
||||
trackerlogin.h \
|
||||
pieceavailabilitybar.h \
|
||||
advancedsettings.h
|
||||
}
|
||||
|
||||
!contains(DEFINES, DISABLE_GUI) {
|
||||
FORMS += ui/mainwindow.ui \
|
||||
!contains(DEFINES, DISABLE_GUI):FORMS += ui/mainwindow.ui \
|
||||
ui/options.ui \
|
||||
ui/about.ui \
|
||||
ui/createtorrent.ui \
|
||||
@ -274,7 +261,6 @@ contains(DEFINES, DISABLE_GUI) {
|
||||
ui/propertieswidget.ui \
|
||||
ui/peer.ui \
|
||||
ui/confirmdeletiondlg.ui
|
||||
}
|
||||
|
||||
SOURCES += main.cpp \
|
||||
bittorrent.cpp \
|
||||
@ -284,10 +270,10 @@ SOURCES += main.cpp \
|
||||
httpconnection.cpp \
|
||||
httprequestparser.cpp \
|
||||
httpresponsegenerator.cpp \
|
||||
eventmanager.cpp
|
||||
eventmanager.cpp \
|
||||
scannedfoldersmodel.cpp
|
||||
|
||||
!contains(DEFINES, DISABLE_GUI) {
|
||||
SOURCES += GUI.cpp \
|
||||
!contains(DEFINES, DISABLE_GUI):SOURCES += GUI.cpp \
|
||||
options_imp.cpp \
|
||||
createtorrent_imp.cpp \
|
||||
searchengine.cpp \
|
||||
@ -299,6 +285,5 @@ SOURCES += main.cpp \
|
||||
transferlistwidget.cpp \
|
||||
propertieswidget.cpp \
|
||||
peerlistwidget.cpp
|
||||
}
|
||||
|
||||
DESTDIR = .
|
||||
|
@ -565,10 +565,10 @@ QGroupBox {
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-76</y>
|
||||
<width>644</width>
|
||||
<height>548</height>
|
||||
<x>-30</x>
|
||||
<y>0</y>
|
||||
<width>632</width>
|
||||
<height>684</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||
@ -583,7 +583,7 @@ QGroupBox {
|
||||
<property name="title">
|
||||
<string>File system</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_25">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="styleSheet">
|
||||
@ -696,57 +696,120 @@ QGroupBox {
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkScanDir">
|
||||
<property name="text">
|
||||
<string>Automatically load .torrent files from:</string>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Check Folders for .torrent Files:</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_38">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_16">
|
||||
<item>
|
||||
<widget class="QTableView" name="scanFoldersView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>80</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>80</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_37">
|
||||
<item>
|
||||
<widget class="QPushButton" name="addScanFolderButton">
|
||||
<property name="text">
|
||||
<string>Add folder ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="removeScanFolderButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="textScanDir">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string>QLineEdit {
|
||||
margin-left: 23px;
|
||||
}</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="browseScanDirButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>27</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/Icons/oxygen/browse.png</normaloff>:/Icons/oxygen/browse.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkExportDir">
|
||||
<property name="text">
|
||||
@ -1060,8 +1123,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>482</height>
|
||||
<width>447</width>
|
||||
<height>288</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_28">
|
||||
@ -1305,8 +1368,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>490</height>
|
||||
<width>364</width>
|
||||
<height>332</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
||||
@ -1710,8 +1773,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>490</height>
|
||||
<width>459</width>
|
||||
<height>415</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_20">
|
||||
@ -2127,8 +2190,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>490</height>
|
||||
<width>475</width>
|
||||
<height>312</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
@ -2561,8 +2624,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>490</height>
|
||||
<width>287</width>
|
||||
<height>124</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_21">
|
||||
@ -2658,8 +2721,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>490</height>
|
||||
<width>213</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_23">
|
||||
@ -2825,8 +2888,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>490</height>
|
||||
<width>445</width>
|
||||
<height>192</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_24">
|
||||
@ -3000,8 +3063,8 @@ QGroupBox {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>490</height>
|
||||
<width>96</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_36"/>
|
||||
@ -3062,7 +3125,6 @@ QGroupBox {
|
||||
<tabstop>checkPreallocateAll</tabstop>
|
||||
<tabstop>checkAdditionDialog</tabstop>
|
||||
<tabstop>checkStartPaused</tabstop>
|
||||
<tabstop>browseScanDirButton</tabstop>
|
||||
<tabstop>spinPort</tabstop>
|
||||
<tabstop>checkUPnP</tabstop>
|
||||
<tabstop>checkNATPMP</tabstop>
|
||||
|
Loading…
x
Reference in New Issue
Block a user