You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-12 03:12:18 +02:00
Compare commits
1 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6ecb5fe1e1 |
@@ -41,25 +41,22 @@
|
||||
- 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)
|
||||
- FEATURE: Greatly improved ETA calculation algorithm (use GASA)
|
||||
- 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
|
||||
- BUGFIX: Fixed a crash when filtering all the files in a torrent
|
||||
- BUGFIX: Reload torrent only when necessary (properties)
|
||||
- BUGFIX: qBittorrent is not exiting anymore when a dialog is closed and main window is hidden
|
||||
- BUGFIX: Catch all possible exceptions when adding a torrent to avoid crashing
|
||||
- BUGFIX: Search plugin update is not making the GUI freeze anymore (moved to a thread)
|
||||
- BUGFIX: DHT settings were not saved correctly
|
||||
- BUGFIX: Workaround to build on Fedora system (pkg-config problem)
|
||||
- BUGFIX: search plugin update - do not display only last version changelog
|
||||
- BUGFIX: Search plugin update - fixed missing new lines in changelog
|
||||
- BUGFIX: The number of search results was not reset when clicking on 'Clear' button
|
||||
- BUGFIX: Fixed systray integration when qbittorrent is launched on system startup
|
||||
- BUGFIX: Update torrent progress when its content changed (filtered files)
|
||||
- BUGFIX: Improved the way menu icons are installed to avoid problems on some systems
|
||||
- BUGFIX: Improved incremental download
|
||||
@@ -70,8 +67,6 @@
|
||||
- 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
|
||||
|
2
INSTALL
2
INSTALL
@@ -25,7 +25,7 @@ Dependencies:
|
||||
|
||||
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
|
||||
|
||||
- libcurl
|
||||
- libcommoncpp2
|
||||
|
||||
- python >= 2.3 (needed by search engine)
|
||||
|
||||
|
20
TODO
20
TODO
@@ -8,9 +8,11 @@
|
||||
- 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
|
||||
@@ -30,6 +32,7 @@
|
||||
|
||||
// in v1.1.0
|
||||
- Tabs support in search
|
||||
- Allow to hide columns?
|
||||
- Allow to scan multiple directories? (useful?)
|
||||
- Web interface (turbogears? php? python?)
|
||||
* Webserver? Try to write a webserver as a plugin for qBittorrent in Python
|
||||
@@ -43,7 +46,18 @@
|
||||
- Display in torrent addition dialog:
|
||||
* free disk space on selected drive
|
||||
* free disk space after torrent download (and/or torrent size)
|
||||
- Start minimized option in program preferences
|
||||
- In finished list, replace "Seeds/Leechs" column by "Leechers" because Seeds are always 0.
|
||||
- Allow to change action on double-click
|
||||
-> in download list
|
||||
-> in seeding list
|
||||
|
||||
rc11 -> final? changelog:
|
||||
BUGFIX: Fixed systray integration when qbittorrent is launched on system startup
|
||||
BUGFIX: Catch all possible exceptions when adding a torrent to avoid crashing
|
||||
// in v1.0.0 - FEATURE FREEZE
|
||||
- Fix all (or almost all) opened bugs in bug tracker
|
||||
- Recheck doc
|
||||
- Translations update (IN PROGRESS)
|
||||
|
||||
rc7->rc8 changelog:
|
||||
- BUGFIX: Fixed torrent files filtering
|
||||
- BUGFIX: Stop search when clearing results
|
||||
- BUGFIX: Fixed compilation on Fedora 8
|
||||
|
68
configure
vendored
68
configure
vendored
@@ -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-libcurl-inc=[path] Path to libcurl include files
|
||||
--with-libcurl-lib=[path] Path to libcurl library files
|
||||
--with-libcommoncpp2-inc=[path] Path to libcommoncpp2 include files
|
||||
--with-libcommoncpp2-lib=[path] Path to libcommoncpp2 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-libcurl-inc=*)
|
||||
QC_WITH_LIBCURL_INC=$optarg
|
||||
--with-libcommoncpp2-inc=*)
|
||||
QC_WITH_LIBCOMMONCPP2_INC=$optarg
|
||||
shift
|
||||
;;
|
||||
|
||||
--with-libcurl-lib=*)
|
||||
QC_WITH_LIBCURL_LIB=$optarg
|
||||
--with-libcommoncpp2-lib=*)
|
||||
QC_WITH_LIBCOMMONCPP2_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_LIBCURL_INC=$QC_WITH_LIBCURL_INC
|
||||
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
|
||||
echo QC_WITH_LIBCOMMONCPP2_INC=$QC_WITH_LIBCOMMONCPP2_INC
|
||||
echo QC_WITH_LIBCOMMONCPP2_LIB=$QC_WITH_LIBCOMMONCPP2_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
|
||||
@@ -485,25 +485,25 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#line 1 "libcurl.qcm"
|
||||
#line 1 "libcommoncpp2.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libcommoncpp2
|
||||
arg: with-libcurl-inc=[path], Path to libcurl include files
|
||||
arg: with-libcurl-lib=[path], Path to libcurl library files
|
||||
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files
|
||||
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_libcurl : public ConfObj
|
||||
class qc_libcommoncpp2 : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libcurl(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libcurl"; }
|
||||
QString shortname() const { return "libcurl"; }
|
||||
qc_libcommoncpp2(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "GNU Common C++ library (libcommoncpp2)"; }
|
||||
QString shortname() const { return "libcommoncpp2"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "curl/curl.h")) {
|
||||
if(!conf->checkHeader(s, "cc++/url.h")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
@@ -512,7 +512,7 @@ public:
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "curl/curl.h")){
|
||||
if(conf->checkHeader(s, "cc++/url.h")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -523,10 +523,12 @@ public:
|
||||
}
|
||||
conf->addIncludePath(s);
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!QFile::exists(s+QString("/libcurl.so")))
|
||||
return false;
|
||||
if(!QFile::exists(s+QString("/libccext2.so")))
|
||||
return false;
|
||||
if(!QFile::exists(s+QString("/libccgnu2.so")))
|
||||
return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}else{
|
||||
QStringList sl;
|
||||
@@ -536,9 +538,11 @@ public:
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(QFile::exists(s+QString("libcurl.so"))){
|
||||
found = true;
|
||||
break;
|
||||
if(QFile::exists(s+QString("libccext2.so"))){
|
||||
if(QFile::exists(s+QString("libccgnu2.so"))){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found) return false;
|
||||
@@ -594,9 +598,9 @@ public:
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkLibrary(s, "Magick++")) {
|
||||
return false;
|
||||
}
|
||||
if(!QFile::exists(s+QString("/libMagick++.so"))){
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
@@ -605,9 +609,9 @@ public:
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkLibrary(s, "Magick++")) {
|
||||
if(QFile::exists(s+QString("libMagick++.so"))){
|
||||
found = true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
@@ -711,7 +715,7 @@ cat >$1/modules_new.cpp <<EOT
|
||||
o = new qc_libboost(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libcurl(conf);
|
||||
o = new qc_libcommoncpp2(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libmagick(conf);
|
||||
@@ -1669,8 +1673,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_LIBCURL_INC
|
||||
export QC_WITH_LIBCURL_LIB
|
||||
export QC_WITH_LIBCOMMONCPP2_INC
|
||||
export QC_WITH_LIBCOMMONCPP2_LIB
|
||||
export QC_DISABLE_libmagick
|
||||
export QC_WITH_LIBMAGICK_INC
|
||||
export QC_WITH_LIBMAGICK_LIB
|
||||
|
@@ -12,7 +12,7 @@
|
||||
<dep type='libboost'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libcurl'>
|
||||
<dep type='libcommoncpp2'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libmagick'/>
|
||||
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
-----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;
|
||||
}
|
||||
};
|
@@ -44,9 +44,9 @@ public:
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkLibrary(s, "Magick++")) {
|
||||
return false;
|
||||
}
|
||||
if(!QFile::exists(s+QString("/libMagick++.so"))){
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
@@ -55,9 +55,9 @@ public:
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkLibrary(s, "Magick++")) {
|
||||
if(QFile::exists(s+QString("libMagick++.so"))){
|
||||
found = true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
|
@@ -313,6 +313,8 @@ 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) {
|
||||
@@ -332,7 +334,7 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
|
||||
has_pause = true;
|
||||
}
|
||||
}
|
||||
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
myFinishedListMenu.addAction(actionPreview_file);
|
||||
has_preview = true;
|
||||
}
|
||||
|
126
src/GUI.cpp
126
src/GUI.cpp
@@ -45,7 +45,6 @@
|
||||
#include "options_imp.h"
|
||||
#include "previewSelect.h"
|
||||
#include "allocationDlg.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
@@ -61,21 +60,14 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
||||
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
|
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||
systrayIntegration = settings.value(QString::fromUtf8("Preferences/General/SystrayEnabled"), true).toBool();
|
||||
systrayCreator = 0;
|
||||
// Create tray icon
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
if(systrayIntegration) {
|
||||
createTrayIcon();
|
||||
}
|
||||
}else{
|
||||
if(systrayIntegration) {
|
||||
// May be system startup, check again later
|
||||
systrayCreator = new QTimer(this);
|
||||
connect(systrayCreator, SIGNAL(timeout()), this, SLOT(createSystrayDelayed()));
|
||||
systrayCreator->start(1000);
|
||||
}
|
||||
systrayIntegration = false;
|
||||
qDebug("Info: System tray unavailable");
|
||||
qDebug("Info: System tray unavailable\n");
|
||||
}
|
||||
// Setting icons
|
||||
this->setWindowIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent32.png")));
|
||||
@@ -167,6 +159,8 @@ 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();
|
||||
@@ -183,14 +177,14 @@ GUI::~GUI() {
|
||||
delete downloadingTorrentTab;
|
||||
delete finishedTorrentTab;
|
||||
delete checkConnect;
|
||||
if(systrayCreator) {
|
||||
delete systrayCreator;
|
||||
}
|
||||
if(systrayIntegration) {
|
||||
delete myTrayIcon;
|
||||
delete myTrayIconMenu;
|
||||
}
|
||||
delete tcpServer;
|
||||
previewProcess->kill();
|
||||
previewProcess->waitForFinished();
|
||||
delete previewProcess;
|
||||
delete connecStatusLblIcon;
|
||||
delete tabs;
|
||||
// Keyboard shortcuts
|
||||
@@ -394,6 +388,12 @@ 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,10 +402,24 @@ void GUI::on_actionExit_triggered() {
|
||||
}
|
||||
|
||||
void GUI::previewFile(QString filePath) {
|
||||
QDesktopServices::openUrl(QString("file://")+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."));
|
||||
}
|
||||
}
|
||||
|
||||
int GUI::getCurrentTabIndex() const{
|
||||
unsigned int GUI::getCurrentTabIndex() const{
|
||||
if(isMinimized() || isHidden())
|
||||
return -1;
|
||||
return tabs->currentIndex();
|
||||
@@ -459,7 +473,7 @@ void GUI::on_actionAbout_triggered() {
|
||||
|
||||
// Called when we close the program
|
||||
void GUI::closeEvent(QCloseEvent *e) {
|
||||
|
||||
qDebug("Mainwindow received closeEvent");
|
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||
bool goToSystrayOnExit = settings.value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool();
|
||||
if(!force_exit && systrayIntegration && goToSystrayOnExit && !this->isHidden()) {
|
||||
@@ -471,16 +485,13 @@ void GUI::closeEvent(QCloseEvent *e) {
|
||||
show();
|
||||
if(!isMaximized())
|
||||
showNormal();
|
||||
if(e->spontaneous() == true || force_exit == true) {
|
||||
if(QMessageBox::question(this,
|
||||
tr("Are you sure you want to quit?")+QString::fromUtf8(" -- ")+tr("qBittorrent"),
|
||||
tr("The download list is not empty.\nAre you sure you want to quit qBittorrent?"),
|
||||
tr("&Yes"), tr("&No"),
|
||||
QString(), 0, 1)) {
|
||||
e->ignore();
|
||||
force_exit = false;
|
||||
return;
|
||||
}
|
||||
if(QMessageBox::question(this,
|
||||
tr("Are you sure you want to quit?")+QString::fromUtf8(" -- ")+tr("qBittorrent"),
|
||||
tr("The download list is not empty.\nAre you sure you want to quit qBittorrent?"),
|
||||
tr("&Yes"), tr("&No"),
|
||||
QString(), 0, 1)) {
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
hide();
|
||||
@@ -498,7 +509,6 @@ void GUI::closeEvent(QCloseEvent *e) {
|
||||
qApp->exit();
|
||||
}
|
||||
|
||||
|
||||
// Display window to create a torrent
|
||||
void GUI::on_actionCreate_torrent_triggered() {
|
||||
createtorrent *ct = new createtorrent(this);
|
||||
@@ -778,12 +788,7 @@ void GUI::processDownloadedFiles(QString path, QString url) {
|
||||
void GUI::configureSession(bool deleteOptions) {
|
||||
qDebug("Configuring session");
|
||||
// General
|
||||
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;
|
||||
displaySpeedInTitle = options->speedInTitleBar();
|
||||
unsigned int new_refreshInterval = options->getRefreshInterval();
|
||||
if(refreshInterval != new_refreshInterval) {
|
||||
refreshInterval = new_refreshInterval;
|
||||
@@ -844,21 +849,12 @@ 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;
|
||||
@@ -867,22 +863,12 @@ void GUI::configureSession(bool deleteOptions) {
|
||||
proxySettings.type = proxy_settings::socks5_pw;
|
||||
break;
|
||||
}
|
||||
if(!proxy_str.isEmpty()) {
|
||||
// We need this for urllib in search engine plugins
|
||||
#ifdef Q_WS_WIN
|
||||
char proxystr[512];
|
||||
snprintf(proxystr, 512, "http_proxy=%s", proxy_str.toUtf8().data());
|
||||
putenv(proxystr);
|
||||
#else
|
||||
setenv("http_proxy", proxy_str.toUtf8().data(), 1);
|
||||
#endif
|
||||
proxySettings.hostname = options->getProxyIp().toStdString();
|
||||
proxySettings.port = options->getProxyPort();
|
||||
if(options->isProxyAuthEnabled()) {
|
||||
proxySettings.username = options->getProxyUsername().toStdString();
|
||||
proxySettings.password = options->getProxyPassword().toStdString();
|
||||
}
|
||||
} else {
|
||||
#ifdef Q_WS_WIN
|
||||
putenv("http_proxy=");
|
||||
#else
|
||||
unsetenv("http_proxy");
|
||||
#endif
|
||||
}
|
||||
BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT());
|
||||
// * Session settings
|
||||
@@ -1193,37 +1179,9 @@ void GUI::downloadFromURLList(const QStringList& urls) {
|
||||
* *
|
||||
*****************************************************/
|
||||
|
||||
void GUI::createSystrayDelayed() {
|
||||
static int timeout = 10;
|
||||
if(QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
// Ok, systray integration is now supported
|
||||
// Create systray icon
|
||||
createTrayIcon();
|
||||
systrayIntegration = true;
|
||||
delete systrayCreator;
|
||||
systrayCreator = 0;
|
||||
} else {
|
||||
if(timeout) {
|
||||
// Retry a bit later
|
||||
systrayCreator->start(1000);
|
||||
--timeout;
|
||||
} else {
|
||||
// Timed out, apparently system really does not
|
||||
// support systray icon
|
||||
delete systrayCreator;
|
||||
systrayCreator = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::createTrayIcon() {
|
||||
// Tray icon
|
||||
#ifdef Q_WS_WIN
|
||||
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent16.png")), this);
|
||||
#endif
|
||||
#ifndef Q_WS_WIN
|
||||
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent22.png")), this);
|
||||
#endif
|
||||
// Tray icon Menu
|
||||
myTrayIconMenu = new QMenu(this);
|
||||
myTrayIconMenu->addAction(actionOpen);
|
||||
|
@@ -59,7 +59,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
QTabWidget *tabs;
|
||||
options_imp *options;
|
||||
QSystemTrayIcon *myTrayIcon;
|
||||
QTimer *systrayCreator;
|
||||
QMenu *myTrayIconMenu;
|
||||
DownloadingTorrents *downloadingTorrentTab;
|
||||
FinishedTorrents *finishedTorrentTab;
|
||||
@@ -75,6 +74,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
QShortcut *switchDownShortcut;
|
||||
QShortcut *switchUpShortcut;
|
||||
QShortcut *switchRSSShortcut;
|
||||
// Preview
|
||||
QProcess *previewProcess;
|
||||
// Search
|
||||
SearchEngine *searchEngine;
|
||||
// RSS
|
||||
@@ -97,6 +98,7 @@ 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();
|
||||
@@ -106,7 +108,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
void updateFinishedTorrentNumber(unsigned int nb);
|
||||
void fullDiskError(QTorrentHandle& h) const;
|
||||
void handleDownloadFromUrlFailure(QString, QString) const;
|
||||
void createSystrayDelayed();
|
||||
// Keyboard shortcuts
|
||||
void createKeyboardShortcuts();
|
||||
void displayDownTab() const;
|
||||
@@ -157,7 +158,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList());
|
||||
~GUI();
|
||||
// Methods
|
||||
int getCurrentTabIndex() const;
|
||||
unsigned int getCurrentTabIndex() const;
|
||||
QPoint screenCenter() const;
|
||||
};
|
||||
|
||||
|
@@ -181,8 +181,7 @@ class PropListDelegate: public QItemDelegate {
|
||||
// } else {
|
||||
model->setData(index, QVariant(HIGH));
|
||||
model->setData(index, QVariant(NORMAL));
|
||||
if(filteredFilesChanged != 0)
|
||||
*filteredFilesChanged = true;
|
||||
*filteredFilesChanged = true;
|
||||
// }
|
||||
break;
|
||||
case 2:
|
||||
|
@@ -27,19 +27,19 @@
|
||||
#include <QDir>
|
||||
#include "misc.h"
|
||||
|
||||
class torrent_file {
|
||||
class file {
|
||||
private:
|
||||
torrent_file *parent;
|
||||
file *parent;
|
||||
bool is_dir;
|
||||
QString rel_path;
|
||||
QList<torrent_file*> children;
|
||||
QList<file*> children;
|
||||
size_type size;
|
||||
float progress;
|
||||
int priority;
|
||||
int index; // Index in torrent_info
|
||||
|
||||
public:
|
||||
torrent_file(torrent_file *parent, QString path, bool dir, size_type size=0, int index=-1, float progress=0., int priority=1): parent(parent), is_dir(dir), size(size), progress(progress), priority(priority), index(index){
|
||||
file(file *parent, QString path, bool dir, size_type size=0, int index=-1, float progress=0., int priority=1): parent(parent), is_dir(dir), size(size), progress(progress), priority(priority), index(index){
|
||||
qDebug("created a file with index %d", index);
|
||||
rel_path = QDir::cleanPath(path);
|
||||
if(parent) {
|
||||
@@ -48,7 +48,7 @@ class torrent_file {
|
||||
}
|
||||
}
|
||||
|
||||
~torrent_file() {
|
||||
~file() {
|
||||
qDeleteAll(children);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class torrent_file {
|
||||
}
|
||||
float wanted = 0.;
|
||||
float done = 0.;
|
||||
torrent_file *child;
|
||||
file *child;
|
||||
foreach(child, children) {
|
||||
wanted += child->getSize();
|
||||
done += child->getSize()*child->getProgress();
|
||||
@@ -80,7 +80,7 @@ class torrent_file {
|
||||
|
||||
void updatePriority(int prio) {
|
||||
Q_ASSERT(is_dir);
|
||||
torrent_file *child;
|
||||
file *child;
|
||||
foreach(child, children) {
|
||||
if(child->getPriority() != prio) return;
|
||||
}
|
||||
@@ -111,13 +111,13 @@ class torrent_file {
|
||||
return (!children.isEmpty());
|
||||
}
|
||||
|
||||
QList<torrent_file*> getChildren() const {
|
||||
QList<file*> getChildren() const {
|
||||
return children;
|
||||
}
|
||||
|
||||
torrent_file* getChild(QString fileName) const {
|
||||
file* getChild(QString fileName) const {
|
||||
Q_ASSERT(is_dir);
|
||||
torrent_file* f;
|
||||
file* f;
|
||||
foreach(f, children) {
|
||||
if(f->name() == fileName) return f;
|
||||
}
|
||||
@@ -130,10 +130,10 @@ class torrent_file {
|
||||
parent->addBytes(b);
|
||||
}
|
||||
|
||||
torrent_file* addChild(QString fileName, bool dir, size_type size=0, int index = -1, float progress=0., int priority=1) {
|
||||
file* addChild(QString fileName, bool dir, size_type size=0, int index = -1, float progress=0., int priority=1) {
|
||||
Q_ASSERT(is_dir);
|
||||
qDebug("Adding a new child of size: %ld", (long)size);
|
||||
torrent_file *f = new torrent_file(this, QDir::cleanPath(rel_path+QDir::separator()+fileName), dir, size, index, progress, priority);
|
||||
file *f = new file(this, QDir::cleanPath(rel_path+QDir::separator()+fileName), dir, size, index, progress, priority);
|
||||
children << f;
|
||||
if(size) {
|
||||
addBytes(size);
|
||||
@@ -148,7 +148,7 @@ class torrent_file {
|
||||
return true;
|
||||
}
|
||||
bool success = true;
|
||||
torrent_file *f;
|
||||
file *f;
|
||||
qDebug("We have %d children", children.size());
|
||||
foreach(f, children) {
|
||||
bool s = f->removeFromFS(saveDir);
|
||||
@@ -169,16 +169,16 @@ class torrent_file {
|
||||
|
||||
class arborescence {
|
||||
private:
|
||||
torrent_file *root;
|
||||
file *root;
|
||||
|
||||
public:
|
||||
arborescence(torrent_info t) {
|
||||
torrent_info::file_iterator fi = t.begin_files();
|
||||
if(t.num_files() > 1) {
|
||||
root = new torrent_file(0, misc::toQString(t.name()), true);
|
||||
root = new file(0, misc::toQString(t.name()), true);
|
||||
} else {
|
||||
// XXX: Will crash if there is no file in torrent
|
||||
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0);
|
||||
root = new file(0, misc::toQString(t.name()), false, fi->size, 0);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
@@ -196,11 +196,11 @@ class arborescence {
|
||||
torrent_info::file_iterator fi = t.begin_files();
|
||||
if(t.num_files() > 1) {
|
||||
qDebug("More than one file in the torrent, setting a folder as root");
|
||||
root = new torrent_file(0, misc::toQString(t.name()), true);
|
||||
root = new file(0, misc::toQString(t.name()), true);
|
||||
} else {
|
||||
// XXX: Will crash if there is no file in torrent
|
||||
qDebug("one file in the torrent, setting it as root with index 0");
|
||||
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]);
|
||||
root = new file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
@@ -218,7 +218,7 @@ class arborescence {
|
||||
delete root;
|
||||
}
|
||||
|
||||
torrent_file* getRoot() const {
|
||||
file* getRoot() const {
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -240,13 +240,13 @@ class arborescence {
|
||||
relative_path.remove(0, 1);
|
||||
QStringList fileNames = relative_path.split(QDir::separator());
|
||||
QString fileName;
|
||||
torrent_file *dad = root;
|
||||
file *dad = root;
|
||||
unsigned int nb_i = 0;
|
||||
unsigned int size = fileNames.size();
|
||||
foreach(fileName, fileNames) {
|
||||
++nb_i;
|
||||
if(fileName == ".") continue;
|
||||
torrent_file* child = dad->getChild(fileName);
|
||||
file* child = dad->getChild(fileName);
|
||||
if(!child) {
|
||||
if(nb_i != size) {
|
||||
// Folder
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,6 @@
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QStringList>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/ip_filter.hpp>
|
||||
@@ -45,17 +44,18 @@ class bittorrent : public QObject{
|
||||
QString scan_dir;
|
||||
QTimer *timerScan;
|
||||
QTimer *timerAlerts;
|
||||
QTimer *fastResumeSaver;
|
||||
QTimer *BigRatioTimer;
|
||||
bool DHTEnabled;
|
||||
downloadThread *downloader;
|
||||
QString defaultSavePath;
|
||||
QStringList torrentsToPauseAfterChecking;
|
||||
QHash<QString, QDateTime> TorrentsStartTime;
|
||||
QHash<QString, size_type> TorrentsStartData;
|
||||
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,9 +63,6 @@ class bittorrent : public QObject{
|
||||
int maxConnecsPerTorrent;
|
||||
int maxUploadsPerTorrent;
|
||||
float max_ratio;
|
||||
bool UPnPEnabled;
|
||||
bool NATPMPEnabled;
|
||||
bool LSDEnabled;
|
||||
|
||||
protected:
|
||||
QString getSavePath(QString hash);
|
||||
@@ -83,7 +80,7 @@ class bittorrent : public QObject{
|
||||
session_status getSessionStatus() const;
|
||||
int getListenPort() const;
|
||||
QStringList getTorrentsToPauseAfterChecking() const;
|
||||
qlonglong getETA(QString hash) const;
|
||||
long getETA(QString hash) const;
|
||||
float getRealRatio(QString hash) const;
|
||||
session* getSession() const;
|
||||
QList<QPair<QString, QString> > getTrackersErrors(QString hash) const;
|
||||
@@ -102,13 +99,13 @@ 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();
|
||||
void enableIPFilter(ip_filter filter);
|
||||
void disableIPFilter();
|
||||
void resumeUnfinishedTorrents();
|
||||
void updateETAs();
|
||||
void saveTorrentSpeedLimits(QString hash);
|
||||
void loadTorrentSpeedLimits(QString hash);
|
||||
void saveDownloadUploadForTorrent(QString hash);
|
||||
@@ -139,7 +136,6 @@ 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();
|
||||
@@ -147,6 +143,8 @@ 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:
|
||||
|
@@ -36,7 +36,6 @@
|
||||
#include <libtorrent/file_pool.hpp>
|
||||
|
||||
#include "createtorrent_imp.h"
|
||||
#include "misc.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
@@ -121,13 +120,11 @@ void createtorrent::on_addURLSeed_button_clicked(){
|
||||
// Subfunction to add files to a torrent_info structure
|
||||
// Written by Arvid Norberg (libtorrent Author)
|
||||
void add_files(torrent_info& t, path const& p, path const& l){
|
||||
qDebug("p: %s, l: %s, l.leaf(): %s", p.string().c_str(), l.string().c_str(), l.leaf().c_str());
|
||||
path f(p / l);
|
||||
if (is_directory(f)){
|
||||
for (directory_iterator i(f), end; i != end; ++i)
|
||||
add_files(t, p, l / i->leaf());
|
||||
}else{
|
||||
qDebug("Adding %s", l.string().c_str());
|
||||
t.add_file(l, file_size(f));
|
||||
}
|
||||
}
|
||||
@@ -144,8 +141,6 @@ QStringList createtorrent::allItems(QListWidget *list){
|
||||
// Main function that create a .torrent file
|
||||
void createtorrent::on_createButton_clicked(){
|
||||
QString input = textInputPath->text().trimmed();
|
||||
if (input.endsWith(QDir::separator()))
|
||||
input.chop(1);
|
||||
if(input.isEmpty()){
|
||||
QMessageBox::critical(0, tr("No input path set"), tr("Please type an input path first"));
|
||||
return;
|
||||
@@ -166,8 +161,9 @@ void createtorrent::on_createButton_clicked(){
|
||||
try {
|
||||
boost::intrusive_ptr<torrent_info> t(new torrent_info);
|
||||
ofstream out(complete(path((const char*)destination.toUtf8())), std::ios_base::binary);
|
||||
path full_path;
|
||||
// Adding files to the torrent
|
||||
path full_path = complete(path(input.toUtf8().data()));
|
||||
full_path = complete(path(input.toUtf8().data()));
|
||||
add_files(*t, full_path.branch_path(), full_path.leaf());
|
||||
// Set piece size
|
||||
int piece_size = getPieceSize();
|
||||
@@ -204,14 +200,8 @@ void createtorrent::on_createButton_clicked(){
|
||||
entry e = t->create_torrent();
|
||||
libtorrent::bencode(std::ostream_iterator<char>(out), e);
|
||||
out.flush();
|
||||
if(checkStartSeeding->isChecked()) {
|
||||
// Create save path file
|
||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+misc::toQString(t->info_hash())+QString::fromUtf8(".savepath"));
|
||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
savepath_file.write(full_path.branch_path().string().c_str());
|
||||
savepath_file.close();
|
||||
if(checkStartSeeding->isChecked())
|
||||
emit torrent_to_seed(destination);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e){
|
||||
std::cerr << e.what() << "\n";
|
||||
|
@@ -21,48 +21,43 @@
|
||||
|
||||
#include "downloadThread.h"
|
||||
#include <iostream>
|
||||
#include <QSettings>
|
||||
#include <stdio.h>
|
||||
#include <cc++/common.h>
|
||||
|
||||
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
|
||||
QString subDownloadThread::errorCodeToString(CURLcode status) {
|
||||
QString subDownloadThread::errorCodeToString(int status) {
|
||||
switch(status){
|
||||
case CURLE_FTP_CANT_GET_HOST:
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
case 1://ost::URLStream::errUnreachable:
|
||||
return tr("Host is unreachable");
|
||||
case CURLE_READ_ERROR:
|
||||
case CURLE_FILE_COULDNT_READ_FILE:
|
||||
case 2://ost::URLStream::errMissing:
|
||||
return tr("File was not found (404)");
|
||||
case CURLE_FTP_ACCESS_DENIED:
|
||||
case CURLE_LOGIN_DENIED:
|
||||
case CURLE_FTP_USER_PASSWORD_INCORRECT:
|
||||
case 3://ost::URLStream::errDenied:
|
||||
return tr("Connection was denied");
|
||||
case CURLE_URL_MALFORMAT:
|
||||
case 4://ost::URLStream::errInvalid:
|
||||
return tr("Url is invalid");
|
||||
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:
|
||||
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:
|
||||
return tr("Connection failure");
|
||||
case CURLE_OPERATION_TIMEOUTED:
|
||||
case 9://ost::URLStream::errTimeout:
|
||||
return tr("Connection was timed out");
|
||||
case CURLE_INTERFACE_FAILED:
|
||||
case 10://ost::URLStream::errInterface:
|
||||
return tr("Incorrect network interface");
|
||||
default:
|
||||
return tr("Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){}
|
||||
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){
|
||||
url_stream = new ost::URLStream();
|
||||
}
|
||||
|
||||
subDownloadThread::~subDownloadThread(){
|
||||
abort = true;
|
||||
wait();
|
||||
delete url_stream;
|
||||
}
|
||||
|
||||
void subDownloadThread::run(){
|
||||
@@ -73,66 +68,38 @@ void subDownloadThread::run(){
|
||||
filePath = tmpfile->fileName();
|
||||
}
|
||||
delete tmpfile;
|
||||
FILE *f = fopen(filePath.toUtf8().data(), "wb");
|
||||
if(!f) {
|
||||
std::cerr << "couldn't open destination file" << "\n";
|
||||
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';
|
||||
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());
|
||||
}
|
||||
}
|
||||
// We have to define CURLOPT_WRITEFUNCTION or it will crash on windows
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
|
||||
// Verbose
|
||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
// No progress info (we don't use it)
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
||||
// Redirections
|
||||
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1);
|
||||
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";
|
||||
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;
|
||||
}
|
||||
}
|
||||
dest_file.close();
|
||||
url_stream->close();
|
||||
emit downloadFinishedST(this, url, filePath);
|
||||
qDebug("download completed here: %s", (const char*)filePath.toUtf8());
|
||||
}
|
||||
|
||||
/** Download Thread **/
|
||||
|
@@ -29,18 +29,22 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QWaitCondition>
|
||||
#include <QStringList>
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace ost {
|
||||
class URLStream;
|
||||
}
|
||||
|
||||
class subDownloadThread : public QThread {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QString url;
|
||||
ost::URLStream *url_stream;
|
||||
bool abort;
|
||||
|
||||
public:
|
||||
subDownloadThread(QObject *parent, QString url);
|
||||
~subDownloadThread();
|
||||
QString errorCodeToString(CURLcode status);
|
||||
QString errorCodeToString(int status);
|
||||
|
||||
signals:
|
||||
// For subthreads
|
||||
@@ -72,13 +76,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);
|
||||
};
|
||||
|
||||
|
@@ -190,6 +190,7 @@ 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>"));
|
||||
}
|
||||
|
||||
@@ -245,6 +246,8 @@ 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) {
|
||||
@@ -264,7 +267,7 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
|
||||
has_pause = true;
|
||||
}
|
||||
}
|
||||
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
myDLLlistMenu.addAction(actionPreview_file);
|
||||
has_preview = true;
|
||||
}
|
||||
@@ -414,7 +417,7 @@ void DownloadingTorrents::updateDlList() {
|
||||
}else{
|
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole);
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
|
||||
setRowColor(row, QPalette::WindowText);
|
||||
}
|
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
|
||||
|
@@ -82,7 +82,7 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
||||
|
||||
public slots:
|
||||
void updateDlList();
|
||||
void setInfoBar(QString info, QColor color=QApplication::palette().color(QPalette::WindowText));
|
||||
void setInfoBar(QString info, QColor color=QPalette::WindowText);
|
||||
void pauseTorrent(QString hash);
|
||||
void resumeTorrent(QString hash);
|
||||
void updateRatio();
|
||||
|
@@ -250,13 +250,11 @@ void engineSelectDlg::setRowColor(int row, QString color){
|
||||
bool engineSelectDlg::checkInstalled(QString plugin_name) const {
|
||||
QProcess nova;
|
||||
QStringList params;
|
||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
||||
params << "--supported_engines";
|
||||
nova.start("python", params, QIODevice::ReadOnly);
|
||||
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly);
|
||||
nova.waitForStarted();
|
||||
nova.waitForFinished();
|
||||
QByteArray result = nova.readAll();
|
||||
result = result.replace("\r", "");
|
||||
result = result.replace("\n", "");
|
||||
QList<QByteArray> plugins_list = result.split(',');
|
||||
return plugins_list.contains(plugin_name.toUtf8());
|
||||
@@ -282,13 +280,11 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
|
||||
QStringList params;
|
||||
// Ask nova core for the supported search engines
|
||||
QProcess nova;
|
||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
||||
params << "--supported_engines";
|
||||
nova.start("python", params, QIODevice::ReadOnly);
|
||||
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly);
|
||||
nova.waitForStarted();
|
||||
nova.waitForFinished();
|
||||
QByteArray result = nova.readAll();
|
||||
result = result.replace("\r", "");
|
||||
result = result.replace("\n", "");
|
||||
qDebug("read: %s", result.data());
|
||||
QByteArray e;
|
||||
@@ -299,13 +295,11 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
|
||||
installed_engines[en] = old_engines.value(en, true);
|
||||
}
|
||||
params.clear();
|
||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
||||
params << "--supported_engines_infos";
|
||||
nova.start("python", params, QIODevice::ReadOnly);
|
||||
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly);
|
||||
nova.waitForStarted();
|
||||
nova.waitForFinished();
|
||||
result = nova.readAll();
|
||||
result = result.replace("\r", "");
|
||||
result = result.replace("\n", "");
|
||||
qDebug("read: %s", result.data());
|
||||
unsigned int i = 0;
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user