You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-16 20:32:23 +02:00
Compare commits
1 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a175812555 |
16
AUTHORS
16
AUTHORS
@@ -6,11 +6,6 @@ Contributors:
|
||||
* Ishan Arora <ishan@qbittorrent.org>
|
||||
* Grigis Gaëtan <cipher16@gmail.com>
|
||||
|
||||
Code from other projects:
|
||||
* files src/ico.cpp src/ico.h
|
||||
copyright: Malte Starostik <malte@kde.org>
|
||||
license: LGPL
|
||||
|
||||
Images Authors:
|
||||
* files: src/Icons/*.png
|
||||
copyright: Gnome Icon Theme
|
||||
@@ -22,14 +17,13 @@ Images Authors:
|
||||
license: Creative Commons Public Domain Dedication
|
||||
url: http://www.openclipart.org
|
||||
|
||||
* files: src/Icons/skin/*.png
|
||||
files: src/menuicons/YYxYY/*.png
|
||||
* files: src/Icons/skins/*.png
|
||||
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
|
||||
license: GPLv2
|
||||
|
||||
* file: src/Icons/skin/tabs.gif
|
||||
copyright: Greg Houston <gregory.houston@gmail.com>
|
||||
license: MIT
|
||||
* files: src/menuicons/YYxYY/*.png
|
||||
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
|
||||
license: GPLv2
|
||||
|
||||
* file: src/search_engine/engines/btjunkie.png
|
||||
copyright: Downloaded from btjunkie.org
|
||||
@@ -52,7 +46,7 @@ Translations authors:
|
||||
- Brazilian: Nick Marinho (nickmarinho@gmail.com)
|
||||
- Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)
|
||||
- Catalan: Gekko Dam Beer (gekko04@users.sourceforge.net)
|
||||
- Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com)
|
||||
- Chinese (Simplified): Guo Yue (guoyue0418@hotmail.com)
|
||||
- Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com)
|
||||
- Czech: Jirka Vilim (web@tets.cz)
|
||||
- Danish: Mathias Nielsen (comoneo@gmail.com)
|
||||
|
54
Changelog
54
Changelog
@@ -1,61 +1,9 @@
|
||||
* Mon Jan 26 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.1
|
||||
- BUGFIX: Torrents paused due to an I/O error were displayed as queued
|
||||
- BUGFIX: qBittorrent now prints backtrace in terminal when segfaulting
|
||||
- BUGFIX: Fixed files progress display in torrent properties
|
||||
- BUGFIX: Improved torrent ratio calculation
|
||||
- BUGFIX: Fixed possible crash when parsing filter file
|
||||
- BUGFIX: Made some code optimization
|
||||
- BUGFIX: Fixed download/upload speed decrease problems
|
||||
- I18N: Updated Finnish, Bulgarian and Greek translations
|
||||
|
||||
* Fri Jan 9 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.0
|
||||
- FEATURE: Based on libtorrent-rasterbar v0.14.2
|
||||
- FEATURE: Improved ratio calculation system
|
||||
- FEATURE: Torrent creation code cleanup
|
||||
- FEATURE: Allow to set maximum number of active seeds (queueing)
|
||||
- FEATURE: Now seeds priorities are handled automatically by libtorrent-rasterbar (queueing)
|
||||
- FEATURE: Code cleanup and optimization (save memory and cpu)
|
||||
- FEATURE: ETA calculation now relies on average speed over all sessions
|
||||
- FEATURE: Allow to force rechecking torrents
|
||||
- FEATURE: Added support for 2 new extensions (uTorrent metadata and smart ban plugin)
|
||||
- FEATURE: Allow to change the save path of torrents after addition
|
||||
- FEATURE: Got rid of libmagick++ dependency
|
||||
- FEATURE: Updated Web interface to MochaUI v0.9.5
|
||||
- FEATURE: Added notification in WebUI when qBittorrent is not reachable
|
||||
- FEATURE: Rewrote folder scanning code (Now uses a filesystem watcher)
|
||||
- FEATURE: Added torrent deletion from hard drive function in Web UI
|
||||
- FEATURE: Added queueing priority actions in Web UI
|
||||
- FEATURE: Display progress using progress bars in Web UI
|
||||
- BUGFIX: Made usage of fastresume data more reliable
|
||||
- BUGFIX: qBittorrent shutdown is now faster
|
||||
- BUGFIX: Fixed several memory leaks
|
||||
- BUGFIX: WebUI is now working with IE7
|
||||
- BUGFIX: Fixed spacing problem in toolbar when toggling its visibility
|
||||
- BUGFIX: Fixed some compilation and Qt4 warnings
|
||||
- BUGFIX: Do not use an addition dialog for torrents from folder scanning
|
||||
- BUGFIX: Catch SIGTERM to exit cleanly (e.g. computer shutdown)
|
||||
- BUGFIX: Improved proxy support code
|
||||
- BUGFIX: Fixed systray icon tooltip on Windows
|
||||
- BUGFIX: Proxy settings are now saved even if disabled
|
||||
|
||||
* Sun Nov 9 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.2.1
|
||||
- BUGFIX: Fixed possible crash when deleting a torrent permanently
|
||||
- BUGFIX: Queued_for_checking torrents were not displayed as checking in seeding list
|
||||
- BUGFIX: Speed up startup time when having a lot of torrents
|
||||
|
||||
* Wed Oct 29th 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.2.0
|
||||
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.2.0
|
||||
- FEATURE: Torrent queueing system (with priorities)
|
||||
- FEATURE: The number of DHT nodes is displayed
|
||||
- FEATURE: RSS can now be disabled from program preferences
|
||||
- FEATURE: Added collapse/expand all buttons in addition and properties dialogs
|
||||
- FEATURE: Can have different proxies for Bittorrent and search engine
|
||||
- FEATURE: Allow multiple item selection in Web UI transfer list
|
||||
- FEATURE: Moved uploads to a separate list in Web UI
|
||||
- BUGFIX: Totally rewritten Web UI list refresh system (fixed memory leak)
|
||||
- BUGFIX: Disable ETA calculation when ETA column is hidden
|
||||
- BUGFIX: Removed "disconnected" connection state, detection was far from perfect
|
||||
- BUGFIX: Torrents are no longer starting from scratch when changing default save path (when torrent addition dialog is disabled)
|
||||
- BUGFIX: Single instance code is now more reliable on Qt >= 4.4
|
||||
- COSMETIC: Transfer speed, ratio, connection status and DHT nodes are displayed in status bar
|
||||
- COSMETIC: RSS Tab is now hidden as a default
|
||||
- COSMETIC: Allow to hide or display top toolbar
|
||||
|
2
INSTALL
2
INSTALL
@@ -17,7 +17,7 @@ Dependencies:
|
||||
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||
Qt >= 4.4.0 is advised
|
||||
|
||||
- libtorrent-rasterbar by Arvid Norberg (>= v0.14.0 REQUIRED)
|
||||
- libtorrent-rasterbar by Arvid Norberg (>= v0.13.1 REQUIRED)
|
||||
-> http://www.qbittorrent.org/download.php (advised)
|
||||
-> http://www.libtorrent.net
|
||||
Be careful: another library (the one used by rTorrent) uses a similar name.
|
||||
|
21
TODO
21
TODO
@@ -1,21 +1,4 @@
|
||||
See https://blueprints.launchpad.net/qbittorrent/
|
||||
|
||||
// translations done in v1.3.0
|
||||
- Romanian
|
||||
- Russian
|
||||
- Hungarian
|
||||
- German
|
||||
- Chinese (traditional)
|
||||
- Chinese (simplified)
|
||||
- Italian
|
||||
- Swedish
|
||||
- Turkish
|
||||
- French
|
||||
- Slovak
|
||||
- Czech
|
||||
- Korean
|
||||
- Portuguese
|
||||
- Brazilian
|
||||
- Greek
|
||||
- Bulgarian
|
||||
- Finnish
|
||||
// in v1.2.0
|
||||
- Split download and uploads in Web UI (Ishan Ahora)
|
||||
|
113
configure
vendored
113
configure
vendored
@@ -26,6 +26,9 @@ Dependency options:
|
||||
--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
|
||||
--disable-libmagick Disable use of libmagick
|
||||
--with-libmagick-inc=[path] Path to libmagick++ include files
|
||||
--with-libmagick-lib=[path] Path to libmagick++ library files
|
||||
--disable-libzzip Disable use of libzzip
|
||||
--with-libzzip-inc=[path] Path to libzzip++ include files
|
||||
--with-libzzip-lib=[path] Path to libzzip++ library files
|
||||
@@ -175,6 +178,21 @@ while [ $# -gt 0 ]; do
|
||||
shift
|
||||
;;
|
||||
|
||||
--disable-libmagick)
|
||||
QC_DISABLE_libmagick="Y"
|
||||
shift
|
||||
;;
|
||||
|
||||
--with-libmagick-inc=*)
|
||||
QC_WITH_LIBMAGICK_INC=$optarg
|
||||
shift
|
||||
;;
|
||||
|
||||
--with-libmagick-lib=*)
|
||||
QC_WITH_LIBMAGICK_LIB=$optarg
|
||||
shift
|
||||
;;
|
||||
|
||||
--disable-libzzip)
|
||||
QC_DISABLE_libzzip="Y"
|
||||
shift
|
||||
@@ -217,6 +235,9 @@ 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_DISABLE_libmagick=$QC_DISABLE_libmagick
|
||||
echo QC_WITH_LIBMAGICK_INC=$QC_WITH_LIBMAGICK_INC
|
||||
echo QC_WITH_LIBMAGICK_LIB=$QC_WITH_LIBMAGICK_LIB
|
||||
echo QC_DISABLE_libzzip=$QC_DISABLE_libzzip
|
||||
echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC
|
||||
echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB
|
||||
@@ -355,13 +376,13 @@ class qc_libtorrent_rasterbar : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
|
||||
QString name() const { return "libtorrent-rasterbar >= 0.13"; }
|
||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
|
||||
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
@@ -370,7 +391,7 @@ public:
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
|
||||
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -532,6 +553,86 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#line 1 "libmagick.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libmagick
|
||||
arg: with-libmagick-inc=[path], Path to libmagick++ include files
|
||||
arg: with-libmagick-lib=[path], Path to libmagick++ library files
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
#include <QProcess>
|
||||
class qc_libmagick : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libmagick(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "ImageMagick library (libmagick++)"; }
|
||||
QString shortname() const { return "libmagick++"; }
|
||||
QString checkString() const {
|
||||
if(!conf->getenv("QC_DISABLE_libmagick").isEmpty())
|
||||
return "";
|
||||
return ConfObj::checkString();
|
||||
}
|
||||
bool exec(){
|
||||
if(!conf->getenv("QC_DISABLE_libmagick").isEmpty())
|
||||
return false;
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBMAGICK_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "Magick++.h")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/include";
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "Magick++.h")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
return false;
|
||||
}
|
||||
conf->addIncludePath(s);
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkLibrary(s, "Magick++")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
sl << "/usr/lib64/";
|
||||
sl << "/usr/local/lib/";
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkLibrary(s, "Magick++")) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
return false;
|
||||
}
|
||||
conf->addLib(QString("-L") + s);
|
||||
QProcess magickConfig;
|
||||
QStringList params;
|
||||
params << "--libs";
|
||||
magickConfig.start("Magick++-config", params, QIODevice::ReadOnly);
|
||||
magickConfig.waitForStarted();
|
||||
magickConfig.waitForFinished();
|
||||
QByteArray result = magickConfig.readAll();
|
||||
result = result.replace("\n", "");
|
||||
conf->addLib(result.data());
|
||||
conf->addDefine("HAVE_MAGICK");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#line 1 "libzzip.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
@@ -619,6 +720,9 @@ cat >$1/modules_new.cpp <<EOT
|
||||
o = new qc_libcurl(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libmagick(conf);
|
||||
o->required = false;
|
||||
o->disabled = false;
|
||||
o = new qc_libzzip(conf);
|
||||
o->required = false;
|
||||
o->disabled = false;
|
||||
@@ -1573,6 +1677,9 @@ export QC_WITH_LIBTORRENT_STATIC_LIB
|
||||
export QC_WITH_LIBBOOST_INC
|
||||
export QC_WITH_LIBCURL_INC
|
||||
export QC_WITH_LIBCURL_LIB
|
||||
export QC_DISABLE_libmagick
|
||||
export QC_WITH_LIBMAGICK_INC
|
||||
export QC_WITH_LIBMAGICK_LIB
|
||||
export QC_DISABLE_libzzip
|
||||
export QC_WITH_LIBZZIP_INC
|
||||
export QC_WITH_LIBZZIP_LIB
|
||||
|
@@ -15,5 +15,6 @@
|
||||
<dep type='libcurl'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libmagick'/>
|
||||
<dep type='libzzip'/>
|
||||
</qconf>
|
||||
|
65
qcm/libcommoncpp2.qcm
Normal file
65
qcm/libcommoncpp2.qcm
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libcommoncpp2
|
||||
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files
|
||||
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_libcommoncpp2 : public ConfObj
|
||||
{
|
||||
public:
|
||||
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_LIBCOMMONCPP2_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "cc++/url.h")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/include";
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "cc++/url.h")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
conf->addIncludePath(s);
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
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;
|
||||
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("libccext2.so"))){
|
||||
if(QFile::exists(s+QString("libccgnu2.so"))){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found) return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
@@ -6,18 +6,17 @@ arg: with-libtorrent-lib=[path], Path to libtorrent-rasterbar library files
|
||||
arg: with-libtorrent-static-lib=[path], Path to libtorrent-rasterbar .a file
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
// see Conf::findPkgConfig
|
||||
class qc_libtorrent_rasterbar : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
|
||||
QString name() const { return "libtorrent-rasterbar >= 0.13"; }
|
||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
|
||||
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
@@ -26,7 +25,7 @@ public:
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
|
||||
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@@ -72,10 +72,7 @@ class DLListDelegate: public QItemDelegate {
|
||||
case RATIO:{
|
||||
QItemDelegate::drawBackground(painter, opt, index);
|
||||
double ratio = index.data().toDouble();
|
||||
if(ratio > 100.)
|
||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞"));
|
||||
else
|
||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||
break;
|
||||
}
|
||||
case PROGRESS:{
|
||||
|
@@ -37,7 +37,8 @@
|
||||
#define F_UPSPEED 2
|
||||
#define F_LEECH 3
|
||||
#define F_RATIO 4
|
||||
#define F_HASH 5
|
||||
#define F_PRIORITY 5
|
||||
#define F_HASH 6
|
||||
|
||||
class FinishedListDelegate: public QItemDelegate {
|
||||
Q_OBJECT
|
||||
@@ -63,10 +64,7 @@ class FinishedListDelegate: public QItemDelegate {
|
||||
case F_RATIO:{
|
||||
QItemDelegate::drawBackground(painter, opt, index);
|
||||
double ratio = index.data().toDouble();
|
||||
if(ratio > 100.)
|
||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞"));
|
||||
else
|
||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -60,11 +60,13 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
||||
void displayFinishedHoSMenu(const QPoint&);
|
||||
void setRowColor(int row, QString color);
|
||||
void saveColWidthFinishedList() const;
|
||||
void loadLastSortedColumn();
|
||||
void toggleFinishedListSortOrder(int index);
|
||||
void sortFinishedList(int index=-1, Qt::SortOrder sortOrder=Qt::AscendingOrder);
|
||||
void sortFinishedListFloat(int index, Qt::SortOrder sortOrder);
|
||||
void sortFinishedListString(int index, Qt::SortOrder sortOrder);
|
||||
void updateFileSize(QString hash);
|
||||
void torrentAdded(QTorrentHandle& h);
|
||||
void on_actionSet_upload_limit_triggered();
|
||||
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
||||
void hideOrShowColumnName();
|
||||
@@ -72,16 +74,17 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
||||
void hideOrShowColumnUpSpeed();
|
||||
void hideOrShowColumnLeechers();
|
||||
void hideOrShowColumnRatio();
|
||||
void forceRecheck();
|
||||
void hideOrShowColumnPriority();
|
||||
|
||||
public slots:
|
||||
void addTorrent(QString hash);
|
||||
void updateTorrent(QTorrentHandle h);
|
||||
void updateFinishedList();
|
||||
void pauseTorrent(QString hash);
|
||||
void resumeTorrent(QString hash);
|
||||
void propertiesSelection();
|
||||
void deleteTorrent(QString hash);
|
||||
void showPropertiesFromHash(QString hash);
|
||||
void loadLastSortedColumn();
|
||||
void hidePriorityColumn(bool hide);
|
||||
|
||||
signals:
|
||||
void torrentMovedFromFinishedList(QString);
|
||||
|
563
src/GUI.cpp
563
src/GUI.cpp
File diff suppressed because it is too large
Load Diff
13
src/GUI.h
13
src/GUI.h
@@ -64,7 +64,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers;
|
||||
// GUI related
|
||||
QTabWidget *tabs;
|
||||
QPointer<options_imp> options;
|
||||
options_imp *options;
|
||||
QSystemTrayIcon *myTrayIcon;
|
||||
QPointer<QTimer> systrayCreator;
|
||||
QMenu *myTrayIconMenu;
|
||||
@@ -128,6 +128,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
void readSettings();
|
||||
void on_actionExit_triggered();
|
||||
void createTrayIcon();
|
||||
void updateUnfinishedTorrentNumberCalc();
|
||||
void updateFinishedTorrentNumberCalc();
|
||||
void updateUnfinishedTorrentNumber(unsigned int nb);
|
||||
void updateFinishedTorrentNumber(unsigned int nb);
|
||||
void fullDiskError(QTorrentHandle& h) const;
|
||||
@@ -156,16 +158,14 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
void processParams(const QStringList& params);
|
||||
void addTorrent(QString path);
|
||||
void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker);
|
||||
void processScannedFiles(const QStringList& params);
|
||||
void processDownloadedFiles(QString path, QString url);
|
||||
void downloadFromURLList(const QStringList& urls);
|
||||
void deleteTorrent(QString hash);
|
||||
void finishedTorrent(QTorrentHandle& h) const;
|
||||
void addedTorrent(QTorrentHandle& h) const;
|
||||
void checkedTorrent(QTorrentHandle& h) const;
|
||||
void pausedTorrent(QTorrentHandle& h) const;
|
||||
void resumedTorrent(QTorrentHandle& h) const;
|
||||
void updateLists(bool force=false);
|
||||
void updateLists();
|
||||
bool initWebUi(QString username, QString password, int port);
|
||||
void pauseTorrent(QString hash);
|
||||
void on_actionIncreasePriority_triggered();
|
||||
void on_actionDecreasePriority_triggered();
|
||||
// Options slots
|
||||
@@ -184,7 +184,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
void showEvent(QShowEvent *);
|
||||
bool event(QEvent * event);
|
||||
void displayRSSTab(bool enable);
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P
|
||||
Comment=V1.3.1
|
||||
Comment=V1.2.0
|
||||
Exec=qbittorrent %f
|
||||
GenericName=Bittorrent client
|
||||
GenericName[bg]=Торент клиент
|
||||
|
BIN
src/Icons/skin/connecting.png
Normal file
BIN
src/Icons/skin/connecting.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 576 B |
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
@@ -61,7 +61,7 @@ class about : public QDialog, private Ui::AboutDlg{
|
||||
- <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\
|
||||
- <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\
|
||||
- <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net) and Peter Koeleman (peter@peerweb.nl)<br>\
|
||||
- <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net) and Pekka Niemi (pekka.niemi@iki.fi)<br>\
|
||||
- <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net)<br>\
|
||||
- <u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\
|
||||
- <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\
|
||||
- <u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)<br>\
|
||||
@@ -76,7 +76,7 @@ class about : public QDialog, private Ui::AboutDlg{
|
||||
- <u>Slovak:</u> helix84<br>\
|
||||
- <u>Spanish:</u> Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net) and Gabriel de Oliveira (deadloop@hotmail.com)<br>\
|
||||
- <u>Swedish:</u> Daniel Nylander (po@danielnylander.se)<br>\
|
||||
- <u>Turkish:</u> Hasan YILMAZ (iletisim@hedefturkce.com) and Erdem Bingöl (erdem84@gmail.com)<br>\
|
||||
- <u>Turkish:</u> Erdem Bingöl (erdem84@gmail.com)<br>\
|
||||
- <u>Ukrainian:</u> Andrey Shpachenko (masterfix@users.sourceforge.net)<br><br>"));
|
||||
te_translation->append(tr("Please contact me if you would like to translate qBittorrent into your own language."));
|
||||
te_translation->scrollToAnchor(QString::fromUtf8("top"));
|
||||
|
@@ -13,6 +13,21 @@
|
||||
<string>Torrent addition dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="fileNameLbl" >
|
||||
<property name="text" >
|
||||
@@ -95,50 +110,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="collapseAllButton" >
|
||||
<property name="text" >
|
||||
<string>Collapse all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="expandAllButton" >
|
||||
<property name="text" >
|
||||
<string>Expand all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkIncrementalDL" >
|
||||
<property name="text" >
|
||||
|
@@ -32,7 +32,7 @@ class torrent_file {
|
||||
torrent_file *parent;
|
||||
bool is_dir;
|
||||
QString rel_path;
|
||||
QList<const torrent_file*> children;
|
||||
QList<torrent_file*> children;
|
||||
size_type size;
|
||||
float progress;
|
||||
int priority;
|
||||
@@ -68,7 +68,8 @@ class torrent_file {
|
||||
}
|
||||
float wanted = 0.;
|
||||
float done = 0.;
|
||||
foreach(const torrent_file *child, children) {
|
||||
torrent_file *child;
|
||||
foreach(child, children) {
|
||||
wanted += child->getSize();
|
||||
done += child->getSize()*child->getProgress();
|
||||
}
|
||||
@@ -79,7 +80,8 @@ class torrent_file {
|
||||
|
||||
void updatePriority(int prio) {
|
||||
Q_ASSERT(is_dir);
|
||||
foreach(const torrent_file *child, children) {
|
||||
torrent_file *child;
|
||||
foreach(child, children) {
|
||||
if(child->getPriority() != prio) return;
|
||||
}
|
||||
priority = prio;
|
||||
@@ -109,13 +111,14 @@ class torrent_file {
|
||||
return (!children.isEmpty());
|
||||
}
|
||||
|
||||
QList<const torrent_file*> getChildren() const {
|
||||
QList<torrent_file*> getChildren() const {
|
||||
return children;
|
||||
}
|
||||
|
||||
const torrent_file* getChild(QString fileName) const {
|
||||
torrent_file* getChild(QString fileName) const {
|
||||
Q_ASSERT(is_dir);
|
||||
foreach(const torrent_file *f, children) {
|
||||
torrent_file* f;
|
||||
foreach(f, children) {
|
||||
if(f->name() == fileName) return f;
|
||||
}
|
||||
return 0;
|
||||
@@ -138,15 +141,16 @@ class torrent_file {
|
||||
return f;
|
||||
}
|
||||
|
||||
bool removeFromFS(QString saveDir) const {
|
||||
bool removeFromFS(QString saveDir) {
|
||||
QString full_path = saveDir + QDir::separator() + rel_path;
|
||||
if(!QFile::exists(full_path)) {
|
||||
qDebug("%s does not exist, no need to remove it", full_path.toUtf8().data());
|
||||
return true;
|
||||
}
|
||||
bool success = true;
|
||||
torrent_file *f;
|
||||
qDebug("We have %d children", children.size());
|
||||
foreach(const torrent_file *f, children) {
|
||||
foreach(f, children) {
|
||||
bool s = f->removeFromFS(saveDir);
|
||||
success = s && success;
|
||||
}
|
||||
@@ -168,27 +172,27 @@ class arborescence {
|
||||
torrent_file *root;
|
||||
|
||||
public:
|
||||
arborescence(boost::intrusive_ptr<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);
|
||||
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);
|
||||
} 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 torrent_file(0, misc::toQString(t.name()), false, fi->size, 0);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
while(fi != t->end_files()) {
|
||||
while(fi != t.end_files()) {
|
||||
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
||||
addFile(path, fi->size, i);
|
||||
fi++;
|
||||
++i;
|
||||
}
|
||||
qDebug("real size: %ld, tree size: %ld", (long)t->total_size(), (long)root->getSize());
|
||||
Q_ASSERT(root->getSize() == t->total_size());
|
||||
qDebug("real size: %ld, tree size: %ld", (long)t.total_size(), (long)root->getSize());
|
||||
Q_ASSERT(root->getSize() == t.total_size());
|
||||
}
|
||||
|
||||
arborescence(torrent_info const& t, std::vector<size_type> fp, int *prioritiesTab) {
|
||||
arborescence(torrent_info t, std::vector<float> fp, int *prioritiesTab) {
|
||||
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");
|
||||
@@ -196,13 +200,13 @@ class arborescence {
|
||||
} 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, ((float)fp[0])/t.file_at(0).size, prioritiesTab[0]);
|
||||
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
while(fi != t.end_files()) {
|
||||
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
||||
addFile(path, fi->size, i, ((float)fp[i])/t.file_at(i).size, prioritiesTab[i]);
|
||||
addFile(path, fi->size, i, fp[i], prioritiesTab[i]);
|
||||
fi++;
|
||||
++i;
|
||||
}
|
||||
@@ -235,13 +239,14 @@ class arborescence {
|
||||
if(relative_path.at(0) ==QDir::separator())
|
||||
relative_path.remove(0, 1);
|
||||
QStringList fileNames = relative_path.split(QDir::separator());
|
||||
QString fileName;
|
||||
torrent_file *dad = root;
|
||||
unsigned int nb_i = 0;
|
||||
unsigned int size = fileNames.size();
|
||||
foreach(const QString &fileName, fileNames) {
|
||||
foreach(fileName, fileNames) {
|
||||
++nb_i;
|
||||
if(fileName == ".") continue;
|
||||
const torrent_file* child = dad->getChild(fileName);
|
||||
torrent_file* child = dad->getChild(fileName);
|
||||
if(!child) {
|
||||
if(nb_i != size) {
|
||||
// Folder
|
||||
@@ -251,7 +256,7 @@ class arborescence {
|
||||
child = dad->addChild(fileName, false, file_size, index, progress, priority);
|
||||
}
|
||||
}
|
||||
dad = (torrent_file*)child;
|
||||
dad = child;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
1567
src/bittorrent.cpp
1567
src/bittorrent.cpp
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,10 @@
|
||||
#define __BITTORRENT_H__
|
||||
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QStringList>
|
||||
#include <QDateTime>
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QPointer>
|
||||
@@ -34,9 +37,8 @@
|
||||
using namespace libtorrent;
|
||||
|
||||
class downloadThread;
|
||||
class deleteThread;
|
||||
class QTimer;
|
||||
class QFileSystemWatcher;
|
||||
class QMutex;
|
||||
class FilterParserThread;
|
||||
|
||||
class bittorrent : public QObject {
|
||||
@@ -44,16 +46,23 @@ class bittorrent : public QObject {
|
||||
|
||||
private:
|
||||
session *s;
|
||||
QPointer<QFileSystemWatcher> FSWatcher;
|
||||
QMutex* FSMutex;
|
||||
QPointer<QTimer> timerAlerts;
|
||||
QString scan_dir;
|
||||
QPointer<QTimer> timerScan;
|
||||
QTimer *timerAlerts;
|
||||
QTimer *fastResumeSaver;
|
||||
QPointer<QTimer> BigRatioTimer;
|
||||
bool DHTEnabled;
|
||||
QPointer<downloadThread> downloader;
|
||||
downloadThread *downloader;
|
||||
QString defaultSavePath;
|
||||
QHash<QString, QDateTime> TorrentsStartTime;
|
||||
QHash<QString, size_type> TorrentsStartData;
|
||||
QHash<QString, QPair<size_type,size_type> > ratioData;
|
||||
QHash<QString, QHash<QString, QString> > trackersErrors;
|
||||
QStringList consoleMessages;
|
||||
QStringList peerBanMessages;
|
||||
deleteThread *deleter;
|
||||
QStringList finishedTorrents;
|
||||
QStringList unfinishedTorrents;
|
||||
bool preAllocateAll;
|
||||
bool addInPause;
|
||||
int maxConnecsPerTorrent;
|
||||
@@ -64,7 +73,16 @@ class bittorrent : public QObject {
|
||||
bool LSDEnabled;
|
||||
QPointer<FilterParserThread> filterParser;
|
||||
QString filterPath;
|
||||
int folderScanInterval; // in seconds
|
||||
bool queueingEnabled;
|
||||
int maxActiveDownloads;
|
||||
int maxActiveTorrents;
|
||||
int currentActiveDownloads;
|
||||
QStringList *downloadQueue;
|
||||
QStringList *queuedDownloads;
|
||||
QStringList *uploadQueue;
|
||||
QStringList *queuedUploads;
|
||||
bool calculateETA;
|
||||
QStringList url_skippingDlg;
|
||||
|
||||
protected:
|
||||
@@ -75,16 +93,20 @@ class bittorrent : public QObject {
|
||||
bittorrent();
|
||||
~bittorrent();
|
||||
QTorrentHandle getTorrentHandle(QString hash) const;
|
||||
std::vector<torrent_handle> getTorrents() const;
|
||||
bool isPaused(QString hash) const;
|
||||
bool isFilePreviewPossible(QString fileHash) const;
|
||||
bool isDHTEnabled() const;
|
||||
float getPayloadDownloadRate() const;
|
||||
float getPayloadUploadRate() const;
|
||||
session_status getSessionStatus() const;
|
||||
int getListenPort() const;
|
||||
qlonglong getETA(QString hash) const;
|
||||
float getRealRatio(QString hash) const;
|
||||
session* getSession() const;
|
||||
QHash<QString, QString> getTrackersErrors(QString hash) const;
|
||||
QStringList getFinishedTorrents() const;
|
||||
QStringList getUnfinishedTorrents() const;
|
||||
bool isFinished(QString hash) const;
|
||||
bool has_filtered_files(QString hash) const;
|
||||
unsigned int getFinishedPausedTorrentsNb() const;
|
||||
unsigned int getUnfinishedPausedTorrentsNb() const;
|
||||
@@ -93,40 +115,46 @@ class bittorrent : public QObject {
|
||||
int getUpTorrentPriority(QString hash) const;
|
||||
int getMaximumActiveDownloads() const;
|
||||
int getMaximumActiveTorrents() const;
|
||||
bool isDownloadQueued(QString hash) const;
|
||||
bool isUploadQueued(QString hash) const;
|
||||
int loadTorrentPriority(QString hash);
|
||||
QStringList getConsoleMessages() const;
|
||||
QStringList getPeerBanMessages() const;
|
||||
qlonglong getETA(QString hash) const;
|
||||
float getUncheckedTorrentProgress(QString hash) const;
|
||||
|
||||
public slots:
|
||||
QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
||||
void loadSessionState();
|
||||
void saveSessionState();
|
||||
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
||||
void downloadFromUrl(QString url);
|
||||
void downloadFromURLList(const QStringList& url_list);
|
||||
void deleteTorrent(QString hash, bool permanent = false);
|
||||
/* Needed by Web UI */
|
||||
bool pauseTorrent(QString hash);
|
||||
bool resumeTorrent(QString hash);
|
||||
void pauseAllTorrents();
|
||||
void resumeAllTorrents();
|
||||
void pauseTorrent(QString hash);
|
||||
void resumeTorrent(QString hash);
|
||||
/* End Web UI */
|
||||
void saveDHTEntry();
|
||||
void preAllocateAllFiles(bool b);
|
||||
void saveFastResumeData();
|
||||
void saveFastResumeAndRatioData();
|
||||
void saveFastResumeAndRatioData(QString hash);
|
||||
void enableDirectoryScanning(QString scan_dir);
|
||||
void disableDirectoryScanning();
|
||||
void enablePeerExchange();
|
||||
void enableIPFilter(QString filter);
|
||||
void disableIPFilter();
|
||||
void setQueueingEnabled(bool enable);
|
||||
void resumeUnfinishedTorrents();
|
||||
void saveTorrentPriority(QString hash, int prio);
|
||||
void saveTorrentSpeedLimits(QString hash);
|
||||
void loadTorrentSpeedLimits(QString hash);
|
||||
void saveDownloadUploadForTorrent(QString hash);
|
||||
void loadDownloadUploadForTorrent(QString hash);
|
||||
void handleDownloadFailure(QString url, QString reason);
|
||||
void loadWebSeeds(QString fileHash);
|
||||
void updateDownloadQueue();
|
||||
void updateUploadQueue();
|
||||
void increaseDlTorrentPriority(QString hash);
|
||||
void decreaseDlTorrentPriority(QString hash);
|
||||
void increaseUpTorrentPriority(QString hash);
|
||||
void decreaseUpTorrentPriority(QString hash);
|
||||
void saveTorrentPriority(QString hash, int prio);
|
||||
void downloadUrlAndSkipDialog(QString);
|
||||
// Session configuration - Setters
|
||||
void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports);
|
||||
@@ -146,15 +174,22 @@ class bittorrent : public QObject {
|
||||
void loadFilesPriorities(QTorrentHandle& h);
|
||||
void setDownloadLimit(QString hash, long val);
|
||||
void setUploadLimit(QString hash, long val);
|
||||
void setUnfinishedTorrent(QString hash);
|
||||
void setFinishedTorrent(QString hash);
|
||||
void enableUPnP(bool b);
|
||||
void enableNATPMP(bool b);
|
||||
void enableLSD(bool b);
|
||||
bool enableDHT(bool b);
|
||||
void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
|
||||
void setTimerScanInterval(int secs);
|
||||
void setMaxActiveDownloads(int val);
|
||||
void setMaxActiveTorrents(int val);
|
||||
void setETACalculation(bool enable);
|
||||
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
||||
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
||||
|
||||
protected slots:
|
||||
void scanDirectory(QString);
|
||||
void scanDirectory();
|
||||
void readAlerts();
|
||||
void processDownloadedFile(QString, QString);
|
||||
bool loadTrackerFile(QString hash);
|
||||
@@ -162,18 +197,33 @@ class bittorrent : public QObject {
|
||||
void deleteBigRatios();
|
||||
|
||||
signals:
|
||||
//void invalidTorrent(QString path);
|
||||
//void duplicateTorrent(QString path);
|
||||
void addedTorrent(QTorrentHandle& h);
|
||||
void deletedTorrent(QString hash);
|
||||
void pausedTorrent(QTorrentHandle& h);
|
||||
void resumedTorrent(QTorrentHandle& h);
|
||||
void pausedTorrent(QString hash);
|
||||
void resumedTorrent(QString hash);
|
||||
void finishedTorrent(QTorrentHandle& h);
|
||||
void fullDiskError(QTorrentHandle& h);
|
||||
void trackerError(QString hash, QString time, QString msg);
|
||||
//void portListeningFailure();
|
||||
void trackerAuthenticationRequired(QTorrentHandle& h);
|
||||
void scanDirFoundTorrents(const QStringList& pathList);
|
||||
void newDownloadedTorrent(QString path, QString url);
|
||||
//void aboutToDownloadFromUrl(QString url);
|
||||
void updateFileSize(QString hash);
|
||||
//void peerBlocked(QString);
|
||||
void downloadFromUrlFailure(QString url, QString reason);
|
||||
void torrentFinishedChecking(QTorrentHandle& h);
|
||||
//void fastResumeDataRejected(QString name);
|
||||
//void urlSeedProblem(QString url, QString msg);
|
||||
//void torrentFinishedChecking(QString hash);
|
||||
//void torrent_ratio_deleted(QString fileName);
|
||||
//void UPnPError(QString msg);
|
||||
//void UPnPSuccess(QString msg);
|
||||
void updateFinishedTorrentNumber();
|
||||
void updateUnfinishedTorrentNumber();
|
||||
void forceUnfinishedListUpdate();
|
||||
void forceFinishedListUpdate();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <libtorrent/entry.hpp>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
@@ -35,7 +34,6 @@
|
||||
#include <libtorrent/storage.hpp>
|
||||
#include <libtorrent/hasher.hpp>
|
||||
#include <libtorrent/file_pool.hpp>
|
||||
#include <libtorrent/create_torrent.hpp>
|
||||
|
||||
#include "createtorrent_imp.h"
|
||||
#include "misc.h"
|
||||
@@ -43,23 +41,13 @@
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
// do not include files and folders whose
|
||||
// name starts with a .
|
||||
bool file_filter(boost::filesystem::path const& filename)
|
||||
{
|
||||
if (filename.leaf()[0] == '.') return false;
|
||||
std::cerr << filename << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
createtorrent::createtorrent(QWidget *parent): QDialog(parent){
|
||||
setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
creatorThread = new torrentCreatorThread(this);
|
||||
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*)), this, SLOT(handleCreationSuccess(QString, const char*)));
|
||||
creatorThread = new torrentCreatorThread();
|
||||
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*, QString)), this, SLOT(handleCreationSuccess(QString, const char*, QString)));
|
||||
connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString)));
|
||||
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
|
||||
path::default_name_check(no_check);
|
||||
show();
|
||||
}
|
||||
|
||||
@@ -138,6 +126,31 @@ 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){
|
||||
using boost::filesystem::path;
|
||||
using boost::filesystem::directory_iterator;
|
||||
#if BOOST_VERSION < 103600
|
||||
std::string const& leaf = l.leaf();
|
||||
#else
|
||||
std::string const& leaf = l.filename();
|
||||
#endif
|
||||
if (leaf == ".." || leaf == ".") return;
|
||||
path f(p / l);
|
||||
if (is_directory(f)) {
|
||||
for (directory_iterator i(f), end; i != end; ++i)
|
||||
#if BOOST_VERSION < 103600
|
||||
add_files(t, p, l / i->leaf());
|
||||
#else
|
||||
add_files(t, p, l / i->filename());
|
||||
#endif
|
||||
} else {
|
||||
qDebug("Adding %s", l.string().c_str());
|
||||
t.add_file(l, file_size(f));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList createtorrent::allItems(QListWidget *list){
|
||||
QStringList res;
|
||||
unsigned int nbItems = list->count();
|
||||
@@ -178,25 +191,17 @@ void createtorrent::handleCreationFailure(QString msg) {
|
||||
hide();
|
||||
}
|
||||
|
||||
void createtorrent::handleCreationSuccess(QString path, const char* branch_path) {
|
||||
if(checkStartSeeding->isChecked()) {
|
||||
// Create save path file
|
||||
boost::intrusive_ptr<torrent_info> t;
|
||||
try {
|
||||
t = new torrent_info(path.toUtf8().data());
|
||||
} catch(std::exception&) {
|
||||
QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list."));
|
||||
return;
|
||||
}
|
||||
QString hash = misc::toQString(t->info_hash());
|
||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
savepath_file.write(branch_path);
|
||||
savepath_file.close();
|
||||
emit torrent_to_seed(path);
|
||||
}
|
||||
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
|
||||
hide();
|
||||
void createtorrent::handleCreationSuccess(QString path, const char* branch_path, QString hash) {
|
||||
if(checkStartSeeding->isChecked()) {
|
||||
// Create save path file
|
||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
savepath_file.write(branch_path);
|
||||
savepath_file.close();
|
||||
emit torrent_to_seed(path);
|
||||
}
|
||||
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
|
||||
hide();
|
||||
}
|
||||
|
||||
void createtorrent::updateProgressBar(int progress) {
|
||||
@@ -219,47 +224,58 @@ void torrentCreatorThread::create(QString _input_path, QString _save_path, QStri
|
||||
start();
|
||||
}
|
||||
|
||||
void sendProgressUpdateSignal(int i, int num, QDialog *parent){
|
||||
((createtorrent*)parent)->updateProgressBar((int)(i*100./(float)num));
|
||||
}
|
||||
|
||||
void torrentCreatorThread::run() {
|
||||
emit updateProgress(0);
|
||||
char const* creator_str = "qBittorrent "VERSION;
|
||||
try {
|
||||
file_storage fs;
|
||||
file_pool fp;
|
||||
path full_path = complete(path(input_path.toUtf8().data()));
|
||||
boost::intrusive_ptr<torrent_info> t(new torrent_info);
|
||||
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
|
||||
// Adding files to the torrent
|
||||
add_files(fs, full_path, file_filter);
|
||||
path full_path = complete(path(input_path.toUtf8().data()));
|
||||
#if BOOST_VERSION < 103600
|
||||
add_files(*t, full_path.branch_path(), full_path.leaf());
|
||||
#else
|
||||
add_files(*t, full_path.branch_path(), full_path.filename());
|
||||
#endif
|
||||
if(abort) return;
|
||||
create_torrent t(fs, piece_size);
|
||||
|
||||
// Set piece size
|
||||
t->set_piece_size(piece_size);
|
||||
// Add url seeds
|
||||
QString seed;
|
||||
foreach(seed, url_seeds){
|
||||
t.add_url_seed(seed.toUtf8().data());
|
||||
t->add_url_seed(seed.toUtf8().data());
|
||||
}
|
||||
for(int i=0; i<trackers.size(); ++i){
|
||||
t.add_tracker(trackers.at(i).toUtf8().data());
|
||||
t->add_tracker(trackers.at(i).toUtf8().data());
|
||||
}
|
||||
if(abort) return;
|
||||
// calculate the hash for all pieces
|
||||
set_piece_hashes(t, full_path.branch_path(), boost::bind<void>(&sendProgressUpdateSignal, _1, t.num_pieces(), parent));
|
||||
file_pool fp;
|
||||
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp));
|
||||
int num = t->num_pieces();
|
||||
std::vector<char> buf(piece_size);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
st->read(&buf[0], i, 0, t->piece_size(i));
|
||||
hasher h(&buf[0], t->piece_size(i));
|
||||
t->set_hash(i, h.final());
|
||||
emit updateProgress((int)(i*100./(float)num));
|
||||
if(abort) return;
|
||||
}
|
||||
// Set qBittorrent as creator and add user comment to
|
||||
// torrent_info structure
|
||||
t.set_creator(creator_str);
|
||||
t.set_comment((const char*)comment.toUtf8());
|
||||
t->set_creator(creator_str);
|
||||
t->set_comment((const char*)comment.toUtf8());
|
||||
// Is private ?
|
||||
if(is_private){
|
||||
t.set_priv(true);
|
||||
t->set_priv(true);
|
||||
}
|
||||
if(abort) return;
|
||||
// create the torrent and print it to out
|
||||
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
|
||||
bencode(std::ostream_iterator<char>(out), t.generate());
|
||||
entry e = t->create_torrent();
|
||||
libtorrent::bencode(std::ostream_iterator<char>(out), e);
|
||||
out.flush();
|
||||
emit updateProgress(100);
|
||||
emit creationSuccess(save_path, full_path.branch_path().string().c_str());
|
||||
emit creationSuccess(save_path, full_path.branch_path().string().c_str(), misc::toQString(t->info_hash()));
|
||||
}
|
||||
catch (std::exception& e){
|
||||
emit creationFailure(QString::fromUtf8(e.what()));
|
||||
|
@@ -37,12 +37,9 @@ class torrentCreatorThread : public QThread {
|
||||
bool is_private;
|
||||
int piece_size;
|
||||
bool abort;
|
||||
QDialog *parent;
|
||||
|
||||
public:
|
||||
torrentCreatorThread(QDialog *_parent) {
|
||||
parent = _parent;
|
||||
}
|
||||
torrentCreatorThread() {}
|
||||
~torrentCreatorThread() {
|
||||
abort = true;
|
||||
wait();
|
||||
@@ -54,7 +51,7 @@ class torrentCreatorThread : public QThread {
|
||||
|
||||
signals:
|
||||
void creationFailure(QString msg);
|
||||
void creationSuccess(QString path, const char* branch_path);
|
||||
void creationSuccess(QString path, const char* branch_path, QString hash);
|
||||
void updateProgress(int progress);
|
||||
};
|
||||
|
||||
@@ -73,9 +70,6 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
|
||||
signals:
|
||||
void torrent_to_seed(QString path);
|
||||
|
||||
public slots:
|
||||
void updateProgressBar(int progress);
|
||||
|
||||
protected slots:
|
||||
void on_createButton_clicked();
|
||||
void on_addFile_button_clicked();
|
||||
@@ -85,7 +79,8 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
|
||||
void on_addURLSeed_button_clicked();
|
||||
void on_removeURLSeed_button_clicked();
|
||||
void handleCreationFailure(QString msg);
|
||||
void handleCreationSuccess(QString path, const char* branch_path);
|
||||
void handleCreationSuccess(QString path, const char* branch_path, QString hash);
|
||||
void updateProgressBar(int progress);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
128
src/deleteThread.h
Normal file
128
src/deleteThread.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2006 Christophe Dumez
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#ifndef DELETETHREAD_H
|
||||
#define DELETETHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QMutexLocker>
|
||||
#include <QPair>
|
||||
|
||||
#include "arborescence.h"
|
||||
|
||||
class subDeleteThread : public QThread {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QString save_path;
|
||||
arborescence *arb;
|
||||
|
||||
public:
|
||||
subDeleteThread(QObject *parent, QString saveDir, arborescence *_arb) : QThread(parent), save_path(saveDir) {
|
||||
arb = _arb;
|
||||
}
|
||||
|
||||
~subDeleteThread(){
|
||||
qDebug("subDeleteThread successfuly deleted");
|
||||
//wait();
|
||||
}
|
||||
|
||||
signals:
|
||||
// For subthreads
|
||||
void deletionSuccessST(subDeleteThread* st);
|
||||
//void deletionFailureST(subDeleteThread* st);
|
||||
|
||||
protected:
|
||||
void run(){
|
||||
/*if(arb->removeFromFS(save_path))
|
||||
emit deletionSuccessST(this);
|
||||
else
|
||||
emit deletionFailureST(this);*/
|
||||
arb->removeFromFS(save_path);
|
||||
emit deletionSuccessST(this);
|
||||
delete arb;
|
||||
}
|
||||
};
|
||||
|
||||
class deleteThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QList<QPair<QString, arborescence*> > torrents_list;
|
||||
QMutex mutex;
|
||||
QWaitCondition condition;
|
||||
bool abort;
|
||||
QList<subDeleteThread*> subThreads;
|
||||
|
||||
public:
|
||||
deleteThread(QObject* parent) : QThread(parent), abort(false){}
|
||||
|
||||
~deleteThread(){
|
||||
mutex.lock();
|
||||
abort = true;
|
||||
condition.wakeOne();
|
||||
mutex.unlock();
|
||||
qDeleteAll(subThreads);
|
||||
wait();
|
||||
}
|
||||
|
||||
void deleteTorrent(QString saveDir, arborescence *arb){
|
||||
qDebug("deleteThread called");
|
||||
QMutexLocker locker(&mutex);
|
||||
torrents_list << QPair<QString, arborescence*>(saveDir, arb);
|
||||
if(!isRunning()){
|
||||
start();
|
||||
}else{
|
||||
condition.wakeOne();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void run(){
|
||||
forever{
|
||||
if(abort)
|
||||
return;
|
||||
mutex.lock();
|
||||
if(!torrents_list.empty()){
|
||||
QPair<QString, arborescence *> torrent = torrents_list.takeFirst();
|
||||
mutex.unlock();
|
||||
subDeleteThread *st = new subDeleteThread(0, torrent.first, torrent.second);
|
||||
subThreads << st;
|
||||
connect(st, SIGNAL(deletionSuccessST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
|
||||
//connect(st, SIGNAL(deletionFailureST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
|
||||
st->start();
|
||||
}else{
|
||||
condition.wait(&mutex);
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected slots:
|
||||
void deleteSubThread(subDeleteThread* st){
|
||||
int index = subThreads.indexOf(st);
|
||||
Q_ASSERT(index != -1);
|
||||
subThreads.removeAt(index);
|
||||
delete st;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@@ -18,7 +18,16 @@
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<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>
|
||||
@@ -91,8 +100,7 @@
|
||||
</action>
|
||||
<action name="actionOpen_destination_folder" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/folder.png</normaloff>:/Icons/folder.png</iconset>
|
||||
<iconset resource="icons.qrc" >:/Icons/folder.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Open destination folder</string>
|
||||
@@ -140,8 +148,7 @@
|
||||
</action>
|
||||
<action name="actionBuy_it" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/money.png</normaloff>:/Icons/money.png</iconset>
|
||||
<iconset resource="icons.qrc" >:/Icons/money.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Buy it</string>
|
||||
@@ -154,8 +161,7 @@
|
||||
</action>
|
||||
<action name="actionIncreasePriority" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/skin/increase.png</normaloff>:/Icons/skin/increase.png</iconset>
|
||||
<iconset resource="icons.qrc" >:/Icons/skin/increase.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Increase priority</string>
|
||||
@@ -163,22 +169,12 @@
|
||||
</action>
|
||||
<action name="actionDecreasePriority" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/skin/decrease.png</normaloff>:/Icons/skin/decrease.png</iconset>
|
||||
<iconset resource="icons.qrc" >:/Icons/skin/decrease.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Decrease priority</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionForce_recheck" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/gear.png</normaloff>:/Icons/gear.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Force recheck</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="icons.qrc" />
|
||||
|
@@ -81,7 +81,7 @@ void subDownloadThread::run(){
|
||||
return;
|
||||
}
|
||||
CURL *curl;
|
||||
CURLcode res = (CURLcode)-1;
|
||||
CURLcode res;
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
std::string c_url = url.toUtf8().data();
|
||||
@@ -91,11 +91,11 @@ void subDownloadThread::run(){
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
// PROXY SUPPORT
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
int intValue = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxyType"), 0).toInt();
|
||||
int intValue = settings.value(QString::fromUtf8("Preferences/Connection/ProxyType"), 0).toInt();
|
||||
if(intValue > 0) {
|
||||
// Proxy enabled
|
||||
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString();
|
||||
QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString();
|
||||
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
|
||||
@@ -106,8 +106,8 @@ void subDownloadThread::run(){
|
||||
// Authentication?
|
||||
if(intValue > 2) {
|
||||
qDebug("Proxy requires authentication, authenticating");
|
||||
QString username = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Username"), QString()).toString();
|
||||
QString password = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Password"), QString()).toString();
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -123,13 +123,10 @@ void subDownloadThread::run(){
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1);
|
||||
qDebug("Downloading %s", url.toUtf8().data());
|
||||
if(!abort)
|
||||
res = curl_easy_perform(curl);
|
||||
res = curl_easy_perform(curl);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(f);
|
||||
if(abort)
|
||||
return;
|
||||
if(res) {
|
||||
emit downloadFailureST(this, url, errorCodeToString(res));
|
||||
} else {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -58,6 +58,7 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
||||
signals:
|
||||
void unfinishedTorrentsNumberChanged(unsigned int);
|
||||
void torrentDoubleClicked(QString hash, bool finished);
|
||||
void torrentFinished(QString hash);
|
||||
|
||||
protected slots:
|
||||
void on_actionSet_download_limit_triggered();
|
||||
@@ -65,11 +66,13 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
||||
void on_actionSet_upload_limit_triggered();
|
||||
void displayDLListMenu(const QPoint& pos);
|
||||
void displayDLHoSMenu(const QPoint&);
|
||||
void addTorrent(QString hash);
|
||||
void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder);
|
||||
void toggleDownloadListSortOrder(int index);
|
||||
void sortDownloadListFloat(int index, Qt::SortOrder sortOrder);
|
||||
void sortDownloadListString(int index, Qt::SortOrder sortOrder);
|
||||
void saveColWidthDLList() const;
|
||||
void torrentAdded(QTorrentHandle& h);
|
||||
void setRowColor(int row, QColor color);
|
||||
void showProperties(const QModelIndex &index);
|
||||
void hideOrShowColumnName();
|
||||
@@ -81,19 +84,17 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
||||
void hideOrShowColumnRatio();
|
||||
void hideOrShowColumnEta();
|
||||
void hideOrShowColumnPriority();
|
||||
void forceRecheck();
|
||||
void loadLastSortedColumn();
|
||||
|
||||
public slots:
|
||||
bool updateTorrent(QTorrentHandle h);
|
||||
void updateDlList();
|
||||
void pauseTorrent(QString hash);
|
||||
void resumeTorrent(QString hash);
|
||||
void deleteTorrent(QString hash);
|
||||
void propertiesSelection();
|
||||
void updateFileSizeAndProgress(QString hash);
|
||||
void showPropertiesFromHash(QString hash);
|
||||
void hidePriorityColumn(bool hide);
|
||||
void sortProgressColumn(QTorrentHandle& h);
|
||||
void loadLastSortedColumn();
|
||||
void addTorrent(QString hash);
|
||||
|
||||
};
|
||||
|
||||
|
@@ -32,6 +32,11 @@
|
||||
#include <QDropEvent>
|
||||
#include <QInputDialog>
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
#include <Magick++.h>
|
||||
using namespace Magick;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZZIP
|
||||
#include <zzip/zzip.h>
|
||||
#endif
|
||||
@@ -606,6 +611,20 @@ void engineSelectDlg::processDownloadedFile(QString url, QString filePath) {
|
||||
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
|
||||
// Icon downloaded
|
||||
QImage fileIcon;
|
||||
#ifdef HAVE_MAGICK
|
||||
try{
|
||||
QFile::copy(filePath, filePath+".ico");
|
||||
Image image(QDir::cleanPath(filePath+".ico").toUtf8().data());
|
||||
// Convert to PNG since we can't read ICO format
|
||||
image.magick("PNG");
|
||||
// Resize to 16x16px
|
||||
image.sample(Geometry(16, 16));
|
||||
image.write(filePath.toUtf8().data());
|
||||
QFile::remove(filePath+".ico");
|
||||
}catch(Magick::Exception &error_){
|
||||
qDebug("favicon conversion to PNG failure: %s", error_.what());
|
||||
}
|
||||
#endif
|
||||
if(fileIcon.load(filePath)) {
|
||||
QList<QTreeWidgetItem*> items = findItemsWithUrl(url);
|
||||
QTreeWidgetItem *item;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora & Christophe Dumez
|
||||
* <ishan@qbittorrent.org>, <chris@qbittorrent.org>
|
||||
* Copyright (C) 2007 by Ishan Arora
|
||||
* ishanarora@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,75 +21,169 @@
|
||||
|
||||
#include "eventmanager.h"
|
||||
#include "bittorrent.h"
|
||||
#include "json.h"
|
||||
#include <QDebug>
|
||||
|
||||
EventManager::EventManager(QObject *parent, bittorrent *BTSession)
|
||||
: QObject(parent), BTSession(BTSession)
|
||||
{
|
||||
revision = 0;
|
||||
}
|
||||
|
||||
QList<QVariantMap> EventManager::getEventList() const {
|
||||
return event_list.values();
|
||||
void EventManager::update(QVariantMap event)
|
||||
{
|
||||
++revision;
|
||||
events << QPair<ulong, QVariantMap>(revision, event);
|
||||
emit updated();
|
||||
//qDebug("Added the following event");
|
||||
//qDebug() << event;
|
||||
/* QLinkedList<QPair<ulong, QVariantMap> >::iterator i;
|
||||
for (i = events.begin(); i != events.end(); i++)
|
||||
qDebug() << *i;*/
|
||||
}
|
||||
|
||||
QVariant EventManager::querySince(ulong r) const
|
||||
{
|
||||
QVariantList list;
|
||||
QLinkedListIterator<QPair<ulong, QVariantMap> > i(events);
|
||||
i.toBack();
|
||||
while (i.hasPrevious())
|
||||
{
|
||||
QPair<ulong, QVariantMap> pair = i.previous();
|
||||
if (pair.first <= r)
|
||||
break;
|
||||
list.prepend(QVariant(pair.second));
|
||||
}
|
||||
QVariantMap map;
|
||||
map["events"] = QVariant(list);
|
||||
map["revision"] = QVariant((qulonglong) revision);
|
||||
return QVariant(map);
|
||||
}
|
||||
|
||||
bool EventManager::isUpdated(ulong r) const
|
||||
{
|
||||
return (r < revision);
|
||||
}
|
||||
|
||||
void EventManager::addedTorrent(QTorrentHandle& h)
|
||||
{
|
||||
modifiedTorrent(h);
|
||||
QVariantMap event;
|
||||
event["type"] = QVariant("add");
|
||||
event["hash"] = QVariant(h.hash());
|
||||
event["name"] = QVariant(h.name());
|
||||
update(event);
|
||||
}
|
||||
|
||||
void EventManager::deletedTorrent(QString hash)
|
||||
{
|
||||
event_list.remove(hash);
|
||||
QVariantMap event;
|
||||
event["type"] = QVariant("delete");
|
||||
event["hash"] = QVariant(hash);
|
||||
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
|
||||
bool loop = true;
|
||||
while (loop && i != events.begin()) {
|
||||
--i;
|
||||
QVariantMap oldevent = i->second;
|
||||
if(oldevent["hash"] == QVariant(hash))
|
||||
{
|
||||
if(oldevent["type"] == QVariant("add"))
|
||||
loop = false;
|
||||
i = events.erase(i);
|
||||
}
|
||||
}
|
||||
update(event);
|
||||
}
|
||||
|
||||
void EventManager::modifiedTorrent(QTorrentHandle h)
|
||||
{
|
||||
QString hash = h.hash();
|
||||
QVariantMap event;
|
||||
|
||||
if(h.is_paused()) {
|
||||
event["state"] = QVariant("paused");
|
||||
} else {
|
||||
if(BTSession->isQueueingEnabled() && h.is_queued()) {
|
||||
event["state"] = QVariant("queued");
|
||||
} else {
|
||||
switch(h.state())
|
||||
{
|
||||
case torrent_status::finished:
|
||||
case torrent_status::seeding:
|
||||
event["state"] = QVariant("seeding");
|
||||
break;
|
||||
case torrent_status::checking_files:
|
||||
case torrent_status::queued_for_checking:
|
||||
event["state"] = QVariant("checking");
|
||||
break;
|
||||
case torrent_status::allocating:
|
||||
case torrent_status::downloading:
|
||||
case torrent_status::downloading_metadata:
|
||||
if(h.download_payload_rate() > 0)
|
||||
event["state"] = QVariant("downloading");
|
||||
else
|
||||
event["state"] = QVariant("stalled");
|
||||
break;
|
||||
default:
|
||||
qDebug("No status, should not happen!!! status is %d", h.state());
|
||||
event["state"] = QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
event["name"] = QVariant(h.name());
|
||||
event["size"] = QVariant((qlonglong)h.actual_size());
|
||||
if(!h.is_seed()) {
|
||||
event["progress"] = QVariant(h.progress());
|
||||
event["dlspeed"] = QVariant(h.download_payload_rate());
|
||||
if(BTSession->isQueueingEnabled()) {
|
||||
event["priority"] = QVariant(h.queue_position());
|
||||
} else {
|
||||
event["priority"] = -1;
|
||||
}
|
||||
QString hash = h.hash();
|
||||
QVariantMap event;
|
||||
QVariant v;
|
||||
|
||||
if(h.is_paused()) {
|
||||
if(BTSession->isDownloadQueued(hash) || BTSession->isUploadQueued(hash))
|
||||
v = QVariant("queued");
|
||||
else
|
||||
v = QVariant("paused");
|
||||
} else {
|
||||
switch(h.state())
|
||||
{
|
||||
case torrent_status::finished:
|
||||
case torrent_status::seeding:
|
||||
v = QVariant("seeding");
|
||||
break;
|
||||
case torrent_status::checking_files:
|
||||
case torrent_status::queued_for_checking:
|
||||
v = QVariant("checking");
|
||||
break;
|
||||
case torrent_status::connecting_to_tracker:
|
||||
if(h.download_payload_rate() > 0)
|
||||
v = QVariant("downloading");
|
||||
else
|
||||
v = QVariant("connecting");
|
||||
break;
|
||||
case torrent_status::downloading:
|
||||
case torrent_status::downloading_metadata:
|
||||
if(h.download_payload_rate() > 0)
|
||||
v = QVariant("downloading");
|
||||
else
|
||||
v = QVariant("stalled");
|
||||
break;
|
||||
default:
|
||||
v = QVariant();
|
||||
}
|
||||
}
|
||||
if(modify(hash, "state", v))
|
||||
event["state"] = v;
|
||||
|
||||
v = QVariant((qlonglong)h.actual_size());
|
||||
if(modify(hash, "size", v))
|
||||
event["size"] = v;
|
||||
|
||||
v = QVariant(h.progress());
|
||||
if(modify(hash, "progress", v))
|
||||
event["progress"] = v;
|
||||
|
||||
v = QVariant(h.download_payload_rate());
|
||||
if(modify(hash, "dlspeed", v))
|
||||
event["dlspeed"] = v;
|
||||
|
||||
v = QVariant(h.upload_payload_rate());
|
||||
if(modify(hash, "upspeed", v))
|
||||
event["upspeed"] = v;
|
||||
|
||||
if(event.size() > 0)
|
||||
{
|
||||
event["type"] = QVariant("modify");
|
||||
event["hash"] = QVariant(hash);
|
||||
update(event);
|
||||
}
|
||||
event["upspeed"] = QVariant(h.upload_payload_rate());
|
||||
event["seed"] = QVariant(h.is_seed());
|
||||
event["hash"] = QVariant(hash);
|
||||
event_list[hash] = event;
|
||||
}
|
||||
|
||||
bool EventManager::modify(QString hash, QString key, QVariant value)
|
||||
{
|
||||
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
|
||||
while (i != events.begin()) {
|
||||
--i;
|
||||
QVariantMap event = i->second;
|
||||
if(event["hash"] == QVariant(hash))
|
||||
{
|
||||
if(event["type"] == QVariant("add"))
|
||||
return true;
|
||||
if(event.contains(key))
|
||||
{
|
||||
if(event[key] == value)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if(event.size() <= 3)
|
||||
i = events.erase(i);
|
||||
else
|
||||
i->second.remove(key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user