Compare commits

...

19 Commits

Author SHA1 Message Date
Christophe Dumez
22f0f20a45 Tagged rc9 release 2007-11-24 12:11:12 +00:00
Christophe Dumez
b1d8fb0f11 - Some bug fixes (Proxy) 2007-11-22 10:49:10 +00:00
Christophe Dumez
78fc5d4865 - BUGFIX: Added proxy support in search engine, RSS, downloads from urls
- Must add SOCKS5 proxy support in search engine plugins (python -> urllib2?)
2007-11-21 22:33:32 +00:00
Christophe Dumez
19996736d6 do not save fastresume data regularly for seeding torrents 2007-11-21 20:34:17 +00:00
Christophe Dumez
6f9d22af03 - BUGFIX: title bar is now reset when "Display speed in title" is disabled 2007-11-21 20:18:11 +00:00
Christophe Dumez
6b6d05a380 - BUGFIX: Fixed possible overflow in ETA calculation 2007-11-21 19:01:24 +00:00
Christophe Dumez
df92e3e5e9 - Save fastresume data every minute instead of every 10 sec 2007-11-21 16:50:26 +00:00
Christophe Dumez
26b6c26ea8 - Fixed segfault that would happen when unfiltering files in torrent addition dialog (closes #163379) 2007-11-19 21:44:21 +00:00
Christophe Dumez
1b6183bfa3 - BUGFIX: Saving trackers file only when necessary 2007-11-19 21:22:48 +00:00
Christophe Dumez
7edbaa3847 - BUGFIX: Do not save fastresume data for checking torrents anymore 2007-11-19 20:45:35 +00:00
Christophe Dumez
2ee152a374 - BUGFIX: Do no pause torrents before saving fastresume data anymore (no longer needed)
- BUGFIX: Save fast resume data regularly (every 10 seconds) to avoid downloading from s
cratch if qBittorrent crashes
2007-11-19 20:36:01 +00:00
Christophe Dumez
bc8ac43a54 - BUGFIX: Improved proxy support in search engine (HTTP only) 2007-11-16 20:01:15 +00:00
Christophe Dumez
5f48a51070 - BUGFIX: Remember properties window size and position 2007-11-16 19:35:12 +00:00
Christophe Dumez
c3a6b24ed1 - FEATURE: Better media file preview (player detected automatically) 2007-11-16 18:39:50 +00:00
Christophe Dumez
c3b22c9a01 bump version to rc8 2007-11-14 21:50:33 +00:00
Christophe Dumez
5d09ace7eb - Removed a fedora 7 workaround 2007-11-13 10:31:42 +00:00
Christophe Dumez
fe37724338 - Removed Fedora pkg-config workaround because Fedora 8 fixed the problem 2007-11-10 09:27:25 +00:00
Christophe Dumez
8aaacbe38d - BUGFIX: Stop search when clearing results 2007-11-07 11:18:09 +00:00
Christophe Dumez
edc625c9c9 - fixed torrent files filtering (closes #158846) 2007-11-06 20:57:36 +00:00
25 changed files with 435 additions and 412 deletions

View File

@@ -41,9 +41,11 @@
- FEATURE: Added an option to automatically delete torrents when they reach a given ratio (>= 1.0)
- FEATURE: Added an option to display current transfer speeds in title bar
- FEATURE: Torrent content is now displayed as a tree
- FEATURE: Better media file preview (player detected automatically)
- I18N: Added Hungarian translation
- I18N: Added Brazilian translation
- BUGFIX: Progress of paused torrents is now correct on restart
- BUGFIX: clear the results of a search stops searching
- BUGFIX: Progress column gets sorted on restart it is was during last execution
- BUGFIX: Made ETA more reliable using stats instead of instant values
- BUGFIX: Remove torrent from hard drive used to delete parent folder if empty
@@ -66,6 +68,8 @@
- BUGFIX: Fixed drag'n drop on non-KDE systems
- BUGFIX: Removed build dependency on Python
- BUGFIX: Catching DHT exception in case there is a problem
- BUGFIX: Remember properties window size and position
- BUGFIX: Improved proxy support in search engine (HTTP only)
- COSMETIC: Redesigned torrent properties a little
- COSMETIC: Totally redesigned program preferences
- COSMETIC: Display more logs messages concerning features

View File

@@ -25,7 +25,7 @@ Dependencies:
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
- libcommoncpp2
- libcurl
- python >= 2.3 (needed by search engine)

31
TODO
View File

@@ -8,11 +8,9 @@
- Skins support? (contact Mateusz)
// Harder
- Display a progress bar that really represents the pieces we have (like in eMule)
- Torrent scheduler ala µtorrent/Bitcomet
// Waiting for libtorrent
- File selection in a torrent in compact mode
- Allow to prioritize torrents (may code this in qBittorrent?)
// Unsure
@@ -52,16 +50,19 @@
-> in download list
-> in seeding list
// in v1.0.0 - FEATURE FREEZE
- Fix all (or almost all) opened bugs in bug tracker
- Recheck doc
- Translations update (IN PROGRESS)
rc6->rc7 changelog:
- BUGFIX: Catching DHT exception in case there is a problem
- BUGFIX: Removed build dependency on Python
- BUGFIX: Fixed a bug in children update when changing files priorities
- BUGFIX: Pause/Start All now affect all tabs, not only the current one
- BUGFIX: Don't reload all torrents everytime settings are saved
- BUGFIX: Don't reload seeding torrents anymore (no point)
- I18N: Updated Turkish translation
rc8->rc9 changelog:
- FEATURE: Better media file preview (player detected automatically)
- BUGFIX: Remember properties window size and position
- BUGFIX: Added HTTP and SOCKS5 proxy support in downloads from urls, RSS
- BUGFIX: Added HTTP proxy support in search engine (no SOCKS yet)
- BUGFIX: Do no pause torrents before saving fastresume data anymore (no longer needed)
- BUGFIX: Save fast resume data regularly (every 60 seconds) to avoid downloading from scratch if qBittorrent crashes
- BUGFIX: Do not save fastresume data for checking torrents anymore
- BUGFIX: Saving trackers file only when necessary
- BUGFIX: Fixed possible segfault when unfiltering files in torrent addition dialog
- BUGFIX: Fixed possible overflow in ETA calculation
- BUGFIX: title bar is now reset when "Display speed in title" is disabled
- BUGFIX: Fixed HTTP_PW and SOCKS5_PW in proxy combobox
- BUGFIX: Fixed proxy auth disable problem when disabling proxy
- BUGFIX: Fixed proxy layout in program preferences
- BUGFIX: Fixed everlasting libtorrent session destruction on exit

78
configure vendored
View File

@@ -22,8 +22,8 @@ Dependency options:
--with-libtorrent-lib=[path] Path to libtorrent library files
--with-libtorrent-static-lib=[path] Path to libtorrent .a file
--with-libboost-inc=[path] Path to libboost include files
--with-libcommoncpp2-inc=[path] Path to libcommoncpp2 include files
--with-libcommoncpp2-lib=[path] Path to libcommoncpp2 library files
--with-libcurl-inc=[path] Path to libcurl include files
--with-libcurl-lib=[path] Path to libcurl library files
--disable-libmagick Disable use of libmagick
--with-libmagick-inc=[path] Path to libmagick++ include files
--with-libmagick-lib=[path] Path to libmagick++ library files
@@ -166,13 +166,13 @@ while [ $# -gt 0 ]; do
shift
;;
--with-libcommoncpp2-inc=*)
QC_WITH_LIBCOMMONCPP2_INC=$optarg
--with-libcurl-inc=*)
QC_WITH_LIBCURL_INC=$optarg
shift
;;
--with-libcommoncpp2-lib=*)
QC_WITH_LIBCOMMONCPP2_LIB=$optarg
--with-libcurl-lib=*)
QC_WITH_LIBCURL_LIB=$optarg
shift
;;
@@ -231,8 +231,8 @@ echo QC_WITH_LIBTORRENT_INC=$QC_WITH_LIBTORRENT_INC
echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB
echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
echo QC_WITH_LIBCOMMONCPP2_INC=$QC_WITH_LIBCOMMONCPP2_INC
echo QC_WITH_LIBCOMMONCPP2_LIB=$QC_WITH_LIBCOMMONCPP2_LIB
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
echo QC_DISABLE_libmagick=$QC_DISABLE_libmagick
echo QC_WITH_LIBMAGICK_INC=$QC_WITH_LIBMAGICK_INC
echo QC_WITH_LIBMAGICK_LIB=$QC_WITH_LIBMAGICK_LIB
@@ -425,16 +425,6 @@ public:
if(!found) return false;
conf->addLib(QString("-L") + s);
}
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-lssl -lcrypto -lboost_date_time -lboost_filesystem -lboost_thread -lz -ltorrent");
}
}
return true;
}
};
@@ -495,25 +485,25 @@ public:
return true;
}
};
#line 1 "libcommoncpp2.qcm"
#line 1 "libcurl.qcm"
/*
-----BEGIN QCMOD-----
name: libcommoncpp2
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files
arg: with-libcurl-inc=[path], Path to libcurl include files
arg: with-libcurl-lib=[path], Path to libcurl library files
-----END QCMOD-----
*/
class qc_libcommoncpp2 : public ConfObj
class qc_libcurl : public ConfObj
{
public:
qc_libcommoncpp2(Conf *c) : ConfObj(c) {}
QString name() const { return "GNU Common C++ library (libcommoncpp2)"; }
QString shortname() const { return "libcommoncpp2"; }
qc_libcurl(Conf *c) : ConfObj(c) {}
QString name() const { return "libcurl"; }
QString shortname() const { return "libcurl"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_INC");
s = conf->getenv("QC_WITH_LIBCURL_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "cc++/url.h")) {
if(!conf->checkHeader(s, "curl/curl.h")) {
return false;
}
}else{
@@ -522,7 +512,7 @@ public:
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "cc++/url.h")){
if(conf->checkHeader(s, "curl/curl.h")){
found = true;
break;
}
@@ -533,12 +523,10 @@ public:
}
conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
s = conf->getenv("QC_WITH_LIBCURL_LIB");
if(!s.isEmpty()) {
if(!QFile::exists(s+QString("/libccext2.so")))
return false;
if(!QFile::exists(s+QString("/libccgnu2.so")))
return false;
if(!QFile::exists(s+QString("/libcurl.so")))
return false;
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
@@ -548,26 +536,14 @@ public:
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(QFile::exists(s+QString("libccext2.so"))){
if(QFile::exists(s+QString("libccgnu2.so"))){
found = true;
break;
}
if(QFile::exists(s+QString("libcurl.so"))){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-pthread -lccext2 -lz -lccgnu2 -ldl -lrt");
}
}
return true;
}
};
@@ -735,7 +711,7 @@ cat >$1/modules_new.cpp <<EOT
o = new qc_libboost(conf);
o->required = true;
o->disabled = false;
o = new qc_libcommoncpp2(conf);
o = new qc_libcurl(conf);
o->required = true;
o->disabled = false;
o = new qc_libmagick(conf);
@@ -1693,8 +1669,8 @@ export QC_WITH_LIBTORRENT_INC
export QC_WITH_LIBTORRENT_LIB
export QC_WITH_LIBTORRENT_STATIC_LIB
export QC_WITH_LIBBOOST_INC
export QC_WITH_LIBCOMMONCPP2_INC
export QC_WITH_LIBCOMMONCPP2_LIB
export QC_WITH_LIBCURL_INC
export QC_WITH_LIBCURL_LIB
export QC_DISABLE_libmagick
export QC_WITH_LIBMAGICK_INC
export QC_WITH_LIBMAGICK_LIB

View File

@@ -12,7 +12,7 @@
<dep type='libboost'>
<required/>
</dep>
<dep type='libcommoncpp2'>
<dep type='libcurl'>
<required/>
</dep>
<dep type='libmagick'/>

View File

@@ -60,16 +60,6 @@ public:
if(!found) return false;
conf->addLib(QString("-L") + s);
}
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-pthread -lccext2 -lz -lccgnu2 -ldl -lrt");
}
}
return true;
}
};

61
qcm/libcurl.qcm Normal file
View File

@@ -0,0 +1,61 @@
/*
-----BEGIN QCMOD-----
name: libcommoncpp2
arg: with-libcurl-inc=[path], Path to libcurl include files
arg: with-libcurl-lib=[path], Path to libcurl library files
-----END QCMOD-----
*/
class qc_libcurl : public ConfObj
{
public:
qc_libcurl(Conf *c) : ConfObj(c) {}
QString name() const { return "libcurl"; }
QString shortname() const { return "libcurl"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBCURL_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "curl/curl.h")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "curl/curl.h")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBCURL_LIB");
if(!s.isEmpty()) {
if(!QFile::exists(s+QString("/libcurl.so")))
return false;
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(QFile::exists(s+QString("libcurl.so"))){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true;
}
};

View File

@@ -65,16 +65,6 @@ public:
if(!found) return false;
conf->addLib(QString("-L") + s);
}
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-lssl -lcrypto -lboost_date_time -lboost_filesystem -lboost_thread -lz -ltorrent");
}
}
return true;
}
};

View File

@@ -313,8 +313,6 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
QModelIndex index;
// Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
QSettings settings("qBittorrent", "qBittorrent");
QString previewProgram = settings.value("Preferences/general/MediaPlayer", QString()).toString();
bool has_pause = false, has_start = false, has_preview = false;
foreach(index, selectedIndexes) {
if(index.column() == F_NAME) {
@@ -334,7 +332,7 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
has_pause = true;
}
}
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
myFinishedListMenu.addAction(actionPreview_file);
has_preview = true;
}

View File

@@ -45,6 +45,7 @@
#include "options_imp.h"
#include "previewSelect.h"
#include "allocationDlg.h"
#include "stdlib.h"
using namespace libtorrent;
@@ -159,8 +160,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
checkConnect = new QTimer(this);
connect(checkConnect, SIGNAL(timeout()), this, SLOT(checkConnectionStatus()));
checkConnect->start(5000);
previewProcess = new QProcess(this);
connect(previewProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(cleanTempPreviewFile(int, QProcess::ExitStatus)));
// Accept drag 'n drops
setAcceptDrops(true);
show();
@@ -182,9 +181,6 @@ GUI::~GUI() {
delete myTrayIconMenu;
}
delete tcpServer;
previewProcess->kill();
previewProcess->waitForFinished();
delete previewProcess;
delete connecStatusLblIcon;
delete tabs;
// Keyboard shortcuts
@@ -388,12 +384,6 @@ void GUI::on_actionPreview_file_triggered() {
new previewSelect(this, h);
}
void GUI::cleanTempPreviewFile(int, QProcess::ExitStatus) const {
if(!QFile::remove(QDir::tempPath()+QDir::separator()+QString::fromUtf8("qBT_preview.tmp"))) {
std::cerr << "Couldn't remove temporary file: " << (QDir::tempPath()+QDir::separator()+QString::fromUtf8("qBT_preview.tmp")).toUtf8().data() << "\n";
}
}
// Necessary if we want to close the window
// in one time if "close to systray" is enabled
void GUI::on_actionExit_triggered() {
@@ -402,21 +392,7 @@ void GUI::on_actionExit_triggered() {
}
void GUI::previewFile(QString filePath) {
// Check if there is already one preview running
if(previewProcess->state() == QProcess::NotRunning) {
// First copy temporarily (XXX: is it necessary?)
QString tmpPath = QDir::tempPath()+QDir::separator()+QString::fromUtf8("qBT_preview.tmp");
QFile::remove(tmpPath);
QFile::copy(filePath, tmpPath);
// Launch program preview
QStringList params;
params << tmpPath;
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString previewProgram = settings.value(QString::fromUtf8("Preferences/General/MediaPlayer"), QString()).toString();
previewProcess->start(previewProgram, params, QIODevice::ReadOnly);
}else{
QMessageBox::critical(0, tr("Preview process already running"), tr("There is already another preview process running.\nPlease close the other one first."));
}
QDesktopServices::openUrl(filePath);
}
unsigned int GUI::getCurrentTabIndex() const{
@@ -788,7 +764,12 @@ void GUI::processDownloadedFiles(QString path, QString url) {
void GUI::configureSession(bool deleteOptions) {
qDebug("Configuring session");
// General
displaySpeedInTitle = options->speedInTitleBar();
bool new_displaySpeedInTitle = options->speedInTitleBar();
if(!new_displaySpeedInTitle && new_displaySpeedInTitle != displaySpeedInTitle) {
// Reset title
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
}
displaySpeedInTitle = new_displaySpeedInTitle;
unsigned int new_refreshInterval = options->getRefreshInterval();
if(refreshInterval != new_refreshInterval) {
refreshInterval = new_refreshInterval;
@@ -849,12 +830,21 @@ void GUI::configureSession(bool deleteOptions) {
// * Proxy settings
proxy_settings proxySettings;
if(options->isProxyEnabled()) {
proxySettings.hostname = options->getProxyIp().toStdString();
proxySettings.port = options->getProxyPort();
if(options->isProxyAuthEnabled()) {
proxySettings.username = options->getProxyUsername().toStdString();
proxySettings.password = options->getProxyPassword().toStdString();
}
QString proxy_str;
switch(options->getProxyType()) {
case HTTP:
proxySettings.type = proxy_settings::http;
proxy_str = misc::toQString("http://")+options->getProxyIp()+":"+misc::toQString(proxySettings.port);
break;
case HTTP_PW:
proxySettings.type = proxy_settings::http_pw;
proxy_str = misc::toQString("http://")+options->getProxyUsername()+":"+options->getProxyPassword()+"@"+options->getProxyIp()+":"+misc::toQString(proxySettings.port);
break;
case SOCKS5:
proxySettings.type = proxy_settings::socks5;
@@ -863,12 +853,12 @@ void GUI::configureSession(bool deleteOptions) {
proxySettings.type = proxy_settings::socks5_pw;
break;
}
proxySettings.hostname = options->getProxyIp().toStdString();
proxySettings.port = options->getProxyPort();
if(options->isProxyAuthEnabled()) {
proxySettings.username = options->getProxyUsername().toStdString();
proxySettings.password = options->getProxyPassword().toStdString();
if(!proxy_str.isEmpty()) {
// We need this for urllib in search engine plugins
setenv("http_proxy", proxy_str.toUtf8().data(), 1);
}
} else {
unsetenv("http_proxy");
}
BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT());
// * Session settings

View File

@@ -74,8 +74,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
QShortcut *switchDownShortcut;
QShortcut *switchUpShortcut;
QShortcut *switchRSSShortcut;
// Preview
QProcess *previewProcess;
// Search
SearchEngine *searchEngine;
// RSS
@@ -98,7 +96,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void togglePausedState(QString hash);
void on_actionPreview_file_triggered();
void previewFile(QString filePath);
void cleanTempPreviewFile(int, QProcess::ExitStatus) const;
void balloonClicked();
void writeSettings();
void readSettings();

View File

@@ -181,6 +181,8 @@ class PropListDelegate: public QItemDelegate {
// } else {
model->setData(index, QVariant(HIGH));
model->setData(index, QVariant(NORMAL));
if(filteredFilesChanged != 0)
*filteredFilesChanged = true;
// }
break;
case 2:

View File

@@ -43,7 +43,7 @@
#define MAX_TRACKER_ERRORS 2
// Main constructor
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1) {
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false) {
// To avoid some exceptions
fs::path::default_name_check(fs::no_check);
// Creating bittorrent session
@@ -58,6 +58,9 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false
ETARefresher = new QTimer();
connect(ETARefresher, SIGNAL(timeout()), this, SLOT(updateETAs()));
ETARefresher->start(ETA_REFRESH_INTERVAL);
fastResumeSaver = new QTimer();
connect(fastResumeSaver, SIGNAL(timeout()), this, SLOT(saveFastResumeAndRatioData()));
fastResumeSaver->start(60000);
// To download from urls
downloader = new downloadThread(this);
connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString)));
@@ -73,6 +76,7 @@ bittorrent::~bittorrent() {
disableDirectoryScanning();
// Delete our objects
delete deleter;
delete fastResumeSaver;
delete timerAlerts;
delete ETARefresher;
delete downloader;
@@ -93,7 +97,7 @@ void bittorrent::preAllocateAllFiles(bool b) {
qDebug("/!\\ Error: Invalid handle");
continue;
}
pauseAndReloadTorrent(h, b);
reloadTorrent(h, b);
}
}
}
@@ -162,8 +166,16 @@ void bittorrent::updateETAs() {
foreach(val, listEtas) {
moy += (qlonglong)((double)val/(double)nbETAs);
}
Q_ASSERT(moy >= 0);
ETAs[hash] = moy;
if(moy < 0) {
if(ETAstats.contains(hash)) {
ETAstats.remove(hash);
}
if(ETAs.contains(hash)) {
ETAs.remove(hash);
}
} else {
ETAs[hash] = moy;
}
} else {
// Speed is too low, we don't want an overflow.
if(ETAstats.contains(hash)) {
@@ -233,10 +245,6 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
ETAs.remove(hash);
// Remove tracker errors
trackersErrors.remove(hash);
// Remove from reloadingTorrents if reloading
if(reloadingTorrents.contains(hash)) {
reloadingTorrents.remove(hash);
}
// Remove it from ratio table
ratioData.remove(hash);
int index = finishedTorrents.indexOf(hash);
@@ -302,6 +310,8 @@ void bittorrent::setFinishedTorrent(QString hash) {
// Remove it from ETAs hash tables
ETAstats.remove(hash);
ETAs.remove(hash);
// Save fast resume data
saveFastResumeAndRatioData(hash);
}
// Pause a running torrent
@@ -311,6 +321,8 @@ bool bittorrent::pauseTorrent(QString hash) {
if(h.is_valid() && !h.is_paused()) {
h.pause();
change = true;
// Save fast resume data
saveFastResumeAndRatioData(hash);
qDebug("Torrent paused successfully");
}else{
if(!h.is_valid()) {
@@ -619,25 +631,49 @@ bool bittorrent::isDHTEnabled() const{
void bittorrent::enableUPnP(bool b) {
if(b) {
s->start_upnp();
if(!UPnPEnabled) {
qDebug("Enabling UPnP");
s->start_upnp();
UPnPEnabled = true;
}
} else {
s->stop_upnp();
if(UPnPEnabled) {
qDebug("Disabling UPnP");
s->stop_upnp();
UPnPEnabled = false;
}
}
}
void bittorrent::enableNATPMP(bool b) {
if(b) {
s->start_natpmp();
if(!NATPMPEnabled) {
qDebug("Enabling NAT-PMP");
s->start_natpmp();
NATPMPEnabled = true;
}
} else {
s->stop_natpmp();
if(NATPMPEnabled) {
qDebug("Disabling NAT-PMP");
s->stop_natpmp();
NATPMPEnabled = false;
}
}
}
void bittorrent::enableLSD(bool b) {
if(b) {
s->start_lsd();
if(!LSDEnabled) {
qDebug("Enabling LSD");
s->start_lsd();
LSDEnabled = true;
}
} else {
s->stop_lsd();
if(LSDEnabled) {
qDebug("Disabling LSD");
s->stop_lsd();
LSDEnabled = false;
}
}
}
@@ -708,6 +744,7 @@ void bittorrent::loadTorrentSpeedLimits(QString hash) {
// Read pieces priorities from .priorities file
// and ask QTorrentHandle to consider them
void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
qDebug("Applying pieces priorities");
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
return;
@@ -822,10 +859,26 @@ void bittorrent::saveDownloadUploadForTorrent(QString hash) {
ratio_file.close();
}
// Save fastresume data for all torrents
// and remove them from the session
// Only save fast resume data for unfinished and unpaused torrents (Optimization)
// Called periodically and on exit
void bittorrent::saveFastResumeAndRatioData() {
qDebug("Saving fast resume and ratio data");
QString hash;
QStringList hashes = getUnfinishedTorrents();
foreach(hash, hashes) {
QTorrentHandle h = getTorrentHandle(hash);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
}
if(h.is_paused()) {
// Do not need to save fast resume data for paused torrents
continue;
}
saveFastResumeAndRatioData(hash);
}
}
void bittorrent::saveFastResumeAndRatioData(QString hash) {
QString file;
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
// Checking if torrentBackup Dir exists
@@ -833,54 +886,26 @@ void bittorrent::saveFastResumeAndRatioData() {
if(! torrentBackup.exists()) {
torrentBackup.mkpath(torrentBackup.path());
}
// Pause torrents
std::vector<torrent_handle> handles = s->get_torrents();
for(unsigned int i=0; i<handles.size(); ++i) {
QTorrentHandle h = handles[i];
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
}
// Pause download (needed before fast resume writing)
if(!h.is_paused()){
waitingForPause << h.hash();
h.pause();
}
// Extracting resume data
QTorrentHandle h = getTorrentHandle(hash);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
return;
}
// Write fast resume data
for(unsigned int i=0; i<handles.size(); ++i) {
QTorrentHandle h = handles[i];
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
if (h.has_metadata() && h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking) {
if(QFile::exists(torrentBackup.path()+QDir::separator()+hash+".torrent")) {
// Remove old .fastresume data in case it exists
QFile::remove(torrentBackup.path()+QDir::separator()+hash + ".fastresume");
// Write fast resume data
entry resumeData = h.write_resume_data();
file = hash + ".fastresume";
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toUtf8().data()) / file.toUtf8().data(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), resumeData);
}
QString hash = h.hash();
while(waitingForPause.contains(hash)) {
//qDebug("Sleeping while waiting that %s is paused", misc::toString(h.info_hash()).c_str());
SleeperThread::msleep(300);
readAlerts();
}
// Extracting resume data
if (h.has_metadata()) {
if(QFile::exists(torrentBackup.path()+QDir::separator()+hash+".torrent")) {
// Remove old .fastresume data in case it exists
QFile::remove(torrentBackup.path()+QDir::separator()+hash + ".fastresume");
// Write fast resume data
entry resumeData = h.write_resume_data();
file = hash + ".fastresume";
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toUtf8().data()) / file.toUtf8().data(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), resumeData);
}
// Save ratio data
saveDownloadUploadForTorrent(hash);
// Save trackers
saveTrackerFile(hash);
}
// Remove torrent
s->remove_torrent(h.get_torrent_handle());
// Save ratio data
saveDownloadUploadForTorrent(hash);
}
qDebug("Fast resume and ratio data saved");
}
bool bittorrent::isFilePreviewPossible(QString hash) const{
@@ -1023,6 +1048,7 @@ bool bittorrent::loadTrackerFile(QString hash) {
}
void bittorrent::saveTrackerFile(QString hash) {
qDebug("Saving tracker file for %s", hash.toUtf8().data());
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
if(tracker_file.exists()) {
@@ -1125,21 +1151,6 @@ void bittorrent::readAlerts() {
}
}
}
else if (torrent_paused_alert* p = dynamic_cast<torrent_paused_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if(h.is_valid()){
QString hash = h.hash();
qDebug("Received torrent_paused_alert for %s", hash.toUtf8().data());
int index = waitingForPause.indexOf(hash);
if(index != -1){
waitingForPause.removeAt(index);
}
if(reloadingTorrents.contains(hash)) {
reloadTorrent(h, reloadingTorrents.value(hash));
reloadingTorrents.remove(hash);
}
}
}
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
}
@@ -1180,22 +1191,6 @@ QStringList bittorrent::getTorrentsToPauseAfterChecking() const{
return torrentsToPauseAfterChecking;
}
// Function to reload the torrent async after the torrent is actually
// paused so that we can get fastresume data
void bittorrent::pauseAndReloadTorrent(QTorrentHandle h, bool full_alloc) {
if(!h.is_valid()) {
std::cerr << "/!\\ Error: Invalid handle\n";
return;
}
// ask to pause the torrent (async)
h.pause();
QString hash = h.hash();
// Add it to reloadingTorrents has table so that we now we
// we should reload the torrent once we receive the
// torrent_paused_alert. pause() is async now...
reloadingTorrents[hash] = full_alloc;
}
// Reload a torrent with full allocation mode
void bittorrent::reloadTorrent(const QTorrentHandle &h, bool full_alloc) {
qDebug("** Reloading a torrent");

View File

@@ -44,18 +44,17 @@ class bittorrent : public QObject{
QString scan_dir;
QTimer *timerScan;
QTimer *timerAlerts;
QTimer *fastResumeSaver;
bool DHTEnabled;
downloadThread *downloader;
QString defaultSavePath;
QStringList torrentsToPauseAfterChecking;
QHash<QString, bool> reloadingTorrents;
QHash<QString, QList<qlonglong> > ETAstats;
QHash<QString, qlonglong> ETAs;
QHash<QString, QPair<size_type,size_type> > ratioData;
QTimer *ETARefresher;
QHash<QString, QList<QPair<QString, QString> > > trackersErrors;
deleteThread *deleter;
QStringList waitingForPause;
QStringList finishedTorrents;
QStringList unfinishedTorrents;
bool preAllocateAll;
@@ -63,6 +62,9 @@ class bittorrent : public QObject{
int maxConnecsPerTorrent;
int maxUploadsPerTorrent;
float max_ratio;
bool UPnPEnabled;
bool NATPMPEnabled;
bool LSDEnabled;
protected:
QString getSavePath(QString hash);
@@ -99,6 +101,7 @@ class bittorrent : public QObject{
void saveDHTEntry();
void preAllocateAllFiles(bool b);
void saveFastResumeAndRatioData();
void saveFastResumeAndRatioData(QString hash);
void enableDirectoryScanning(QString scan_dir);
void disableDirectoryScanning();
void enablePeerExchange();
@@ -136,6 +139,7 @@ class bittorrent : public QObject{
void enableNATPMP(bool b);
void enableLSD(bool b);
bool enableDHT(bool b);
void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
protected slots:
void scanDirectory();
@@ -143,8 +147,6 @@ class bittorrent : public QObject{
void processDownloadedFile(QString, QString);
bool loadTrackerFile(QString hash);
void saveTrackerFile(QString hash);
void pauseAndReloadTorrent(QTorrentHandle h, bool full_alloc);
void reloadTorrent(const QTorrentHandle &h, bool full_alloc); // This is protected now, call pauseAndReloadTorrent() instead
void deleteBigRatios();
signals:

View File

@@ -21,43 +21,48 @@
#include "downloadThread.h"
#include <iostream>
#include <cc++/common.h>
#include <QSettings>
#include <stdio.h>
QString subDownloadThread::errorCodeToString(int status) {
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
QString subDownloadThread::errorCodeToString(CURLcode status) {
switch(status){
case 1://ost::URLStream::errUnreachable:
case CURLE_FTP_CANT_GET_HOST:
case CURLE_COULDNT_RESOLVE_HOST:
return tr("Host is unreachable");
case 2://ost::URLStream::errMissing:
case CURLE_READ_ERROR:
case CURLE_FILE_COULDNT_READ_FILE:
return tr("File was not found (404)");
case 3://ost::URLStream::errDenied:
case CURLE_FTP_ACCESS_DENIED:
case CURLE_LOGIN_DENIED:
case CURLE_FTP_USER_PASSWORD_INCORRECT:
return tr("Connection was denied");
case 4://ost::URLStream::errInvalid:
case CURLE_URL_MALFORMAT:
return tr("Url is invalid");
case 5://ost::URLStream::errForbidden:
return tr("Connection forbidden (403)");
case 6://ost::URLStream::errUnauthorized:
return tr("Connection was not authorized (401)");
case 7://ost::URLStream::errRelocated:
return tr("Content has moved (301)");
case 8://ost::URLStream::errFailure:
case CURLE_COULDNT_RESOLVE_PROXY:
return tr("Could not resolve proxy");
//case 5:
// return tr("Connection forbidden (403)");
//case 6:
// return tr("Connection was not authorized (401)");
//case 7:
// return tr("Content has moved (301)");
case CURLE_COULDNT_CONNECT:
return tr("Connection failure");
case 9://ost::URLStream::errTimeout:
case CURLE_OPERATION_TIMEOUTED:
return tr("Connection was timed out");
case 10://ost::URLStream::errInterface:
case CURLE_INTERFACE_FAILED:
return tr("Incorrect network interface");
default:
return tr("Unknown error");
}
}
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){
url_stream = new ost::URLStream();
}
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){}
subDownloadThread::~subDownloadThread(){
abort = true;
wait();
delete url_stream;
}
void subDownloadThread::run(){
@@ -68,38 +73,57 @@ void subDownloadThread::run(){
filePath = tmpfile->fileName();
}
delete tmpfile;
QFile dest_file(filePath);
if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){
std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n';
FILE *f = fopen(filePath.toUtf8().data(), "w");
if(!f) {
std::cerr << "couldn't open destination file" << "\n";
return;
}
ost::URLStream::Error status = url_stream->get((const char*)url.toUtf8());
if(status){
// Failure
QString error_msg = errorCodeToString((int)status);
qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8());
url_stream->close();
emit downloadFailureST(this, url, error_msg);
return;
}
qDebug("Downloading %s...", (const char*)url.toUtf8());
char cbuf[1024];
int len;
while(!url_stream->eof()) {
url_stream->read(cbuf, sizeof(cbuf));
len = url_stream->gcount();
if(len > 0)
dest_file.write(cbuf, len);
if(abort){
dest_file.close();
url_stream->close();
return;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
std::string c_url = url.toUtf8().data();
curl_easy_setopt(curl, CURLOPT_URL, c_url.c_str());
// SSL support
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
// PROXY SUPPORT
QSettings settings("qBittorrent", "qBittorrent");
int intValue = settings.value(QString::fromUtf8("Preferences/Connection/ProxyType"), 0).toInt();
if(intValue > 0) {
// Proxy enabled
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/IP"), "0.0.0.0").toString();
QString port = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Port"), 8080).toString();
qDebug("Using proxy: %s", (IP+QString(":")+port).toUtf8().data());
curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toUtf8().data());
// Default proxy type is HTTP, we must change if it is SOCKS5
if(intValue%2==0) {
qDebug("Proxy is SOCKS5, not HTTP");
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
}
// Authentication?
if(intValue > 2) {
qDebug("Proxy requires authentication, authenticating");
QString username = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Username"), QString()).toString();
QString password = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Password"), QString()).toString();
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toUtf8().data());
}
}
// TODO: define CURLOPT_WRITEFUNCTION or it will crash on windows
curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
qDebug("Downloading %s", url.toUtf8().data());
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
fclose(f);
if(res) {
emit downloadFailureST(this, url, errorCodeToString(res));
} else {
emit downloadFinishedST(this, url, filePath);
}
} else {
std::cerr << "Could not initialize CURL" << "\n";
}
dest_file.close();
url_stream->close();
emit downloadFinishedST(this, url, filePath);
qDebug("download completed here: %s", (const char*)filePath.toUtf8());
}
/** Download Thread **/

View File

@@ -29,22 +29,18 @@
#include <QMutexLocker>
#include <QWaitCondition>
#include <QStringList>
namespace ost {
class URLStream;
}
#include <curl/curl.h>
class subDownloadThread : public QThread {
Q_OBJECT
private:
QString url;
ost::URLStream *url_stream;
bool abort;
public:
subDownloadThread(QObject *parent, QString url);
~subDownloadThread();
QString errorCodeToString(int status);
QString errorCodeToString(CURLcode status);
signals:
// For subthreads
@@ -76,13 +72,13 @@ class downloadThread : public QThread {
~downloadThread();
void downloadUrl(QString url);
void setProxy(QString IP, int port, QString username, QString password);
protected:
void run();
protected slots:
void propagateDownloadedFile(subDownloadThread* st, QString url, QString path);
void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason);
};

View File

@@ -190,7 +190,6 @@ void DownloadingTorrents::setInfoBar(QString info, QColor color) {
infoBar->clear();
nbLines = 1;
}
qDebug("Color is %s", color.name().toUtf8().data());
infoBar->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + info + QString::fromUtf8("</i></font>"));
}
@@ -246,8 +245,6 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
QModelIndex index;
// Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString previewProgram = settings.value(QString::fromUtf8("Preferences/general/MediaPlayer"), QString()).toString();
bool has_pause = false, has_start = false, has_preview = false;
foreach(index, selectedIndexes) {
if(index.column() == NAME) {
@@ -267,7 +264,7 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
has_pause = true;
}
}
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
myDLLlistMenu.addAction(actionPreview_file);
has_preview = true;
}

View File

@@ -306,51 +306,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="previewBox" >
<property name="title" >
<string>Preview program</string>
</property>
<layout class="QVBoxLayout" >
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="lbl_preview" >
<property name="text" >
<string>Media player:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="textMediaPlayer" />
</item>
<item>
<widget class="QToolButton" name="browsePreviewButton" >
<property name="text" >
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
@@ -992,70 +947,72 @@
<property name="title" >
<string>Affected connections</string>
</property>
<widget class="QCheckBox" name="checkProxyTrackers" >
<property name="geometry" >
<rect>
<x>10</x>
<y>20</y>
<width>341</width>
<height>22</height>
</rect>
</property>
<property name="text" >
<string>Use proxy for connections to trackers</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
<widget class="QCheckBox" name="checkProxyPeers" >
<property name="geometry" >
<rect>
<x>10</x>
<y>40</y>
<width>341</width>
<height>22</height>
</rect>
</property>
<property name="text" >
<string>Use proxy for connections to regular peers</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
<widget class="QCheckBox" name="checkProxyWebseeds" >
<property name="geometry" >
<rect>
<x>10</x>
<y>60</y>
<width>341</width>
<height>22</height>
</rect>
</property>
<property name="text" >
<string>Use proxy for connections to web seeds</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
<widget class="QCheckBox" name="checkProxyDHT" >
<property name="geometry" >
<rect>
<x>10</x>
<y>80</y>
<width>341</width>
<height>22</height>
</rect>
</property>
<property name="text" >
<string>Use proxy for DHT messages</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
<layout class="QVBoxLayout" >
<item>
<widget class="QCheckBox" name="checkProxyTrackers" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Use proxy for connections to trackers</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkProxyPeers" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Use proxy for connections to regular peers</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkProxyDHT" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Use proxy for DHT messages</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkProxyWebseeds" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Use proxy for connections to web seeds</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>

View File

@@ -152,7 +152,6 @@ options_imp::options_imp(QWidget *parent):QDialog(parent){
connect(checkCloseToSystray, SIGNAL(stateChanged(int)), this, SLOT(enableApplyButton()));
connect(checkMinimizeToSysTray, SIGNAL(stateChanged(int)), this, SLOT(enableApplyButton()));
connect(checkSystrayBalloons, SIGNAL(stateChanged(int)), this, SLOT(enableApplyButton()));
connect(textMediaPlayer, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
// Downloads tab
connect(textSavePath, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
connect(checkPreallocateAll, SIGNAL(stateChanged(int)), this, SLOT(enableApplyButton()));
@@ -262,7 +261,6 @@ void options_imp::saveOptions(){
settings.setValue(QString::fromUtf8("CloseToTray"), closeToTray());
settings.setValue(QString::fromUtf8("MinimizeToTray"), minimizeToTray());
settings.setValue(QString::fromUtf8("NotificationBaloons"), OSDEnabled());
settings.setValue(QString::fromUtf8("MediaPlayer"), getPreviewProgram());
// End General preferences
settings.endGroup();
// Downloads preferences
@@ -406,7 +404,6 @@ void options_imp::loadOptions(){
checkMinimizeToSysTray->setChecked(settings.value(QString::fromUtf8("MinimizeToTray"), false).toBool());
checkSystrayBalloons->setChecked(settings.value(QString::fromUtf8("NotificationBaloons"), true).toBool());
}
textMediaPlayer->setText(settings.value(QString::fromUtf8("MediaPlayer"), QString()).toString());
// End General preferences
settings.endGroup();
// Downloads preferences
@@ -463,7 +460,15 @@ void options_imp::loadOptions(){
spinUploadLimit->setEnabled(false);
}
intValue = settings.value(QString::fromUtf8("ProxyType"), 0).toInt();
if(intValue < 0) intValue = 0;
if(intValue <= 0) {
intValue = 0;
} else {
if(intValue%2 == 0) {
intValue = 2;
}else {
intValue = 1;
}
}
comboProxyType->setCurrentIndex(intValue);
enableProxy(intValue);
if(isProxyEnabled()) {
@@ -583,12 +588,6 @@ int options_imp::getEncryptionSetting() const{
return comboEncryption->currentIndex();
}
QString options_imp::getPreviewProgram() const{
QString preview_txt = textMediaPlayer->text();
preview_txt = preview_txt.trimmed();
return preview_txt;
}
bool options_imp::minimizeToTray() const{
if(checkNoSystray->isChecked()) return false;
return checkMinimizeToSysTray->isChecked();
@@ -872,6 +871,7 @@ void options_imp::enableProxy(int index){
textProxyIP->setEnabled(false);
lblProxyPort->setEnabled(false);
spinProxyPort->setEnabled(false);
checkProxyAuth->setChecked(false);
checkProxyAuth->setEnabled(false);
ProxyConnecsBox->setEnabled(false);
}
@@ -996,13 +996,6 @@ void options_imp::on_browseFilterButton_clicked() {
}
}
void options_imp::on_browsePreviewButton_clicked() {
QString program_txt = QFileDialog::getOpenFileName(this, tr("Choose your favourite preview program"), QDir::homePath());
if(!program_txt.isNull()){
textMediaPlayer->setText(program_txt);
}
}
// Display dialog to choose save dir
void options_imp::on_browseSaveDirButton_clicked(){
QString dir = QFileDialog::getExistingDirectory(this, tr("Choose a save directory"), QDir::homePath());

View File

@@ -61,7 +61,6 @@ class options_imp : public QDialog, private Ui::Dialog{
bool minimizeToTray() const;
bool closeToTray() const;
bool OSDEnabled() const;
QString getPreviewProgram() const;
// Downloads
QString getSavePath() const;
bool preAllocateAllFiles() const;
@@ -119,7 +118,6 @@ class options_imp : public QDialog, private Ui::Dialog{
void on_addFilterRangeButton_clicked();
void on_delFilterRangeButton_clicked();
void on_browseScanDirButton_clicked();
void on_browsePreviewButton_clicked();
void on_browseFilterButton_clicked();
void on_browseSaveDirButton_clicked();
void processFilterFile(QString filePath=QString());

View File

@@ -5,7 +5,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>538</width>
<width>594</width>
<height>567</height>
</rect>
</property>

View File

@@ -30,6 +30,8 @@
#include <QMenu>
#include <QTimer>
#include <QStandardItemModel>
#include <QSettings>
#include <QDesktopWidget>
// Constructor
properties::properties(QWidget *parent, bittorrent *BTSession, QTorrentHandle &h): QDialog(parent), h(h), BTSession(BTSession), changedFilteredfiles(false), hash(h.hash()) {
@@ -118,6 +120,7 @@ properties::properties(QWidget *parent, bittorrent *BTSession, QTorrentHandle &h
updateInfosTimer = new QTimer(this);
connect(updateInfosTimer, SIGNAL(timeout()), this, SLOT(updateInfos()));
updateInfosTimer->start(3000);
loadSettings();
}
properties::~properties(){
@@ -155,6 +158,36 @@ void properties::addFilesToTree(file *root, QStandardItem *parent) {
}
}
void properties::writeSettings() {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.beginGroup(QString::fromUtf8("PropWindow"));
settings.setValue(QString::fromUtf8("size"), size());
settings.setValue(QString::fromUtf8("pos"), pos());
settings.endGroup();
}
void properties::loadSettings() {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
resize(settings.value(QString::fromUtf8("PropWindow/size"), size()).toSize());
move(settings.value(QString::fromUtf8("PropWindow/pos"), screenCenter()).toPoint());
}
// Center window
QPoint properties::screenCenter() const{
int scrn = 0;
QWidget *w = this->topLevelWidget();
if(w)
scrn = QApplication::desktop()->screenNumber(w);
else if(QApplication::desktop()->isVirtualDesktop())
scrn = QApplication::desktop()->screenNumber(QCursor::pos());
else
scrn = QApplication::desktop()->screenNumber(this);
QRect desk(QApplication::desktop()->availableGeometry(scrn));
return QPoint((desk.width() - this->frameGeometry().width()) / 2, (desk.height() - this->frameGeometry().height()) / 2);
}
// priority is the new priority of given item
void properties::updateParentsPriority(QStandardItem *item, int priority) {
QStandardItem *parent = item->parent();
@@ -304,6 +337,7 @@ bool properties::allFiltered() const {
void properties::getPriorities(QStandardItem *parent, int *priorities) {
qDebug("In getPriorities");
unsigned int nbRows = parent->rowCount();
for(unsigned int i=0; i<nbRows; ++i){
QStandardItem *item = parent->child(i, INDEX);
@@ -313,6 +347,7 @@ void properties::getPriorities(QStandardItem *parent, int *priorities) {
} else {
item = parent->child(i, PRIORITY);
priorities[index] = item->text().toInt();
qDebug("File at index %d has priority %d", index, priorities[index]);
}
}
}
@@ -454,6 +489,7 @@ void properties::askForTracker(){
h.force_reannounce();
// Reload Trackers
loadTrackers();
emit trackersChanged(h.hash());
}
void properties::deleteSelectedUrlSeeds(){
@@ -502,6 +538,7 @@ void properties::deleteSelectedTrackers(){
h.force_reannounce();
// Reload Trackers
loadTrackers();
emit trackersChanged(h.hash());
}
void properties::riseSelectedTracker(){
@@ -535,6 +572,7 @@ void properties::riseSelectedTracker(){
// Reload Trackers
loadTrackers();
trackersURLS->item(i-1)->setSelected(true);
emit trackersChanged(h.hash());
}
}
@@ -569,6 +607,7 @@ void properties::lowerSelectedTracker(){
// Reload Trackers
loadTrackers();
trackersURLS->item(i+1)->setSelected(true);
emit trackersChanged(h.hash());
}
}

View File

@@ -74,10 +74,13 @@ class properties : public QDialog, private Ui::properties{
void updateParentsPriority(QStandardItem *item, int priority);
void updatePriorities(QStandardItem *item);
void getPriorities(QStandardItem *parent, int *priorities);
void writeSettings();
void loadSettings();
signals:
void filteredFilesChanged(QString hash);
void fileSizeChanged(QString hash);
void trackersChanged(QString hash);
public:
// Constructor
@@ -86,6 +89,9 @@ class properties : public QDialog, private Ui::properties{
bool allFiltered() const;
bool savePiecesPriorities();
int* loadPiecesPriorities();
protected:
QPoint screenCenter() const;
};
#endif

View File

@@ -452,12 +452,19 @@ void SearchEngine::on_stop_search_button_clicked(){
// Clear search results list
void SearchEngine::on_clear_button_clicked(){
// Kill process
searchProcess->terminate();
search_stopped = true;
searchResultsUrls.clear();
SearchListModel->removeRows(0, SearchListModel->rowCount());
// Disable clear & download buttons
clear_button->setEnabled(false);
download_button->setEnabled(false);
results_lbl->setText(tr("Results")+" <i>(0)</i>:");
// focus on search pattern
search_pattern->clear();
search_pattern->setFocus();
}
void SearchEngine::on_clearPatternButton_clicked() {

View File

@@ -11,7 +11,7 @@ TARGET = qbittorrent
CONFIG += qt thread x11 network
# Update this VERSION for each release
DEFINES += VERSION=\\\"v1.0.0rc7\\\"
DEFINES += VERSION=\\\"v1.0.0rc9\\\"
DEFINES += VERSION_MAJOR=1
DEFINES += VERSION_MINOR=0
DEFINES += VERSION_BUGFIX=0
@@ -81,7 +81,7 @@ QMAKE_CXXFLAGS_RELEASE += -fwrapv -O2
QMAKE_CXXFLAGS_DEBUG += -fwrapv -O1
CONFIG += link_pkgconfig
PKGCONFIG += libtorrent libccext2 libccgnu2
PKGCONFIG += "libtorrent libcurl"
!contains(DEFINES, HAVE_MAGICK){
message(ImageMagick disabled)