Compare commits

..

1 Commits

Author SHA1 Message Date
Christophe Dumez
ec1521c2ca - tagged v1.2.0beta3 release 2008-08-17 04:00:52 +00:00
232 changed files with 33030 additions and 40681 deletions

23
AUTHORS
View File

@@ -6,35 +6,24 @@ Contributors:
* Ishan Arora <ishan@qbittorrent.org> * Ishan Arora <ishan@qbittorrent.org>
* Grigis Gaëtan <cipher16@gmail.com> * 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: Images Authors:
* files: src/Icons/*.png * files: src/Icons/*.png
copyright: Gnome Icon Theme copyright: Gnome Icon Theme
license: GPLv2 license: GPLv2
url: http://ftp.acc.umu.se/pub/GNOME/sources/gnome-icon-theme url: http://ftp.acc.umu.se/pub/GNOME/sources/gnome-icon-theme
* files: src/oxygen/*.png
copyright: Oxygen Icon Theme (KDE)
license: LGPL
url: http://www.oxygen-icons.org
* files: src/Icons/flags/*.png * files: src/Icons/flags/*.png
copyright: Open Clip Art Library copyright: Open Clip Art Library
license: Creative Commons Public Domain Dedication license: Creative Commons Public Domain Dedication
url: http://www.openclipart.org url: http://www.openclipart.org
* files: src/Icons/skin/*.png * files: src/Icons/skins/*.png
files: src/menuicons/YYxYY/*.png
copyright: Mateusz Tobola <tobejodok@qbittorrent.org> copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
license: GPLv2 license: GPLv2
* file: src/Icons/skin/tabs.gif * files: src/menuicons/YYxYY/*.png
copyright: Greg Houston <gregory.houston@gmail.com> copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
license: MIT license: GPLv2
* file: src/search_engine/engines/btjunkie.png * file: src/search_engine/engines/btjunkie.png
copyright: Downloaded from btjunkie.org copyright: Downloaded from btjunkie.org
@@ -57,9 +46,7 @@ Translations authors:
- Brazilian: Nick Marinho (nickmarinho@gmail.com) - Brazilian: Nick Marinho (nickmarinho@gmail.com)
- Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net) - Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)
- Catalan: Gekko Dam Beer (gekko04@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) - Danish: Mathias Nielsen (comoneo@gmail.com)
- Dutch: Joost Schipper (heavyjoost@users.sourceforge.net) - Dutch: Joost Schipper (heavyjoost@users.sourceforge.net)
- English: Christophe Dumez (chris@qbittorrent.org) - English: Christophe Dumez (chris@qbittorrent.org)

14
COPYING
View File

@@ -1,17 +1,3 @@
qBittorrent is licensed under the GNU General Public License version 2 with the
addition of the following special exception:
In addition, as a special exception, the copyright holders give permission to
link this program with the OpenSSL project's "OpenSSL" library (or with
modified versions of it that use the same license as the "OpenSSL" library),
and distribute the linked executables. You must obey the GNU General Public
License in all respects for all of the code used other than "OpenSSL". If you
modify file(s), you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version.
----------
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991

135
Changelog
View File

@@ -1,143 +1,14 @@
* Sun Aug 21 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.4.1 * Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.2.0
- BUGFIX: Fix problems when changing save path (if using temporary download folder)
- BUGFIX: Display real save path instead of the temporary one in torrent properties
- BUGFIX: Catching invalid_handle exception to avoid rare crashes
- BUGFIX: Fixed popup menu position in RSS feeds list
- BUGFIX: Don't save RSS feed state if it could not be updated
* Thu Aug 13 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.4.0
- FEATURE: Display swarm information in lists
- FEATURE: Allow to define temporary download folder
- FEATURE: Display total amount of uploaded data in finished list
- FEATURE: Resizing a column in a search results tab affects all tabs
- FEATURE: Search results tab columns are now remembered upon startup
- FEATURE: Added right click menu in search engine to clear completion history
- FEATURE: Allow to set a different port for DHT (UDP) than the one used for Bittorrent
- FEATURE: Updated spoofing code to avoid trackers ban
- BUGFIX: Provide more helpful explanation when an I/O error occured
- BUGFIX: Stop enforcing UTF-8 and use system locale instead
- COSMETIC: Redesigned program preferences
- COSMETIC: Updated icons set
* Fri Jul 24 2009 - Christophe DUMEZ <chris@qbittorrent.org> - 1.3.5
- BUGFIX: Made IP filter parser more robust
- BUGFIX: Fixed torrent creation tool
- BUGFIX: Fixed possible overflow in progress calculation in arborescence.h
- BUGFIX: Save properties window size, position, columns width and restore them
- BUGFIX: Set a minimum default width for NAME column in properties
- BUGFIX: Remember visual indexes of columns in transfer lists
* Sun Jul 12 2009 - Christophe DUMEZ <chris@qbittorrent.org> - v1.3.4
- BUGFIX: Fixed IP filter file parsing on 64bits
- BUGFIX: Suppressed QLayout: Attempting to add QLayout "" to properties "properties" warning message when opening a properties dialog
- BUGFIX: Fixed a little bug in search engine plugins helper file
- BUGFIX: Fixed compilation problems with Qt 4.3
- BUGFIX: Percentages no longer disapear with default cleanlooks style
- BUGFIX: Cleanly fixed popup menus position in lists (no more workarounds)
- BUGFIX: Fixed memory leak in search engine
- BUGFIX: Torrents with an infinite ratio are no longer affected by ratio_limit set in program preferences
- BUGFIX: Display a ratio of 0.0 if total_upload and total_download are both 0
- BUGFIX: Remove last separator in top tool bar
- BUGFIX: Tuned lists properties to make sure display is correct
- COSMETIC: Display date as well as time in log window
* Sun Apr 5 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.3
- BUGFIX: Fixed Web UI torrent upload form
- BUGFIX: Fixed unicode support in search engine
- BUGFIX: Fixed search engine bug that prevented a torrent from appearing more than once among all tabs
- LICENSE: Added an exception to the license regarding OpenSSL.
- I18N: Updated Finnish translation
* Sat Mar 7 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.2
- BUGFIX: Fix top toolbar disabling
- BUGFIX: Fix building with Qt 4.5
- BUGFIX: RSS items read status is now remembered upon restart
* 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
- FEATURE: Torrent queueing system (with priorities) - FEATURE: Torrent queueing system (with priorities)
- FEATURE: DHT is always ON (no longer used as fallback)
- FEATURE: The number of DHT nodes is displayed - FEATURE: The number of DHT nodes is displayed
- FEATURE: RSS can now be disabled from program preferences - 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: Disable ETA calculation when ETA column is hidden
- BUGFIX: Removed "disconnected" connection state, detection was far from perfect - 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: Transfer speed, ratio, connection status and DHT nodes are displayed in status bar
- COSMETIC: RSS Tab is now hidden as a default - COSMETIC: RSS Tab is now hidden as a default
- COSMETIC: Allow to hide or display top toolbar - COSMETIC: Allow to hide or display top toolbar
- COSMETIC: Log is now in a separate dialog - COSMETIC: Top toolbar is now hidden as a default
* Sun Sept 14 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.4
- FEATURE: DHT is no longer used as fallback only
- FEATURE: Ported WebUI to Mootools v1.2
- BUGFIX: Fixed 'start seeding after torrent creation' feature
- BUGFIX: Fixed compilation with boost v1.36
- BUGFIX: Some code optimization
- BUGFIX: Fixed memory leak in Web UI
- BUGFIX: Fixed problems with column sorting
- BUGFIX: Improved code for pausing torrents on startup
- BUGFIX: Torrent addition dialog is now disabled for downloads from WebUI
- BUGFIX: Give focus to input field in WebUI download dialog
* Tue Aug 26 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.3
- BUGFIX: Fixed ratio saving for seeding torrents
- I18N: Added czech and traditional chinese translations
* Sun Aug 17 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.2
- BUGFIX: Fixed progress calculation
- BUGFIX: Fixed finished torrent detection
* Fri Aug 01 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.1
- BUGFIX: Fixed bad resource file for icons
* Fri Aug 01 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.0 * Fri Aug 01 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.0
- FEATURE: Web interface to control qbittorrent (Ishan Arora) - FEATURE: Web interface to control qbittorrent (Ishan Arora)

View File

@@ -17,7 +17,7 @@ Dependencies:
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml) - Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
Qt >= 4.4.0 is advised 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.qbittorrent.org/download.php (advised)
-> http://www.libtorrent.net -> http://www.libtorrent.net
Be careful: another library (the one used by rTorrent) uses a similar name. Be careful: another library (the one used by rTorrent) uses a similar name.

2
TODO
View File

@@ -1,2 +1,4 @@
See https://blueprints.launchpad.net/qbittorrent/ See https://blueprints.launchpad.net/qbittorrent/
// in v1.2.0
- Split download and uploads in Web UI (Ishan Ahora)

202
configure vendored
View File

@@ -18,9 +18,17 @@ Main options:
--help This help text. --help This help text.
Dependency options: Dependency options:
--with-libtorrent-inc=[path] Path to libtorrent-rasterbar include
files
--with-libtorrent-lib=[path] Path to libtorrent-rasterbar library
files
--with-libtorrent-static-lib=[path] Path to libtorrent-rasterbar .a file
--with-libboost-inc=[path] Path to libboost include files --with-libboost-inc=[path] Path to libboost include files
--with-libcurl-inc=[path] Path to libcurl include files --with-libcurl-inc=[path] Path to libcurl include files
--with-libcurl-lib=[path] Path to libcurl library 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 --disable-libzzip Disable use of libzzip
--with-libzzip-inc=[path] Path to libzzip++ include files --with-libzzip-inc=[path] Path to libzzip++ include files
--with-libzzip-lib=[path] Path to libzzip++ library files --with-libzzip-lib=[path] Path to libzzip++ library files
@@ -140,6 +148,21 @@ while [ $# -gt 0 ]; do
shift shift
;; ;;
--with-libtorrent-inc=*)
QC_WITH_LIBTORRENT_INC=$optarg
shift
;;
--with-libtorrent-lib=*)
QC_WITH_LIBTORRENT_LIB=$optarg
shift
;;
--with-libtorrent-static-lib=*)
QC_WITH_LIBTORRENT_STATIC_LIB=$optarg
shift
;;
--with-libboost-inc=*) --with-libboost-inc=*)
QC_WITH_LIBBOOST_INC=$optarg QC_WITH_LIBBOOST_INC=$optarg
shift shift
@@ -155,6 +178,21 @@ while [ $# -gt 0 ]; do
shift 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) --disable-libzzip)
QC_DISABLE_libzzip="Y" QC_DISABLE_libzzip="Y"
shift shift
@@ -191,9 +229,15 @@ echo PREFIX=$PREFIX
echo BINDIR=$BINDIR echo BINDIR=$BINDIR
echo DATADIR=$DATADIR echo DATADIR=$DATADIR
echo EX_QTDIR=$EX_QTDIR echo EX_QTDIR=$EX_QTDIR
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_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB 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_DISABLE_libzzip=$QC_DISABLE_libzzip
echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC
echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB
@@ -323,29 +367,70 @@ public:
/* /*
-----BEGIN QCMOD----- -----BEGIN QCMOD-----
name: libtorrent-rasterbar name: libtorrent-rasterbar
arg: with-libtorrent-inc=[path], Path to libtorrent-rasterbar include files
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----- -----END QCMOD-----
*/ */
// see Conf::findPkgConfig
class qc_libtorrent_rasterbar : public ConfObj class qc_libtorrent_rasterbar : public ConfObj
{ {
public: public:
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {} qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent-rasterbar >= 0.14.0 (>= 0.14.4 advised)"; } QString name() const { return "libtorrent-rasterbar >= 0.13"; }
QString shortname() const { return "libtorrent-rasterbar"; } QString shortname() const { return "libtorrent-rasterbar"; }
bool exec(){ bool exec(){
QStringList incs; QString s;
QString req_ver = "0.14.0"; s = conf->getenv("QC_WITH_LIBTORRENT_INC");
QString adv_ver = "0.14.4"; if(!s.isEmpty()) {
QString version, libs, other; if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
VersionMode mode = VersionMin;
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other))
return false; return false;
for(int n = 0; n < incs.count(); ++n) }
conf->addIncludePath(incs[n]); }else{
if(!libs.isEmpty()) QStringList sl;
conf->addLib(libs); sl << "/usr/include";
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, adv_ver, &version, &incs, &libs, &other)) sl << "/usr/local/include";
printf("\nWarning: libtorrent-rasterbar v%s was detected. Although it will compile and run, you will probably experience some bugs. Please consider updating to v%s!\n", version.toUtf8().data(), adv_ver.toUtf8().data()); bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
conf->addIncludePath(s+QDir::separator()+"libtorrent");
s = conf->getenv("QC_WITH_LIBTORRENT_STATIC_LIB");
if(!s.isEmpty() && QFile::exists(s) && s.endsWith(".a")){
conf->addLib(s);
return true;
}
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
if(!s.isEmpty()) {
if(!conf->checkLibrary(s, "torrent-rasterbar")) {
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(conf->checkLibrary(s, "torrent-rasterbar")){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true; return true;
} }
}; };
@@ -468,6 +553,86 @@ public:
return true; 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" #line 1 "libzzip.qcm"
/* /*
-----BEGIN QCMOD----- -----BEGIN QCMOD-----
@@ -555,6 +720,9 @@ cat >$1/modules_new.cpp <<EOT
o = new qc_libcurl(conf); o = new qc_libcurl(conf);
o->required = true; o->required = true;
o->disabled = false; o->disabled = false;
o = new qc_libmagick(conf);
o->required = false;
o->disabled = false;
o = new qc_libzzip(conf); o = new qc_libzzip(conf);
o->required = false; o->required = false;
o->disabled = false; o->disabled = false;
@@ -1503,9 +1671,15 @@ export PREFIX
export BINDIR export BINDIR
export DATADIR export DATADIR
export EX_QTDIR export EX_QTDIR
export QC_WITH_LIBTORRENT_INC
export QC_WITH_LIBTORRENT_LIB
export QC_WITH_LIBTORRENT_STATIC_LIB
export QC_WITH_LIBBOOST_INC export QC_WITH_LIBBOOST_INC
export QC_WITH_LIBCURL_INC export QC_WITH_LIBCURL_INC
export QC_WITH_LIBCURL_LIB 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_DISABLE_libzzip
export QC_WITH_LIBZZIP_INC export QC_WITH_LIBZZIP_INC
export QC_WITH_LIBZZIP_LIB export QC_WITH_LIBZZIP_LIB

View File

@@ -15,5 +15,6 @@
<dep type='libcurl'> <dep type='libcurl'>
<required/> <required/>
</dep> </dep>
<dep type='libmagick'/>
<dep type='libzzip'/> <dep type='libzzip'/>
</qconf> </qconf>

65
qcm/libcommoncpp2.qcm Normal file
View 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;
}
};

View File

@@ -64,11 +64,14 @@ public:
return false; return false;
} }
conf->addLib(QString("-L") + s); conf->addLib(QString("-L") + s);
QString out = ""; QProcess magickConfig;
QStringList params; QStringList params;
params << "--libs"; params << "--libs";
qconf->doCommand("Magick++-config", params, &out); magickConfig.start("Magick++-config", params, QIODevice::ReadOnly);
out = out.replace("\n", ""); magickConfig.waitForStarted();
magickConfig.waitForFinished();
QByteArray result = magickConfig.readAll();
result = result.replace("\n", "");
conf->addLib(result.data()); conf->addLib(result.data());
conf->addDefine("HAVE_MAGICK"); conf->addDefine("HAVE_MAGICK");
return true; return true;

View File

@@ -1,29 +1,70 @@
/* /*
-----BEGIN QCMOD----- -----BEGIN QCMOD-----
name: libtorrent-rasterbar name: libtorrent-rasterbar
arg: with-libtorrent-inc=[path], Path to libtorrent-rasterbar include files
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----- -----END QCMOD-----
*/ */
// see Conf::findPkgConfig
class qc_libtorrent_rasterbar : public ConfObj class qc_libtorrent_rasterbar : public ConfObj
{ {
public: public:
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {} qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent-rasterbar >= 0.14.0 (>= 0.14.4 advised)"; } QString name() const { return "libtorrent-rasterbar >= 0.13"; }
QString shortname() const { return "libtorrent-rasterbar"; } QString shortname() const { return "libtorrent-rasterbar"; }
bool exec(){ bool exec(){
QStringList incs; QString s;
QString req_ver = "0.14.0"; s = conf->getenv("QC_WITH_LIBTORRENT_INC");
QString adv_ver = "0.14.4"; if(!s.isEmpty()) {
QString version, libs, other; if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
VersionMode mode = VersionMin;
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other))
return false; return false;
for(int n = 0; n < incs.count(); ++n) }
conf->addIncludePath(incs[n]); }else{
if(!libs.isEmpty()) QStringList sl;
conf->addLib(libs); sl << "/usr/include";
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, adv_ver, &version, &incs, &libs, &other)) sl << "/usr/local/include";
printf("\nWarning: libtorrent-rasterbar v%s was detected. Although it will compile and run, you will probably experience some bugs. Please consider updating to v%s!\n", version.toUtf8().data(), adv_ver.toUtf8().data()); bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
conf->addIncludePath(s+QDir::separator()+"libtorrent");
s = conf->getenv("QC_WITH_LIBTORRENT_STATIC_LIB");
if(!s.isEmpty() && QFile::exists(s) && s.endsWith(".a")){
conf->addLib(s);
return true;
}
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
if(!s.isEmpty()) {
if(!conf->checkLibrary(s, "torrent-rasterbar")) {
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(conf->checkLibrary(s, "torrent-rasterbar")){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true; return true;
} }
}; };

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -81,9 +72,6 @@ class DLListDelegate: public QItemDelegate {
case RATIO:{ case RATIO:{
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
double ratio = index.data().toDouble(); 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; break;
} }

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -44,13 +35,10 @@
#define F_NAME 0 #define F_NAME 0
#define F_SIZE 1 #define F_SIZE 1
#define F_UPSPEED 2 #define F_UPSPEED 2
#define F_SWARM 3 #define F_LEECH 3
#define F_PEERS 4 #define F_RATIO 4
#define F_UPLOAD 5 #define F_PRIORITY 5
#define F_RATIO 6 #define F_HASH 6
#define F_HASH 7
#define MAX_RATIO 100.
class FinishedListDelegate: public QItemDelegate { class FinishedListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
@@ -64,7 +52,6 @@ class FinishedListDelegate: public QItemDelegate {
QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
switch(index.column()){ switch(index.column()){
case F_SIZE: case F_SIZE:
case F_UPLOAD:
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong()));
break; break;
@@ -77,9 +64,6 @@ class FinishedListDelegate: public QItemDelegate {
case F_RATIO:{ case F_RATIO:{
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
double ratio = index.data().toDouble(); double ratio = index.data().toDouble();
if(ratio > MAX_RATIO)
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; break;
} }

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
#include "FinishedTorrents.h" #include "FinishedTorrents.h"
@@ -46,18 +37,18 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
setupUi(this); setupUi(this);
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png"))); actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png"))); actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
finishedListModel = new QStandardItemModel(0,8); connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool)));
finishedListModel = new QStandardItemModel(0,7);
finishedListModel->setHeaderData(F_NAME, Qt::Horizontal, tr("Name", "i.e: file name")); finishedListModel->setHeaderData(F_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
finishedListModel->setHeaderData(F_SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); finishedListModel->setHeaderData(F_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
finishedListModel->setHeaderData(F_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed")); finishedListModel->setHeaderData(F_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed"));
finishedListModel->setHeaderData(F_SWARM, Qt::Horizontal, tr("Seeds / Leechers")); finishedListModel->setHeaderData(F_LEECH, Qt::Horizontal, tr("Leechers", "i.e: full/partial sources"));
finishedListModel->setHeaderData(F_PEERS, Qt::Horizontal, tr("Connected peers"));
finishedListModel->setHeaderData(F_UPLOAD, Qt::Horizontal, tr("Total uploaded", "i.e: Total amount of uploaded data"));
finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio")); finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio"));
finishedListModel->setHeaderData(F_PRIORITY, Qt::Horizontal, tr("Priority"));
finishedList->setModel(finishedListModel); finishedList->setModel(finishedListModel);
finishedList->setRootIsDecorated(false);
finishedList->setAllColumnsShowFocus(true);
loadHiddenColumns(); loadHiddenColumns();
// Hide priority column
finishedList->hideColumn(F_PRIORITY);
// Hide hash column // Hide hash column
finishedList->hideColumn(F_HASH); finishedList->hideColumn(F_HASH);
// Load last columns width for download list // Load last columns width for download list
@@ -67,13 +58,14 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
// Make download list header clickable for sorting // Make download list header clickable for sorting
finishedList->header()->setClickable(true); finishedList->header()->setClickable(true);
finishedList->header()->setSortIndicatorShown(true); finishedList->header()->setSortIndicatorShown(true);
connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(toggleFinishedListSortOrder(int))); connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortFinishedList(int)));
finishedListDelegate = new FinishedListDelegate(finishedList); finishedListDelegate = new FinishedListDelegate(finishedList);
finishedList->setItemDelegate(finishedListDelegate); finishedList->setItemDelegate(finishedListDelegate);
connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&))); connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&)));
finishedList->header()->setContextMenuPolicy(Qt::CustomContextMenu); finishedList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(finishedList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedHoSMenu(const QPoint&))); connect(finishedList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedHoSMenu(const QPoint&)));
connect(finishedList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&))); connect(finishedList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
connect(BTSession, SIGNAL(forceFinishedListUpdate()), this, SLOT(updateFinishedList()));
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png"))); actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png"))); actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png"))); actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
@@ -82,20 +74,20 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered())); connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered())); connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered()));
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered())); connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
connect(actionIncreasePriority, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionIncreasePriority_triggered()));
connect(actionDecreasePriority, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDecreasePriority_triggered()));
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered())); connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered()));
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered())); connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder())); connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage())); connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection())); connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
connect(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName())); connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize())); connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed())); connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed()));
connect(actionHOSColSwarm, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSwarm())); connect(actionHOSColLeechers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnLeechers()));
connect(actionHOSColPeers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPeers()));
connect(actionHOSColUpload, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpload()));
connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio())); connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio()));
connect(actionHOSColPriority, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPriority()));
} }
FinishedTorrents::~FinishedTorrents(){ FinishedTorrents::~FinishedTorrents(){
@@ -111,7 +103,14 @@ void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
emit torrentDoubleClicked(hash, true); emit torrentDoubleClicked(hash, true);
} }
void FinishedTorrents::hidePriorityColumn(bool hide) {
finishedList->setColumnHidden(F_PRIORITY, hide);
}
void FinishedTorrents::addTorrent(QString hash){ void FinishedTorrents::addTorrent(QString hash){
if(!BTSession->isFinished(hash)){
BTSession->setFinishedTorrent(hash);
}
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
if(row != -1) return; if(row != -1) return;
row = finishedListModel->rowCount(); row = finishedListModel->rowCount();
@@ -121,10 +120,10 @@ void FinishedTorrents::addTorrent(QString hash){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name())); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name()));
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size())); finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.)); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.));
finishedListModel->setData(finishedListModel->index(row, F_SWARM), QVariant("-1/-1")); finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant("0"));
finishedListModel->setData(finishedListModel->index(row, F_PEERS), QVariant("0"));
finishedListModel->setData(finishedListModel->index(row, F_UPLOAD), QVariant((qlonglong)h.all_time_upload()));
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString::fromUtf8(misc::toString(BTSession->getRealRatio(hash)).c_str()))); finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString::fromUtf8(misc::toString(BTSession->getRealRatio(hash)).c_str())));
if(BTSession->isQueueingEnabled())
finishedListModel->setData(finishedListModel->index(row, F_PRIORITY), QVariant((int)BTSession->getUpTorrentPriority(hash)));
finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash)); finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash));
if(h.is_paused()) { if(h.is_paused()) {
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
@@ -136,8 +135,13 @@ void FinishedTorrents::addTorrent(QString hash){
// Update the number of finished torrents // Update the number of finished torrents
++nbFinished; ++nbFinished;
emit finishedTorrentsNumberChanged(nbFinished); emit finishedTorrentsNumberChanged(nbFinished);
// Sort List }
sortFinishedList();
void FinishedTorrents::torrentAdded(QString, QTorrentHandle& h, bool) {
QString hash = h.hash();
if(BTSession->isFinished(hash)) {
addTorrent(hash);
}
} }
// Set the color of a row in data model // Set the color of a row in data model
@@ -150,8 +154,9 @@ void FinishedTorrents::setRowColor(int row, QString color){
QStringList FinishedTorrents::getSelectedTorrents(bool only_one) const{ QStringList FinishedTorrents::getSelectedTorrents(bool only_one) const{
QStringList res; QStringList res;
QModelIndex index;
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == F_NAME) { if(index.column() == F_NAME) {
// Get the file hash // Get the file hash
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString(); QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
@@ -181,44 +186,10 @@ bool FinishedTorrents::loadColWidthFinishedList(){
for(unsigned int i=0; i<listSize; ++i){ for(unsigned int i=0; i<listSize; ++i){
finishedList->header()->resizeSection(i, width_list.at(i).toInt()); finishedList->header()->resizeSection(i, width_list.at(i).toInt());
} }
loadLastSortedColumn();
QVariantList visualIndexes = settings.value(QString::fromUtf8("FinishedListVisualIndexes"), QVariantList()).toList();
if(visualIndexes.size() != finishedListModel->columnCount()-1) {
qDebug("Corrupted values for download list columns sizes");
return false;
}
bool change = false;
do {
change = false;
for(int i=0;i<visualIndexes.size(); ++i) {
int new_visual_index = visualIndexes.at(finishedList->header()->logicalIndex(i)).toInt();
if(i != new_visual_index) {
qDebug("Moving column from %d to %d", finishedList->header()->logicalIndex(i), new_visual_index);
finishedList->header()->moveSection(i, new_visual_index);
change = true;
}
}
}while(change);
qDebug("Finished list columns width loaded"); qDebug("Finished list columns width loaded");
return true; return true;
} }
void FinishedTorrents::loadLastSortedColumn() {
// Loading last sorted column
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortedCol = settings.value(QString::fromUtf8("FinishedListSortedCol"), QString()).toString();
if(!sortedCol.isEmpty()) {
Qt::SortOrder sortOrder;
if(sortedCol.endsWith(QString::fromUtf8("d")))
sortOrder = Qt::DescendingOrder;
else
sortOrder = Qt::AscendingOrder;
sortedCol = sortedCol.left(sortedCol.size()-1);
int index = sortedCol.toInt();
sortFinishedList(index, sortOrder);
}
}
// Save columns width in a file to remember them // Save columns width in a file to remember them
// (finished list) // (finished list)
void FinishedTorrents::saveColWidthFinishedList() const{ void FinishedTorrents::saveColWidthFinishedList() const{
@@ -233,7 +204,7 @@ void FinishedTorrents::saveColWidthFinishedList() const{
width_list = line.split(' '); width_list = line.split(' ');
} }
for(short i=0; i<nbColumns; ++i){ for(short i=0; i<nbColumns; ++i){
if(finishedList->columnWidth(i)<1 && width_list.size() == nbColumns && width_list.at(i).toInt()>=1) { if(finishedList->columnWidth(i)<1 && width_list.size() == finishedListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
// load the former width // load the former width
new_width_list << width_list.at(i); new_width_list << width_list.at(i);
} else if(finishedList->columnWidth(i)>=1) { } else if(finishedList->columnWidth(i)>=1) {
@@ -246,18 +217,14 @@ void FinishedTorrents::saveColWidthFinishedList() const{
} }
} }
settings.setValue("FinishedListColsWidth", new_width_list.join(" ")); settings.setValue("FinishedListColsWidth", new_width_list.join(" "));
QVariantList visualIndexes;
for(int i=0; i<nbColumns; ++i) {
visualIndexes.append(finishedList->header()->visualIndex(i));
}
settings.setValue(QString::fromUtf8("FinishedListVisualIndexes"), visualIndexes);
qDebug("Finished list columns width saved"); qDebug("Finished list columns width saved");
} }
void FinishedTorrents::on_actionSet_upload_limit_triggered(){ void FinishedTorrents::on_actionSet_upload_limit_triggered(){
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
QModelIndex index;
QStringList hashes; QStringList hashes;
foreach(const QModelIndex &index, selectedIndexes){ foreach(index, selectedIndexes){
if(index.column() == F_NAME){ if(index.column() == F_NAME){
// Get the file hash // Get the file hash
hashes << finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString(); hashes << finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
@@ -266,9 +233,15 @@ void FinishedTorrents::on_actionSet_upload_limit_triggered(){
new BandwidthAllocationDialog(this, true, BTSession, hashes); new BandwidthAllocationDialog(this, true, BTSession, hashes);
} }
void FinishedTorrents::updateTorrent(QTorrentHandle h) { void FinishedTorrents::updateFinishedList(){
if(!h.is_valid()) return; QString hash;
QString hash = h.hash(); QStringList finishedSHAs = BTSession->getFinishedTorrents();
foreach(hash, finishedSHAs){
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(!h.is_valid()){
qDebug("Problem: This torrent is not valid in finished list");
continue;
}
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
if(row == -1){ if(row == -1){
qDebug("Cannot find torrent in finished list, adding it"); qDebug("Cannot find torrent in finished list, adding it");
@@ -276,43 +249,51 @@ void FinishedTorrents::updateTorrent(QTorrentHandle h) {
row = getRowFromHash(hash); row = getRowFromHash(hash);
} }
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
if(!finishedList->isColumnHidden(F_SWARM)) { // Update priority
finishedListModel->setData(finishedListModel->index(row, F_SWARM), misc::toQString(h.num_complete())+QString("/")+misc::toQString(h.num_incomplete())); if(BTSession->isQueueingEnabled()) {
} finishedListModel->setData(finishedListModel->index(row, F_PRIORITY), QVariant((int)BTSession->getUpTorrentPriority(hash)));
if(h.is_paused()) return; if(h.is_paused() && BTSession->isUploadQueued(hash)) {
// Update queued torrent
if(BTSession->isQueueingEnabled() && h.is_queued()) {
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
} else {
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole);
}
// Reset upload speed and seeds/leech
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), 0.);
finishedListModel->setData(finishedListModel->index(row, F_PEERS), "0");
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
return;
} }
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){ }
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole); if(h.is_paused()) continue;
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
continue;
}
if(h.state() == torrent_status::downloading || (h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking && h.progress() < 1.)) {
// What are you doing here? go back to download tab!
int reponse = QMessageBox::question(this, tr("Incomplete torrent in seeding list"), tr("It appears that the state of '%1' torrent changed from 'seeding' to 'downloading'. Would you like to move it back to download list? (otherwise the torrent will simply be deleted)").arg(h.name()), QMessageBox::Yes | QMessageBox::No);
if (reponse == QMessageBox::Yes) {
qDebug("Info: a torrent was moved from finished to download tab");
deleteTorrent(hash);
BTSession->setUnfinishedTorrent(hash);
emit torrentMovedFromFinishedList(hash);
}
else if (reponse == QMessageBox::No) {
qDebug("Deleted from the finished");
BTSession->deleteTorrent(hash, true);
}
continue;
}
if(h.state() == torrent_status::checking_files){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
return; continue;
} }
setRowColor(row, QString::fromUtf8("orange")); setRowColor(row, QString::fromUtf8("orange"));
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
if(!finishedList->isColumnHidden(F_UPSPEED)) { if(!finishedList->isColumnHidden(F_UPSPEED)) {
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate())); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
} }
if(!finishedList->isColumnHidden(F_PEERS)) { if(!finishedList->isColumnHidden(F_LEECH)) {
finishedListModel->setData(finishedListModel->index(row, F_PEERS), misc::toQString(h.num_peers() - h.num_seeds(), true)); finishedListModel->setData(finishedListModel->index(row, F_LEECH), misc::toQString(h.num_peers() - h.num_seeds(), true));
}
if(!finishedList->isColumnHidden(F_UPLOAD)) {
finishedListModel->setData(finishedListModel->index(row, F_UPLOAD), QVariant((double)h.all_time_upload()));
} }
if(!finishedList->isColumnHidden(F_RATIO)) { if(!finishedList->isColumnHidden(F_RATIO)) {
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
} }
} }
}
int FinishedTorrents::getRowFromHash(QString hash) const{ int FinishedTorrents::getRowFromHash(QString hash) const{
unsigned int nbRows = finishedListModel->rowCount(); unsigned int nbRows = finishedListModel->rowCount();
@@ -331,10 +312,17 @@ void FinishedTorrents::pauseTorrent(QString hash) {
return; return;
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0)); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0));
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
finishedListModel->setData(finishedListModel->index(row, F_PEERS), QVariant(QString::fromUtf8("0"))); finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant(QString::fromUtf8("0")));
setRowColor(row, QString::fromUtf8("red")); setRowColor(row, QString::fromUtf8("red"));
} }
void FinishedTorrents::resumeTorrent(QString hash) {
int row = getRowFromHash(hash);
Q_ASSERT(row != -1);
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("orange"));
}
QString FinishedTorrents::getHashFromRow(unsigned int row) const { QString FinishedTorrents::getHashFromRow(unsigned int row) const {
Q_ASSERT(row < (unsigned int)finishedListModel->rowCount()); Q_ASSERT(row < (unsigned int)finishedListModel->rowCount());
return finishedListModel->data(finishedListModel->index(row, F_HASH)).toString(); return finishedListModel->data(finishedListModel->index(row, F_HASH)).toString();
@@ -374,31 +362,21 @@ void FinishedTorrents::updateFileSize(QString hash){
// display properties of selected items // display properties of selected items
void FinishedTorrents::propertiesSelection(){ void FinishedTorrents::propertiesSelection(){
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){ QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == F_NAME){ if(index.column() == F_NAME){
showProperties(index); showProperties(index);
} }
} }
} }
void FinishedTorrents::forceRecheck(){ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){
if(index.column() == F_NAME){
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
QTorrentHandle h = BTSession->getTorrentHandle(hash);
qDebug("Forcing recheck for torrent %s", hash.toLocal8Bit().data());
h.force_recheck();
}
}
}
void FinishedTorrents::displayFinishedListMenu(const QPoint&){
QMenu myFinishedListMenu(this); QMenu myFinishedListMenu(this);
QModelIndex index;
// Enable/disable pause/start action given the DL state // Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
bool has_pause = false, has_start = false, has_preview = false; bool has_pause = false, has_start = false, has_preview = false;
foreach(const QModelIndex &index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == F_NAME) { if(index.column() == F_NAME) {
// Get the file name // Get the file name
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString(); QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
@@ -429,15 +407,19 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint&){
myFinishedListMenu.addSeparator(); myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionSet_upload_limit); myFinishedListMenu.addAction(actionSet_upload_limit);
myFinishedListMenu.addSeparator(); myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionForce_recheck);
myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionOpen_destination_folder); myFinishedListMenu.addAction(actionOpen_destination_folder);
myFinishedListMenu.addAction(actionTorrent_Properties); myFinishedListMenu.addAction(actionTorrent_Properties);
if(BTSession->isQueueingEnabled()) {
myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionIncreasePriority);
myFinishedListMenu.addAction(actionDecreasePriority);
}
myFinishedListMenu.addSeparator(); myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionBuy_it); myFinishedListMenu.addAction(actionBuy_it);
// Call menu // Call menu
myFinishedListMenu.exec(QCursor::pos()); // XXX: why mapToGlobal() is not enough?
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,58));
} }
@@ -449,8 +431,13 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint&){
void FinishedTorrents::displayFinishedHoSMenu(const QPoint& pos){ void FinishedTorrents::displayFinishedHoSMenu(const QPoint& pos){
QMenu hideshowColumn(this); QMenu hideshowColumn(this);
hideshowColumn.setTitle(tr("Hide or Show Column")); hideshowColumn.setTitle(tr("Hide or Show Column"));
int lastCol = F_RATIO; int lastCol;
for(int i=0; i<=lastCol; i++) { if(BTSession->isQueueingEnabled()) {
lastCol = F_PRIORITY;
} else {
lastCol = F_RATIO;
}
for(int i=0; i<=F_RATIO; i++) {
hideshowColumn.addAction(getActionHoSCol(i)); hideshowColumn.addAction(getActionHoSCol(i));
} }
// Call menu // Call menu
@@ -472,12 +459,12 @@ void FinishedTorrents::hideOrShowColumn(int index) {
if(nbVisibleColumns <= 1) return; if(nbVisibleColumns <= 1) return;
// User can hide the column, do it. // User can hide the column, do it.
finishedList->setColumnHidden(index, true); finishedList->setColumnHidden(index, true);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png"))); getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
--nbVisibleColumns; --nbVisibleColumns;
} else { } else {
// User want to display the column // User want to display the column
finishedList->setColumnHidden(index, false); finishedList->setColumnHidden(index, false);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png"))); getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
++nbVisibleColumns; ++nbVisibleColumns;
} }
//resize all others non-hidden columns //resize all others non-hidden columns
@@ -500,22 +487,18 @@ void FinishedTorrents::hideOrShowColumnUpSpeed() {
hideOrShowColumn(F_UPSPEED); hideOrShowColumn(F_UPSPEED);
} }
void FinishedTorrents::hideOrShowColumnSwarm() { void FinishedTorrents::hideOrShowColumnLeechers() {
hideOrShowColumn(F_SWARM); hideOrShowColumn(F_LEECH);
}
void FinishedTorrents::hideOrShowColumnPeers() {
hideOrShowColumn(F_PEERS);
}
void FinishedTorrents::hideOrShowColumnUpload() {
hideOrShowColumn(F_UPLOAD);
} }
void FinishedTorrents::hideOrShowColumnRatio() { void FinishedTorrents::hideOrShowColumnRatio() {
hideOrShowColumn(F_RATIO); hideOrShowColumn(F_RATIO);
} }
void FinishedTorrents::hideOrShowColumnPriority() {
hideOrShowColumn(F_PRIORITY);
}
// load the previous settings, and hide the columns // load the previous settings, and hide the columns
bool FinishedTorrents::loadHiddenColumns() { bool FinishedTorrents::loadHiddenColumns() {
bool loaded = false; bool loaded = false;
@@ -535,9 +518,9 @@ bool FinishedTorrents::loadHiddenColumns() {
for(int i=0; i<finishedListModel->columnCount()-1; i++) { for(int i=0; i<finishedListModel->columnCount()-1; i++) {
if(loaded && ishidden_list.at(i) == "0") { if(loaded && ishidden_list.at(i) == "0") {
finishedList->setColumnHidden(i, true); finishedList->setColumnHidden(i, true);
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png"))); getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
} else { } else {
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png"))); getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
} }
} }
return loaded; return loaded;
@@ -571,18 +554,15 @@ QAction* FinishedTorrents::getActionHoSCol(int index) {
case F_UPSPEED : case F_UPSPEED :
return actionHOSColUpSpeed; return actionHOSColUpSpeed;
break; break;
case F_SWARM : case F_LEECH :
return actionHOSColSwarm; return actionHOSColLeechers;
break;
case F_PEERS :
return actionHOSColPeers;
break;
case F_UPLOAD :
return actionHOSColUpload;
break; break;
case F_RATIO : case F_RATIO :
return actionHOSColRatio; return actionHOSColRatio;
break; break;
case F_PRIORITY :
return actionHOSColPriority;
break;
default : default :
return NULL; return NULL;
} }
@@ -593,42 +573,19 @@ QAction* FinishedTorrents::getActionHoSCol(int index) {
* Sorting functions * Sorting functions
*/ */
void FinishedTorrents::toggleFinishedListSortOrder(int index) { void FinishedTorrents::sortFinishedList(int index){
Qt::SortOrder sortOrder = Qt::AscendingOrder; static Qt::SortOrder sortOrder = Qt::AscendingOrder;
if(finishedList->header()->sortIndicatorSection() == index){ if(finishedList->header()->sortIndicatorSection() == index){
sortOrder = (Qt::SortOrder)!(bool)finishedList->header()->sortIndicatorOrder(); if(sortOrder == Qt::AscendingOrder){
} sortOrder = Qt::DescendingOrder;
switch(index) {
case F_SIZE:
case F_UPSPEED:
case F_RATIO:
case F_UPLOAD:
sortFinishedListFloat(index, sortOrder);
break;
default:
sortFinishedListString(index, sortOrder);
}
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortOrderLetter;
if(sortOrder == Qt::AscendingOrder)
sortOrderLetter = QString::fromUtf8("a");
else
sortOrderLetter = QString::fromUtf8("d");
settings.setValue(QString::fromUtf8("FinishedListSortedCol"), misc::toQString(index)+sortOrderLetter);
}
void FinishedTorrents::sortFinishedList(int index, Qt::SortOrder sortOrder){
if(index == -1) {
index = finishedList->header()->sortIndicatorSection();
sortOrder = finishedList->header()->sortIndicatorOrder();
}else{ }else{
finishedList->header()->setSortIndicator(index, sortOrder); sortOrder = Qt::AscendingOrder;
} }
}
finishedList->header()->setSortIndicator(index, sortOrder);
switch(index){ switch(index){
case F_SIZE: case F_SIZE:
case F_UPSPEED: case F_UPSPEED:
case F_UPLOAD:
case F_RATIO:
sortFinishedListFloat(index, sortOrder); sortFinishedListFloat(index, sortOrder);
break; break;
default: default:

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -69,30 +60,29 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
void displayFinishedHoSMenu(const QPoint&); void displayFinishedHoSMenu(const QPoint&);
void setRowColor(int row, QString color); void setRowColor(int row, QString color);
void saveColWidthFinishedList() const; void saveColWidthFinishedList() const;
void toggleFinishedListSortOrder(int index); void sortFinishedList(int index);
void sortFinishedList(int index=-1, Qt::SortOrder sortOrder=Qt::AscendingOrder);
void sortFinishedListFloat(int index, Qt::SortOrder sortOrder); void sortFinishedListFloat(int index, Qt::SortOrder sortOrder);
void sortFinishedListString(int index, Qt::SortOrder sortOrder); void sortFinishedListString(int index, Qt::SortOrder sortOrder);
void updateFileSize(QString hash); void updateFileSize(QString hash);
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume);
void on_actionSet_upload_limit_triggered(); void on_actionSet_upload_limit_triggered();
void notifyTorrentDoubleClicked(const QModelIndex& index); void notifyTorrentDoubleClicked(const QModelIndex& index);
void hideOrShowColumnName(); void hideOrShowColumnName();
void hideOrShowColumnSize(); void hideOrShowColumnSize();
void hideOrShowColumnUpSpeed(); void hideOrShowColumnUpSpeed();
void hideOrShowColumnSwarm(); void hideOrShowColumnLeechers();
void hideOrShowColumnPeers();
void hideOrShowColumnUpload();
void hideOrShowColumnRatio(); void hideOrShowColumnRatio();
void forceRecheck(); void hideOrShowColumnPriority();
public slots: public slots:
void addTorrent(QString hash); void addTorrent(QString hash);
void updateTorrent(QTorrentHandle h); void updateFinishedList();
void pauseTorrent(QString hash); void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
void propertiesSelection(); void propertiesSelection();
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
void showPropertiesFromHash(QString hash); void showPropertiesFromHash(QString hash);
void loadLastSortedColumn(); void hidePriorityColumn(bool hide);
signals: signals:
void torrentMovedFromFinishedList(QString); void torrentMovedFromFinishedList(QString);

File diff suppressed because it is too large Load Diff

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -33,7 +24,7 @@
#include <QProcess> #include <QProcess>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QPointer>
#include "ui_MainWindow.h" #include "ui_MainWindow.h"
#include "qtorrenthandle.h" #include "qtorrenthandle.h"
@@ -70,13 +61,12 @@ class GUI : public QMainWindow, private Ui::MainWindow{
// Bittorrent // Bittorrent
bittorrent *BTSession; bittorrent *BTSession;
QTimer *checkConnect; QTimer *checkConnect;
QTimer *scrapeTimer;
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers;
// GUI related // GUI related
QTabWidget *tabs; QTabWidget *tabs;
QPointer<options_imp> options; options_imp *options;
QSystemTrayIcon *myTrayIcon; QSystemTrayIcon *myTrayIcon;
QPointer<QTimer> systrayCreator; QTimer *systrayCreator;
QMenu *myTrayIconMenu; QMenu *myTrayIconMenu;
DownloadingTorrents *downloadingTorrentTab; DownloadingTorrents *downloadingTorrentTab;
FinishedTorrents *finishedTorrentTab; FinishedTorrents *finishedTorrentTab;
@@ -107,7 +97,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
// RSS // RSS
RSSImp *rssWidget; RSSImp *rssWidget;
// Web UI // Web UI
QPointer<HttpServer> httpServer; HttpServer *httpServer;
// Misc // Misc
#ifdef QT_4_4 #ifdef QT_4_4
QLocalServer *localServer; QLocalServer *localServer;
@@ -126,7 +116,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void on_actionCreate_torrent_triggered(); void on_actionCreate_torrent_triggered();
void on_actionWebsite_triggered() const; void on_actionWebsite_triggered() const;
void on_actionBugReport_triggered() const; void on_actionBugReport_triggered() const;
void on_actionShow_console_triggered();
void readParamsOnSocket(); void readParamsOnSocket();
void acceptConnection(); void acceptConnection();
void togglePausedState(QString hash); void togglePausedState(QString hash);
@@ -138,9 +127,11 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void readSettings(); void readSettings();
void on_actionExit_triggered(); void on_actionExit_triggered();
void createTrayIcon(); void createTrayIcon();
void updateUnfinishedTorrentNumberCalc();
void updateFinishedTorrentNumberCalc();
void updateUnfinishedTorrentNumber(unsigned int nb); void updateUnfinishedTorrentNumber(unsigned int nb);
void updateFinishedTorrentNumber(unsigned int nb); void updateFinishedTorrentNumber(unsigned int nb);
void fullDiskError(QTorrentHandle& h, QString msg) const; void fullDiskError(QTorrentHandle& h) const;
void handleDownloadFromUrlFailure(QString, QString) const; void handleDownloadFromUrlFailure(QString, QString) const;
void createSystrayDelayed(); void createSystrayDelayed();
// Keyboard shortcuts // Keyboard shortcuts
@@ -166,22 +157,21 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void processParams(const QStringList& params); void processParams(const QStringList& params);
void addTorrent(QString path); void addTorrent(QString path);
void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker); void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker);
void processScannedFiles(const QStringList& params);
void processDownloadedFiles(QString path, QString url); void processDownloadedFiles(QString path, QString url);
void downloadFromURLList(const QStringList& urls); void downloadFromURLList(const QStringList& urls);
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
void deleteRatioTorrent(QString fileName);
void finishedTorrent(QTorrentHandle& h) const; void finishedTorrent(QTorrentHandle& h) const;
void addedTorrent(QTorrentHandle& h) const; void torrentChecked(QString hash) const;
void checkedTorrent(QTorrentHandle& h) const; void updateLists();
void pausedTorrent(QTorrentHandle& h) const;
void resumedTorrent(QTorrentHandle& h) const;
void updateLists(bool force=false);
bool initWebUi(QString username, QString password, int port); bool initWebUi(QString username, QString password, int port);
void pauseTorrent(QString hash);
void on_actionIncreasePriority_triggered(); void on_actionIncreasePriority_triggered();
void on_actionDecreasePriority_triggered(); void on_actionDecreasePriority_triggered();
void scrapeTrackers();
// Options slots // Options slots
void on_actionOptions_triggered(); void on_actionOptions_triggered();
void OptionsSaved(bool deleteOptions); void OptionsSaved(QString info, bool deleteOptions);
// HTTP slots // HTTP slots
void on_actionDownload_from_URL_triggered(); void on_actionDownload_from_URL_triggered();
@@ -195,7 +185,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
protected: protected:
void closeEvent(QCloseEvent *); void closeEvent(QCloseEvent *);
void showEvent(QShowEvent *);
bool event(QEvent * event); bool event(QEvent * event);
void displayRSSTab(bool enable); void displayRSSTab(bool enable);

BIN
src/Icons/bt_settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/Icons/button_cancel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/Icons/button_ok.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/Icons/configure.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/Icons/connection.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

BIN
src/Icons/description.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

BIN
src/Icons/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 575 B

View File

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 750 B

View File

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 704 B

BIN
src/Icons/filter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 B

View File

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 449 B

BIN
src/Icons/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/Icons/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/Icons/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
src/Icons/newmsg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/Icons/password.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
src/Icons/proxy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,6 +1,6 @@
[Desktop Entry] [Desktop Entry]
Categories=Qt;Network;P2P Categories=Qt;Network;P2P
Comment=V1.4.1 Comment=V1.2.0
Exec=qbittorrent %f Exec=qbittorrent %f
GenericName=Bittorrent client GenericName=Bittorrent client
GenericName[bg]=Торент клиент GenericName[bg]=Торент клиент

View File

Before

Width:  |  Height:  |  Size: 965 B

After

Width:  |  Height:  |  Size: 965 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

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: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

BIN
src/Icons/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/Icons/style.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 739 B

After

Width:  |  Height:  |  Size: 739 B

BIN
src/Icons/systemtray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 856 B

BIN
src/Icons/unavailable.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 765 B

After

Width:  |  Height:  |  Size: 765 B

BIN
src/Icons/wizard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0" > <ui version="4.0" >
<class>MainWindow</class> <class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" > <widget class="QMainWindow" name="MainWindow" >
@@ -25,7 +24,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>914</width> <width>914</width>
<height>23</height> <height>26</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menu_Edit" > <widget class="QMenu" name="menu_Edit" >
@@ -59,7 +58,6 @@
<string>Options</string> <string>Options</string>
</property> </property>
<addaction name="actionOptions" /> <addaction name="actionOptions" />
<addaction name="actionShow_console"/>
</widget> </widget>
<widget class="QMenu" name="menu_File" > <widget class="QMenu" name="menu_File" >
<property name="title" > <property name="title" >
@@ -122,6 +120,7 @@
<addaction name="actionIncreasePriority" /> <addaction name="actionIncreasePriority" />
<addaction name="separator" /> <addaction name="separator" />
<addaction name="actionExit" /> <addaction name="actionExit" />
<addaction name="separator" />
</widget> </widget>
<widget class="QStatusBar" name="statusBar" /> <widget class="QStatusBar" name="statusBar" />
<action name="actionOpen" > <action name="actionOpen" >
@@ -236,8 +235,7 @@
</action> </action>
<action name="actionDecreasePriority" > <action name="actionDecreasePriority" >
<property name="icon" > <property name="icon" >
<iconset resource="icons.qrc"> <iconset resource="icons.qrc" >:/Icons/skin/decrease.png</iconset>
<normaloff>:/Icons/skin/decrease.png</normaloff>:/Icons/skin/decrease.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Decrease priority</string> <string>Decrease priority</string>
@@ -248,8 +246,7 @@
</action> </action>
<action name="actionIncreasePriority" > <action name="actionIncreasePriority" >
<property name="icon" > <property name="icon" >
<iconset resource="icons.qrc"> <iconset resource="icons.qrc" >:/Icons/skin/increase.png</iconset>
<normaloff>:/Icons/skin/increase.png</normaloff>:/Icons/skin/increase.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Increase priority</string> <string>Increase priority</string>
@@ -258,15 +255,6 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
</action> </action>
<action name="actionShow_console">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/log.png</normaloff>:/Icons/oxygen/log.png</iconset>
</property>
<property name="text">
<string>Console</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="icons.qrc" /> <include location="icons.qrc" />

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -56,14 +47,13 @@ SearchTab::SearchTab(SearchEngine *parent) : QWidget()
setLayout(box); setLayout(box);
// Set Search results list model // Set Search results list model
SearchListModel = new QStandardItemModel(0,6); SearchListModel = new QStandardItemModel(0,5);
SearchListModel->setHeaderData(SEARCH_NAME, Qt::Horizontal, tr("Name", "i.e: file name")); SearchListModel->setHeaderData(SEARCH_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
SearchListModel->setHeaderData(SEARCH_SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); SearchListModel->setHeaderData(SEARCH_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
SearchListModel->setHeaderData(SEARCH_SEEDERS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources")); SearchListModel->setHeaderData(SEARCH_SEEDERS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources"));
SearchListModel->setHeaderData(SEARCH_LEECHERS, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources")); SearchListModel->setHeaderData(SEARCH_LEECHERS, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources"));
SearchListModel->setHeaderData(SEARCH_ENGINE, Qt::Horizontal, tr("Search engine")); SearchListModel->setHeaderData(SEARCH_ENGINE, Qt::Horizontal, tr("Search engine"));
resultsBrowser->setModel(SearchListModel); resultsBrowser->setModel(SearchListModel);
resultsBrowser->hideColumn(URL_COLUMN); // Hide url column
SearchDelegate = new SearchListDelegate(); SearchDelegate = new SearchListDelegate();
resultsBrowser->setItemDelegate(SearchDelegate); resultsBrowser->setItemDelegate(SearchDelegate);
// Make search list header clickable for sorting // Make search list header clickable for sorting
@@ -75,36 +65,19 @@ SearchTab::SearchTab(SearchEngine *parent) : QWidget()
connect(resultsBrowser->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortSearchList(int))); connect(resultsBrowser->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortSearchList(int)));
// Load last columns width for search results list // Load last columns width for search results list
if(!loadColWidthResultsList()){ if(!loadColWidthSearchList()){
resultsBrowser->header()->resizeSection(0, 275); resultsBrowser->header()->resizeSection(0, 275);
} }
} }
SearchTab::~SearchTab() { SearchTab::~SearchTab()
{
saveColWidthSearchList();
delete resultsBrowser; delete resultsBrowser;
delete SearchListModel; delete SearchListModel;
delete SearchDelegate; delete SearchDelegate;
} }
QHeaderView* SearchTab::header() const {
return resultsBrowser->header();
}
bool SearchTab::loadColWidthResultsList() {
QSettings settings("qBittorrent", "qBittorrent");
QString line = settings.value("SearchResultsColsWidth", QString()).toString();
if(line.isEmpty())
return false;
QStringList width_list = line.split(' ');
if(width_list.size() < SearchListModel->columnCount())
return false;
unsigned int listSize = width_list.size();
for(unsigned int i=0; i<listSize; ++i){
resultsBrowser->header()->resizeSection(i, width_list.at(i).toInt());
}
return true;
}
QLabel* SearchTab::getCurrentLabel() QLabel* SearchTab::getCurrentLabel()
{ {
return results_lbl; return results_lbl;
@@ -155,7 +128,7 @@ void SearchTab::sortSearchListInt(int index, Qt::SortOrder sortOrder){
for(int row=0; row<lines.size(); ++row){ for(int row=0; row<lines.size(); ++row){
SearchListModel->insertRow(SearchListModel->rowCount()); SearchListModel->insertRow(SearchListModel->rowCount());
int sourceRow = lines[row].first; int sourceRow = lines[row].first;
for(int col=0; col<6; ++col){ for(int col=0; col<5; ++col){
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col))); SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col)));
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole); SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole);
} }
@@ -175,7 +148,7 @@ void SearchTab::sortSearchListString(int index, Qt::SortOrder sortOrder){
for(int row=0; row<nbRows_old; ++row){ for(int row=0; row<nbRows_old; ++row){
SearchListModel->insertRow(SearchListModel->rowCount()); SearchListModel->insertRow(SearchListModel->rowCount());
int sourceRow = lines[row].first; int sourceRow = lines[row].first;
for(int col=0; col<6; ++col){ for(int col=0; col<5; ++col){
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col))); SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col)));
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole); SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole);
} }
@@ -184,3 +157,33 @@ void SearchTab::sortSearchListString(int index, Qt::SortOrder sortOrder){
SearchListModel->removeRows(0, nbRows_old); SearchListModel->removeRows(0, nbRows_old);
} }
// Save columns width in a file to remember them
// (download list)
void SearchTab::saveColWidthSearchList() const{
qDebug("Saving columns width in search list");
QSettings settings("qBittorrent", "qBittorrent");
QStringList width_list;
for(int i=0; i<SearchListModel->columnCount(); ++i){
width_list << misc::toQString(resultsBrowser->columnWidth(i));
}
settings.setValue("SearchListColsWidth", width_list.join(" "));
qDebug("Search list columns width saved");
}
// Load columns width in a file that were saved previously
// (search list)
bool SearchTab::loadColWidthSearchList(){
qDebug("Loading columns width for search list");
QSettings settings("qBittorrent", "qBittorrent");
QString line = settings.value("SearchListColsWidth", QString()).toString();
if(line.isEmpty())
return false;
QStringList width_list = line.split(' ');
if(width_list.size() != SearchListModel->columnCount())
return false;
for(int i=0; i<width_list.size(); ++i){
resultsBrowser->header()->resizeSection(i, width_list.at(i).toInt());
}
qDebug("Search list columns width loaded");
return true;
}

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -33,13 +24,9 @@
#include "ui_search.h" #include "ui_search.h"
#define ENGINE_URL_COLUMN 4
#define URL_COLUMN 5
class SearchListDelegate; class SearchListDelegate;
class SearchEngine; class SearchEngine;
class QTreeView; class QTreeView;
class QHeaderView;
class QStandardItemModel; class QStandardItemModel;
class SearchTab : public QWidget, public Ui::search_engine class SearchTab : public QWidget, public Ui::search_engine
@@ -55,17 +42,16 @@ class SearchTab : public QWidget, public Ui::search_engine
public: public:
SearchTab(SearchEngine *parent); SearchTab(SearchEngine *parent);
~SearchTab(); ~SearchTab();
bool loadColWidthResultsList(); bool loadColWidthSearchList();
QLabel * getCurrentLabel(); QLabel * getCurrentLabel();
QStandardItemModel * getCurrentSearchListModel(); QStandardItemModel * getCurrentSearchListModel();
QTreeView * getCurrentTreeView(); QTreeView * getCurrentTreeView();
void setRowColor(int row, QString color); void setRowColor(int row, QString color);
QHeaderView* header() const;
protected slots: protected slots:
void sortSearchList(int index); void sortSearchList(int index);
void sortSearchListInt(int index, Qt::SortOrder sortOrder); void sortSearchListInt(int index, Qt::SortOrder sortOrder);
void sortSearchListString(int index, Qt::SortOrder sortOrder); void sortSearchListString(int index, Qt::SortOrder sortOrder);
void saveColWidthSearchList() const;
}; };

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0" > <ui version="4.0" >
<author>Christophe Dumez</author> <author>Christophe Dumez</author>
<class>AboutDlg</class> <class>AboutDlg</class>
@@ -51,13 +50,13 @@
<item> <item>
<widget class="QLabel" name="lb_name" > <widget class="QLabel" name="lb_name" >
<property name="sizePolicy" > <property name="sizePolicy" >
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text" > <property name="text" >
<string>&lt;h3&gt;&lt;b&gt;qBittorrent&lt;/b&gt;&lt;/h3&gt;</string> <string>&lt;h3>&lt;b>qBittorrent&lt;/b>&lt;/h3></string>
</property> </property>
<property name="textFormat" > <property name="textFormat" >
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>
@@ -69,7 +68,7 @@
<property name="orientation" > <property name="orientation" >
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" >
<size> <size>
<width>40</width> <width>40</width>
<height>20</height> <height>20</height>
@@ -92,7 +91,7 @@
<property name="geometry" > <property name="geometry" >
<rect> <rect>
<x>380</x> <x>380</x>
<y>70</y> <y>50</y>
<width>94</width> <width>94</width>
<height>162</height> <height>162</height>
</rect> </rect>
@@ -105,40 +104,29 @@
<property name="geometry" > <property name="geometry" >
<rect> <rect>
<x>0</x> <x>0</x>
<y>30</y> <y>40</y>
<width>481</width> <width>481</width>
<height>102</height> <height>102</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy" > <property name="sizePolicy" >
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text" > <property name="text" >
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>A bittorrent client using Qt4 and libtorrent, programmed in C++.&lt;br>
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;br>
p, li { white-space: pre-wrap; } Copyright © 2006 by Christophe Dumez&lt;br>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt; &lt;br> &lt;u>Home Page:&lt;/u> &lt;i>http://www.qbittorrent.org&lt;/i>&lt;br></string>
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A Bittorrent client programmed in C++, based on Qt4 toolkit &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and libtorrent-rasterbar. &lt;br /&gt;&lt;br /&gt;Copyright ©2006-2009 Christophe Dumez&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;Home Page:&lt;/span&gt; &lt;a href=&quot;http://www.qbittorrent.org&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;http://www.qbittorrent.org&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="textFormat" > <property name="textFormat" >
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>
</property> </property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment" > <property name="alignment" >
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget> </widget>
</widget> </widget>
<widget class="QWidget" name="tab3" > <widget class="QWidget" name="tab3" >
@@ -163,7 +151,7 @@ p, li { white-space: pre-wrap; }
<property name="sizeType" > <property name="sizeType" >
<enum>QSizePolicy::Preferred</enum> <enum>QSizePolicy::Preferred</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" >
<size> <size>
<width>20</width> <width>20</width>
<height>20</height> <height>20</height>
@@ -294,7 +282,7 @@ p, li { white-space: pre-wrap; }
<property name="sizeType" > <property name="sizeType" >
<enum>QSizePolicy::Preferred</enum> <enum>QSizePolicy::Preferred</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" >
<size> <size>
<width>20</width> <width>20</width>
<height>20</height> <height>20</height>
@@ -356,7 +344,7 @@ p, li { white-space: pre-wrap; }
<property name="orientation" > <property name="orientation" >
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" >
<size> <size>
<width>40</width> <width>40</width>
<height>20</height> <height>20</height>

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -46,8 +37,8 @@ class about : public QDialog, private Ui::AboutDlg{
setupUi(this); setupUi(this);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
// Set icons // Set icons
logo->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/qbittorrent22.png"))); logo->setPixmap(QPixmap(QString::fromUtf8(":/Icons/qbittorrent22.png")));
mascot_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/mascot.png"))); mascot_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/mascot.png")));
//Title //Title
lb_name->setText(QString::fromUtf8("<b><h1>")+tr("qBittorrent")+QString::fromUtf8(" "VERSION"</h1></b>")); lb_name->setText(QString::fromUtf8("<b><h1>")+tr("qBittorrent")+QString::fromUtf8(" "VERSION"</h1></b>"));
// Thanks // Thanks
@@ -66,11 +57,9 @@ class about : public QDialog, private Ui::AboutDlg{
- <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\ - <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\
- <u>Catalan:</u> Gekko Dam Beer (gekko04@users.sourceforge.net)<br>\ - <u>Catalan:</u> Gekko Dam Beer (gekko04@users.sourceforge.net)<br>\
- <u>Chinese (Simplified):</u> Guo Yue (yue.guo0418@gmail.com)<br>\ - <u>Chinese (Simplified):</u> Guo Yue (yue.guo0418@gmail.com)<br>\
- <u>Chinese (Traditional):</u> Yi-Shun Wang (dnextstep@gmail.com)<br>\
- <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\
- <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<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>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>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\
- <u>Greek:</u> Tsvetan Bankov (emerge_life@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>\ - <u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)<br>\
@@ -85,25 +74,13 @@ class about : public QDialog, private Ui::AboutDlg{
- <u>Slovak:</u> helix84<br>\ - <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>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>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>")); - <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->append(tr("Please contact me if you would like to translate qBittorrent into your own language."));
te_translation->scrollToAnchor(QString::fromUtf8("top")); te_translation->scrollToAnchor(QString::fromUtf8("top"));
// License // License
te_license->append(QString::fromUtf8("<a name='top'></a>")); te_license->append(QString::fromUtf8("<a name='top'></a>"));
te_license->append(QString::fromUtf8("qBittorrent is licensed under the GNU General Public License version 2 with the\ te_license->append(QString::fromUtf8("<center><b>GNU GENERAL PUBLIC LICENSE</b></center><br>\
addition of the following special exception:\
<br><br>\
<i>In addition, as a special exception, the copyright holders give permission to\
link this program with the OpenSSL project\'s \"OpenSSL\" library (or with\
modified versions of it that use the same license as the \"OpenSSL\" library),\
and distribute the linked executables. You must obey the GNU General Public\
License in all respects for all of the code used other than \"OpenSSL\". If you\
modify file(s), you may extend this exception to your version of the file(s),\
but you are not obligated to do so. If you do not wish to do so, delete this\
exception statement from your version.</i>\
<br><br>\
<center><b>GNU GENERAL PUBLIC LICENSE</b></center><br>\
<center>Version 2, June 1991</center><br>\ <center>Version 2, June 1991</center><br>\
Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br>\ Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br>\
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA<br>\ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA<br>\

View File

@@ -13,6 +13,21 @@
<string>Torrent addition dialog</string> <string>Torrent addition dialog</string>
</property> </property>
<layout class="QVBoxLayout" > <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> <item>
<widget class="QLabel" name="fileNameLbl" > <widget class="QLabel" name="fileNameLbl" >
<property name="text" > <property name="text" >
@@ -95,50 +110,6 @@
</property> </property>
</widget> </widget>
</item> </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> <item>
<widget class="QCheckBox" name="checkIncrementalDL" > <widget class="QCheckBox" name="checkIncrementalDL" >
<property name="text" > <property name="text" >

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -41,7 +32,7 @@ class torrent_file {
torrent_file *parent; torrent_file *parent;
bool is_dir; bool is_dir;
QString rel_path; QString rel_path;
QList<const torrent_file*> children; QList<torrent_file*> children;
size_type size; size_type size;
float progress; float progress;
int priority; int priority;
@@ -51,8 +42,6 @@ class torrent_file {
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){ 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){
qDebug("created a file with index %d", index); qDebug("created a file with index %d", index);
rel_path = QDir::cleanPath(path); rel_path = QDir::cleanPath(path);
Q_ASSERT(progress >= 0.);
Q_ASSERT(progress <= 1.);
if(parent) { if(parent) {
parent->updateProgress(); parent->updateProgress();
parent->updatePriority(priority); parent->updatePriority(priority);
@@ -77,9 +66,10 @@ class torrent_file {
progress = 0.; progress = 0.;
return; return;
} }
double wanted = 0.; float wanted = 0.;
double done = 0.; float done = 0.;
foreach(const torrent_file *child, children) { torrent_file *child;
foreach(child, children) {
wanted += child->getSize(); wanted += child->getSize();
done += child->getSize()*child->getProgress(); done += child->getSize()*child->getProgress();
} }
@@ -90,7 +80,8 @@ class torrent_file {
void updatePriority(int prio) { void updatePriority(int prio) {
Q_ASSERT(is_dir); Q_ASSERT(is_dir);
foreach(const torrent_file *child, children) { torrent_file *child;
foreach(child, children) {
if(child->getPriority() != prio) return; if(child->getPriority() != prio) return;
} }
priority = prio; priority = prio;
@@ -120,13 +111,14 @@ class torrent_file {
return (!children.isEmpty()); return (!children.isEmpty());
} }
QList<const torrent_file*> getChildren() const { QList<torrent_file*> getChildren() const {
return children; return children;
} }
const torrent_file* getChild(QString fileName) const { torrent_file* getChild(QString fileName) const {
Q_ASSERT(is_dir); Q_ASSERT(is_dir);
foreach(const torrent_file *f, children) { torrent_file* f;
foreach(f, children) {
if(f->name() == fileName) return f; if(f->name() == fileName) return f;
} }
return 0; return 0;
@@ -149,24 +141,25 @@ class torrent_file {
return f; return f;
} }
bool removeFromFS(QString saveDir) const { bool removeFromFS(QString saveDir) {
QString full_path = saveDir + QDir::separator() + rel_path; QString full_path = saveDir + QDir::separator() + rel_path;
if(!QFile::exists(full_path)) { if(!QFile::exists(full_path)) {
qDebug("%s does not exist, no need to remove it", full_path.toLocal8Bit().data()); qDebug("%s does not exist, no need to remove it", full_path.toUtf8().data());
return true; return true;
} }
bool success = true; bool success = true;
torrent_file *f;
qDebug("We have %d children", children.size()); qDebug("We have %d children", children.size());
foreach(const torrent_file *f, children) { foreach(f, children) {
bool s = f->removeFromFS(saveDir); bool s = f->removeFromFS(saveDir);
success = s && success; success = s && success;
} }
if(is_dir) { if(is_dir) {
qDebug("trying to remove directory: %s", full_path.toLocal8Bit().data()); qDebug("trying to remove directory: %s", full_path.toUtf8().data());
QDir dir(full_path); QDir dir(full_path);
dir.rmdir(full_path); dir.rmdir(full_path);
} else { } else {
qDebug("trying to remove file: %s", full_path.toLocal8Bit().data()); qDebug("trying to remove file: %s", full_path.toUtf8().data());
bool s = QFile::remove(full_path); bool s = QFile::remove(full_path);
success = s && success; success = s && success;
} }
@@ -179,27 +172,27 @@ class arborescence {
torrent_file *root; torrent_file *root;
public: public:
arborescence(boost::intrusive_ptr<torrent_info> t) { arborescence(torrent_info t) {
torrent_info::file_iterator fi = t->begin_files(); torrent_info::file_iterator fi = t.begin_files();
if(t->num_files() > 1) { if(t.num_files() > 1) {
root = new torrent_file(0, misc::toQString(t->name()), true); root = new torrent_file(0, misc::toQString(t.name()), true);
} else { } else {
// XXX: Will crash if there is no file in torrent // 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; return;
} }
int i = 0; int i = 0;
while(fi != t->end_files()) { while(fi != t.end_files()) {
QString path = QDir::cleanPath(misc::toQString(fi->path.string())); QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
addFile(path, fi->size, i); addFile(path, fi->size, i);
fi++; fi++;
++i; ++i;
} }
qDebug("real size: %ld, tree size: %ld", (long)t->total_size(), (long)root->getSize()); qDebug("real size: %ld, tree size: %ld", (long)t.total_size(), (long)root->getSize());
Q_ASSERT(root->getSize() == t->total_size()); 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(); torrent_info::file_iterator fi = t.begin_files();
if(t.num_files() > 1) { if(t.num_files() > 1) {
qDebug("More than one file in the torrent, setting a folder as root"); qDebug("More than one file in the torrent, setting a folder as root");
@@ -207,13 +200,13 @@ class arborescence {
} else { } else {
// XXX: Will crash if there is no file in torrent // XXX: Will crash if there is no file in torrent
qDebug("one file in the torrent, setting it as root with index 0"); 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, ((double)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; return;
} }
int i = 0; int i = 0;
while(fi != t.end_files()) { while(fi != t.end_files()) {
QString path = QDir::cleanPath(misc::toQString(fi->path.string())); QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
addFile(path, fi->size, i, ((double)fp[i])/t.file_at(i).size, prioritiesTab[i]); addFile(path, fi->size, i, fp[i], prioritiesTab[i]);
fi++; fi++;
++i; ++i;
} }
@@ -246,13 +239,14 @@ class arborescence {
if(relative_path.at(0) ==QDir::separator()) if(relative_path.at(0) ==QDir::separator())
relative_path.remove(0, 1); relative_path.remove(0, 1);
QStringList fileNames = relative_path.split(QDir::separator()); QStringList fileNames = relative_path.split(QDir::separator());
QString fileName;
torrent_file *dad = root; torrent_file *dad = root;
unsigned int nb_i = 0; unsigned int nb_i = 0;
unsigned int size = fileNames.size(); unsigned int size = fileNames.size();
foreach(const QString &fileName, fileNames) { foreach(fileName, fileNames) {
++nb_i; ++nb_i;
if(fileName == ".") continue; if(fileName == ".") continue;
const torrent_file* child = dad->getChild(fileName); torrent_file* child = dad->getChild(fileName);
if(!child) { if(!child) {
if(nb_i != size) { if(nb_i != size) {
// Folder // Folder
@@ -262,7 +256,7 @@ class arborescence {
child = dad->addChild(fileName, false, file_size, index, progress, priority); child = dad->addChild(fileName, false, file_size, index, progress, priority);
} }
} }
dad = (torrent_file*)child; dad = child;
} }
} }
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -16,25 +16,16 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
#ifndef __BITTORRENT_H__ #ifndef __BITTORRENT_H__
#define __BITTORRENT_H__ #define __BITTORRENT_H__
#include <QHash> #include <QHash>
#include <QList>
#include <QPair>
#include <QStringList> #include <QStringList>
#include <QApplication> #include <QDateTime>
#include <QPalette>
#include <QPointer>
#include <libtorrent/session.hpp> #include <libtorrent/session.hpp>
#include <libtorrent/ip_filter.hpp> #include <libtorrent/ip_filter.hpp>
@@ -43,9 +34,8 @@
using namespace libtorrent; using namespace libtorrent;
class downloadThread; class downloadThread;
class deleteThread;
class QTimer; class QTimer;
class QFileSystemWatcher;
class QMutex;
class FilterParserThread; class FilterParserThread;
class bittorrent : public QObject{ class bittorrent : public QObject{
@@ -53,45 +43,66 @@ class bittorrent : public QObject {
private: private:
session *s; session *s;
QPointer<QFileSystemWatcher> FSWatcher; QString scan_dir;
QMutex* FSMutex; QTimer *timerScan;
QPointer<QTimer> timerAlerts; QTimer *timerAlerts;
QPointer<QTimer> BigRatioTimer; QTimer *fastResumeSaver;
QTimer *BigRatioTimer;
bool DHTEnabled; bool DHTEnabled;
QPointer<downloadThread> downloader; downloadThread *downloader;
QString defaultSavePath; QString defaultSavePath;
QString defaultTempPath; QStringList torrentsToPauseAfterChecking;
QHash<QString, QDateTime> TorrentsStartTime;
QHash<QString, size_type> TorrentsStartData;
QHash<QString, QPair<size_type,size_type> > ratioData;
QHash<QString, QHash<QString, QString> > trackersErrors; QHash<QString, QHash<QString, QString> > trackersErrors;
QStringList consoleMessages; deleteThread *deleter;
QStringList peerBanMessages; QStringList finishedTorrents;
QStringList unfinishedTorrents;
bool preAllocateAll; bool preAllocateAll;
bool addInPause; bool addInPause;
int maxConnecsPerTorrent; int maxConnecsPerTorrent;
int maxUploadsPerTorrent; int maxUploadsPerTorrent;
float ratio_limit; float max_ratio;
bool UPnPEnabled; bool UPnPEnabled;
bool NATPMPEnabled; bool NATPMPEnabled;
bool LSDEnabled; bool LSDEnabled;
QPointer<FilterParserThread> filterParser; FilterParserThread *filterParser;
QString filterPath; QString filterPath;
int folderScanInterval; // in seconds
bool queueingEnabled; bool queueingEnabled;
QStringList url_skippingDlg; int maxActiveDownloads;
int maxActiveTorrents;
int currentActiveDownloads;
QStringList *downloadQueue;
QStringList *queuedDownloads;
QStringList *uploadQueue;
QStringList *queuedUploads;
bool calculateETA;
protected:
QString getSavePath(QString hash);
public: public:
// Constructor / Destructor // Constructor / Destructor
bittorrent(); bittorrent();
~bittorrent(); ~bittorrent();
QTorrentHandle getTorrentHandle(QString hash) const; QTorrentHandle getTorrentHandle(QString hash) const;
std::vector<torrent_handle> getTorrents() const; bool isPaused(QString hash) const;
bool isFilePreviewPossible(QString fileHash) const; bool isFilePreviewPossible(QString fileHash) const;
bool isDHTEnabled() const; bool isDHTEnabled() const;
float getPayloadDownloadRate() const; float getPayloadDownloadRate() const;
float getPayloadUploadRate() const; float getPayloadUploadRate() const;
session_status getSessionStatus() const; session_status getSessionStatus() const;
int getListenPort() const; int getListenPort() const;
QStringList getTorrentsToPauseAfterChecking() const;
qlonglong getETA(QString hash) const;
float getRealRatio(QString hash) const; float getRealRatio(QString hash) const;
session* getSession() const; session* getSession() const;
QHash<QString, QString> getTrackersErrors(QString hash) 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; bool has_filtered_files(QString hash) const;
unsigned int getFinishedPausedTorrentsNb() const; unsigned int getFinishedPausedTorrentsNb() const;
unsigned int getUnfinishedPausedTorrentsNb() const; unsigned int getUnfinishedPausedTorrentsNb() const;
@@ -100,43 +111,43 @@ class bittorrent : public QObject {
int getUpTorrentPriority(QString hash) const; int getUpTorrentPriority(QString hash) const;
int getMaximumActiveDownloads() const; int getMaximumActiveDownloads() const;
int getMaximumActiveTorrents() const; int getMaximumActiveTorrents() const;
bool isDownloadQueued(QString hash) const;
bool isUploadQueued(QString hash) const;
int loadTorrentPriority(QString hash); int loadTorrentPriority(QString hash);
QStringList getConsoleMessages() const;
QStringList getPeerBanMessages() const;
qlonglong getETA(QString hash) const;
bool useTemporaryFolder() const;
QString getSavePath(QString hash);
public slots: public slots:
QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false); void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
void loadSessionState();
void saveSessionState();
void downloadFromUrl(QString url); void downloadFromUrl(QString url);
void downloadFromURLList(const QStringList& url_list); void downloadFromURLList(const QStringList& url_list);
void deleteTorrent(QString hash, bool permanent = false); void deleteTorrent(QString hash, bool permanent = false);
/* Needed by Web UI */ bool pauseTorrent(QString hash);
bool resumeTorrent(QString hash);
void pauseAllTorrents(); void pauseAllTorrents();
void resumeAllTorrents(); void resumeAllTorrents();
void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
/* End Web UI */
void saveDHTEntry(); void saveDHTEntry();
void preAllocateAllFiles(bool b); void preAllocateAllFiles(bool b);
void saveFastResumeData(); void saveFastResumeAndRatioData();
void saveFastResumeAndRatioData(QString hash);
void enableDirectoryScanning(QString scan_dir); void enableDirectoryScanning(QString scan_dir);
void disableDirectoryScanning(); void disableDirectoryScanning();
void enablePeerExchange();
void enableIPFilter(QString filter); void enableIPFilter(QString filter);
void disableIPFilter(); void disableIPFilter();
void setQueueingEnabled(bool enable); void setQueueingEnabled(bool enable);
void resumeUnfinishedTorrents(); void resumeUnfinishedTorrents();
void saveTorrentPriority(QString hash, int prio);
void saveTorrentSpeedLimits(QString hash); void saveTorrentSpeedLimits(QString hash);
void loadTorrentSpeedLimits(QString hash); void loadTorrentSpeedLimits(QString hash);
void saveDownloadUploadForTorrent(QString hash);
void loadDownloadUploadForTorrent(QString hash);
void handleDownloadFailure(QString url, QString reason); void handleDownloadFailure(QString url, QString reason);
void loadWebSeeds(QString fileHash); void loadWebSeeds(QString fileHash);
void updateDownloadQueue();
void updateUploadQueue();
void increaseDlTorrentPriority(QString hash); void increaseDlTorrentPriority(QString hash);
void decreaseDlTorrentPriority(QString hash); void decreaseDlTorrentPriority(QString hash);
void downloadUrlAndSkipDialog(QString); void increaseUpTorrentPriority(QString hash);
void decreaseUpTorrentPriority(QString hash);
void saveTorrentPriority(QString hash, int prio);
// Session configuration - Setters // Session configuration - Setters
void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports); void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports);
void setMaxConnections(int maxConnec); void setMaxConnections(int maxConnec);
@@ -151,39 +162,58 @@ class bittorrent : public QObject {
void setSessionSettings(session_settings sessionSettings); void setSessionSettings(session_settings sessionSettings);
void startTorrentsInPause(bool b); void startTorrentsInPause(bool b);
void setDefaultSavePath(QString savepath); void setDefaultSavePath(QString savepath);
void setDefaultTempPath(QString temppath);
void applyEncryptionSettings(pe_settings se); void applyEncryptionSettings(pe_settings se);
void loadFilesPriorities(QTorrentHandle& h); void loadFilesPriorities(QTorrentHandle& h);
void setDownloadLimit(QString hash, long val); void setDownloadLimit(QString hash, long val);
void setUploadLimit(QString hash, long val); void setUploadLimit(QString hash, long val);
void setUnfinishedTorrent(QString hash);
void setFinishedTorrent(QString hash);
void enableUPnP(bool b); void enableUPnP(bool b);
void enableNATPMP(bool b); void enableNATPMP(bool b);
void enableLSD(bool b); void enableLSD(bool b);
bool enableDHT(bool b); bool enableDHT(bool b);
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText)); void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
void addPeerBanMessage(QString msg, bool from_ipfilter); void setTimerScanInterval(int secs);
void processDownloadedFile(QString, QString); void setMaxActiveDownloads(int val);
void setMaxActiveTorrents(int val);
void setETACalculation(bool enable);
protected slots: protected slots:
void scanDirectory(QString); void scanDirectory();
void readAlerts(); void readAlerts();
void processDownloadedFile(QString, QString);
bool loadTrackerFile(QString hash); bool loadTrackerFile(QString hash);
void saveTrackerFile(QString hash); void saveTrackerFile(QString hash);
void deleteBigRatios(); void deleteBigRatios();
signals: signals:
void addedTorrent(QTorrentHandle& h); void invalidTorrent(QString path);
void duplicateTorrent(QString path);
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume);
void deletedTorrent(QString hash); void deletedTorrent(QString hash);
void pausedTorrent(QTorrentHandle& h); void pausedTorrent(QString hash);
void resumedTorrent(QTorrentHandle& h); void resumedTorrent(QString hash);
void finishedTorrent(QTorrentHandle& h); void finishedTorrent(QTorrentHandle& h);
void fullDiskError(QTorrentHandle& h, QString msg); void fullDiskError(QTorrentHandle& h);
void trackerError(QString hash, QString time, QString msg); void trackerError(QString hash, QString time, QString msg);
void portListeningFailure();
void trackerAuthenticationRequired(QTorrentHandle& h); void trackerAuthenticationRequired(QTorrentHandle& h);
void scanDirFoundTorrents(const QStringList& pathList);
void newDownloadedTorrent(QString path, QString url); void newDownloadedTorrent(QString path, QString url);
void aboutToDownloadFromUrl(QString url);
void updateFileSize(QString hash); void updateFileSize(QString hash);
void peerBlocked(QString);
void downloadFromUrlFailure(QString url, QString reason); 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 #endif

View File

@@ -1,58 +0,0 @@
<ui version="4.0" >
<class>ConsoleDlg</class>
<widget class="QDialog" name="ConsoleDlg" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>512</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle" >
<string>qBittorrent console</string>
</property>
<property name="windowIcon" >
<iconset resource="icons.qrc" >:/Icons/oxygen/log.png</iconset>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QTabWidget" name="tabConsole" >
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="tab" >
<attribute name="title" >
<string>General</string>
</attribute>
<attribute name="icon" >
<iconset resource="icons.qrc" >:/Icons/oxygen/log.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<item>
<widget class="QTextBrowser" name="textConsole" />
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2" >
<attribute name="title" >
<string>Blocked IPs</string>
</attribute>
<attribute name="icon" >
<iconset resource="icons.qrc" >:/Icons/filter.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<item>
<widget class="QTextBrowser" name="textBannedPeers" />
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="icons.qrc" />
</resources>
<connections/>
</ui>

View File

@@ -1,59 +0,0 @@
/*
* 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.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef CONSOLE_H
#define CONSOLE_H
#include "bittorrent.h"
#include "ui_console.h"
using namespace libtorrent;
class consoleDlg : public QDialog, private Ui_ConsoleDlg{
Q_OBJECT
private:
bittorrent *BTSession;
public:
consoleDlg(QWidget *parent, bittorrent* _BTSession) : QDialog(parent) {
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
BTSession = _BTSession;
textConsole->setHtml(BTSession->getConsoleMessages().join("<br>"));
textBannedPeers->setHtml(BTSession->getPeerBanMessages().join("<br>"));
show();
}
~consoleDlg() {}
};
#endif

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -35,7 +26,6 @@
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/bind.hpp>
#include <libtorrent/entry.hpp> #include <libtorrent/entry.hpp>
#include <libtorrent/bencode.hpp> #include <libtorrent/bencode.hpp>
@@ -44,7 +34,6 @@
#include <libtorrent/storage.hpp> #include <libtorrent/storage.hpp>
#include <libtorrent/hasher.hpp> #include <libtorrent/hasher.hpp>
#include <libtorrent/file_pool.hpp> #include <libtorrent/file_pool.hpp>
#include <libtorrent/create_torrent.hpp>
#include "createtorrent_imp.h" #include "createtorrent_imp.h"
#include "misc.h" #include "misc.h"
@@ -52,23 +41,13 @@
using namespace libtorrent; using namespace libtorrent;
using namespace boost::filesystem; 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){ createtorrent::createtorrent(QWidget *parent): QDialog(parent){
setupUi(this); setupUi(this);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
creatorThread = new torrentCreatorThread(this); creatorThread = new torrentCreatorThread();
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*)), this, SLOT(handleCreationSuccess(QString, const char*))); connect(creatorThread, SIGNAL(creationSuccess(QString)), this, SLOT(handleCreationSucess(QString)));
connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString))); connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString)));
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int))); connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
path::default_name_check(no_check);
show(); show();
} }
@@ -147,6 +126,20 @@ 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));
}
}
QStringList createtorrent::allItems(QListWidget *list){ QStringList createtorrent::allItems(QListWidget *list){
QStringList res; QStringList res;
unsigned int nbItems = list->count(); unsigned int nbItems = list->count();
@@ -184,19 +177,12 @@ void createtorrent::on_createButton_clicked(){
void createtorrent::handleCreationFailure(QString msg) { void createtorrent::handleCreationFailure(QString msg) {
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(msg)); QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(msg));
hide();
} }
void createtorrent::handleCreationSuccess(QString path, const char* branch_path) { void createtorrent::handleCreationSuccess(QString path, const char* branch_path, QString hash) {
if(checkStartSeeding->isChecked()) { if(checkStartSeeding->isChecked()) {
// Create save path file // Create save path file
boost::intrusive_ptr<torrent_info> t;
try {
t = new torrent_info(path.toLocal8Bit().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")); QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text); savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
savepath_file.write(branch_path); savepath_file.write(branch_path);
@@ -204,7 +190,7 @@ void createtorrent::handleCreationSuccess(QString path, const char* branch_path)
emit torrent_to_seed(path); emit torrent_to_seed(path);
} }
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path); QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
close(); hide();
} }
void createtorrent::updateProgressBar(int progress) { void createtorrent::updateProgressBar(int progress) {
@@ -227,49 +213,54 @@ void torrentCreatorThread::create(QString _input_path, QString _save_path, QStri
start(); start();
} }
void sendProgressUpdateSignal(int i, int num, torrentCreatorThread *parent){
parent->sendProgressSignal((int)(i*100./(float)num));
}
void torrentCreatorThread::sendProgressSignal(int progress) {
emit updateProgress(progress);
}
void torrentCreatorThread::run() { void torrentCreatorThread::run() {
emit updateProgress(0); emit updateProgress(0);
char const* creator_str = "qBittorrent "VERSION; char const* creator_str = "qBittorrent "VERSION;
try { try {
file_storage fs; boost::intrusive_ptr<torrent_info> t(new torrent_info);
file_pool fp; ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
path full_path = complete(path(input_path.toLocal8Bit().data()));
// Adding files to the torrent // Adding files to the torrent
add_files(fs, full_path, file_filter); path full_path = complete(path(input_path.toUtf8().data()));
add_files(*t, full_path.branch_path(), full_path.leaf());
if(abort) return; if(abort) return;
create_torrent t(fs, piece_size); // Set piece size
t->set_piece_size(piece_size);
// Add url seeds // Add url seeds
QString seed; QString seed;
foreach(seed, url_seeds){ foreach(seed, url_seeds){
t.add_url_seed(seed.toLocal8Bit().data()); t->add_url_seed(seed.toUtf8().data());
} }
for(int i=0; i<trackers.size(); ++i){ for(int i=0; i<trackers.size(); ++i){
t.add_tracker(trackers.at(i).toLocal8Bit().data()); t->add_tracker(trackers.at(i).toUtf8().data());
} }
if(abort) return; if(abort) return;
// calculate the hash for all pieces // calculate the hash for all pieces
set_piece_hashes(t, full_path.branch_path(), boost::bind<void>(&sendProgressUpdateSignal, _1, t.num_pieces(), this)); 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 // Set qBittorrent as creator and add user comment to
// torrent_info structure // torrent_info structure
t.set_creator(creator_str); t->set_creator(creator_str);
t.set_comment((const char*)comment.toLocal8Bit()); t->set_comment((const char*)comment.toUtf8());
// Is private ? // Is private ?
t.set_priv(is_private); if(is_private){
t->set_priv(true);
}
if(abort) return; if(abort) return;
// create the torrent and print it to out // create the torrent and print it to out
ofstream out(complete(path((const char*)save_path.toLocal8Bit())), std::ios_base::binary); entry e = t->create_torrent();
bencode(std::ostream_iterator<char>(out), t.generate()); libtorrent::bencode(std::ostream_iterator<char>(out), e);
out.flush();
emit updateProgress(100); 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){ catch (std::exception& e){
emit creationFailure(QString::fromUtf8(e.what())); emit creationFailure(QString::fromUtf8(e.what()));

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -46,27 +37,21 @@ class torrentCreatorThread : public QThread {
bool is_private; bool is_private;
int piece_size; int piece_size;
bool abort; bool abort;
QDialog *parent;
public: public:
torrentCreatorThread(QDialog *_parent) { torrentCreatorThread() {}
parent = _parent;
}
~torrentCreatorThread() { ~torrentCreatorThread() {
abort = true; abort = true;
wait(); wait();
} }
void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size); void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size);
void sendProgressSignal(int progress);
protected: protected:
void run(); void run();
signals: signals:
void creationFailure(QString msg); void creationFailure(QString msg);
void creationSuccess(QString path, const char* branch_path); void creationSuccess(QString path, const char* branch_path, QString hash);
signals:
void updateProgress(int progress); void updateProgress(int progress);
}; };
@@ -85,9 +70,6 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
signals: signals:
void torrent_to_seed(QString path); void torrent_to_seed(QString path);
public slots:
void updateProgressBar(int progress);
protected slots: protected slots:
void on_createButton_clicked(); void on_createButton_clicked();
void on_addFile_button_clicked(); void on_addFile_button_clicked();
@@ -97,7 +79,8 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
void on_addURLSeed_button_clicked(); void on_addURLSeed_button_clicked();
void on_removeURLSeed_button_clicked(); void on_removeURLSeed_button_clicked();
void handleCreationFailure(QString msg); 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 #endif

125
src/deleteThread.h Normal file
View File

@@ -0,0 +1,125 @@
/*
* 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;
bool abort;
public:
subDeleteThread(QObject *parent, QString saveDir, arborescence *arb) : QThread(parent), save_path(saveDir), arb(arb), abort(false){}
~subDeleteThread(){
abort = true;
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);
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.size() != 0){
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

View File

@@ -18,7 +18,16 @@
<property name="spacing" > <property name="spacing" >
<number>6</number> <number>6</number>
</property> </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> <number>0</number>
</property> </property>
<item> <item>
@@ -48,6 +57,95 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QTabWidget" name="tabBottom" >
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>142</height>
</size>
</property>
<property name="tabPosition" >
<enum>QTabWidget::West</enum>
</property>
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="log_tab" >
<attribute name="title" >
<string>Log</string>
</attribute>
<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="QTextBrowser" name="infoBar" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
<property name="contextMenuPolicy" >
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="filter_tab" >
<attribute name="title" >
<string>IP filter</string>
</attribute>
<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="QTextBrowser" name="textBlockedUsers" >
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>123</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout> </layout>
<action name="actionStart" > <action name="actionStart" >
<property name="text" > <property name="text" >
@@ -64,6 +162,11 @@
<string>Delete</string> <string>Delete</string>
</property> </property>
</action> </action>
<action name="actionClearLog" >
<property name="text" >
<string>Clear</string>
</property>
</action>
<action name="actionPreview_file" > <action name="actionPreview_file" >
<property name="text" > <property name="text" >
<string>Preview file</string> <string>Preview file</string>
@@ -91,8 +194,7 @@
</action> </action>
<action name="actionOpen_destination_folder" > <action name="actionOpen_destination_folder" >
<property name="icon" > <property name="icon" >
<iconset resource="icons.qrc" > <iconset resource="icons.qrc" >:/Icons/folder.png</iconset>
<normaloff>:/Icons/oxygen/folder.png</normaloff>:/Icons/oxygen/folder.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Open destination folder</string> <string>Open destination folder</string>
@@ -140,8 +242,7 @@
</action> </action>
<action name="actionBuy_it" > <action name="actionBuy_it" >
<property name="icon" > <property name="icon" >
<iconset resource="icons.qrc" > <iconset resource="icons.qrc" >:/Icons/money.png</iconset>
<normaloff>:/Icons/money.png</normaloff>:/Icons/money.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Buy it</string> <string>Buy it</string>
@@ -154,8 +255,7 @@
</action> </action>
<action name="actionIncreasePriority" > <action name="actionIncreasePriority" >
<property name="icon" > <property name="icon" >
<iconset resource="icons.qrc" > <iconset resource="icons.qrc" >:/Icons/skin/increase.png</iconset>
<normaloff>:/Icons/skin/increase.png</normaloff>:/Icons/skin/increase.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Increase priority</string> <string>Increase priority</string>
@@ -163,22 +263,12 @@
</action> </action>
<action name="actionDecreasePriority" > <action name="actionDecreasePriority" >
<property name="icon" > <property name="icon" >
<iconset resource="icons.qrc" > <iconset resource="icons.qrc" >:/Icons/skin/decrease.png</iconset>
<normaloff>:/Icons/skin/decrease.png</normaloff>:/Icons/skin/decrease.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Decrease priority</string> <string>Decrease priority</string>
</property> </property>
</action> </action>
<action name="actionForce_recheck" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/oxygen/gear.png</normaloff>:/Icons/oxygen/gear.png</iconset>
</property>
<property name="text" >
<string>Force recheck</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="icons.qrc" /> <include location="icons.qrc" />

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -84,29 +75,29 @@ void subDownloadThread::run(){
filePath = tmpfile->fileName(); filePath = tmpfile->fileName();
} }
delete tmpfile; delete tmpfile;
FILE *f = fopen(filePath.toLocal8Bit().data(), "wb"); FILE *f = fopen(filePath.toUtf8().data(), "wb");
if(!f) { if(!f) {
std::cerr << "couldn't open destination file" << "\n"; std::cerr << "couldn't open destination file" << "\n";
return; return;
} }
CURL *curl; CURL *curl;
CURLcode res = (CURLcode)-1; CURLcode res;
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) { if(curl) {
std::string c_url = url.toLocal8Bit().data(); std::string c_url = url.toUtf8().data();
curl_easy_setopt(curl, CURLOPT_URL, c_url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, c_url.c_str());
// SSL support // SSL support
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
// PROXY SUPPORT // PROXY SUPPORT
QSettings settings("qBittorrent", "qBittorrent"); 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) { if(intValue > 0) {
// Proxy enabled // Proxy enabled
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString(); QString IP = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/IP"), "0.0.0.0").toString();
QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString(); QString port = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Port"), 8080).toString();
qDebug("Using proxy: %s", (IP+QString(":")+port).toLocal8Bit().data()); qDebug("Using proxy: %s", (IP+QString(":")+port).toUtf8().data());
curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toLocal8Bit().data()); curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toUtf8().data());
// Default proxy type is HTTP, we must change if it is SOCKS5 // Default proxy type is HTTP, we must change if it is SOCKS5
if(intValue%2==0) { if(intValue%2==0) {
qDebug("Proxy is SOCKS5, not HTTP"); qDebug("Proxy is SOCKS5, not HTTP");
@@ -115,9 +106,9 @@ void subDownloadThread::run(){
// Authentication? // Authentication?
if(intValue > 2) { if(intValue > 2) {
qDebug("Proxy requires authentication, authenticating"); qDebug("Proxy requires authentication, authenticating");
QString username = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Username"), QString()).toString(); QString username = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Username"), QString()).toString();
QString password = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Password"), QString()).toString(); QString password = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Password"), QString()).toString();
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toLocal8Bit().data()); curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toUtf8().data());
} }
} }
// We have to define CURLOPT_WRITEFUNCTION or it will crash on windows // We have to define CURLOPT_WRITEFUNCTION or it will crash on windows
@@ -131,14 +122,11 @@ void subDownloadThread::run(){
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1); curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1); curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1);
qDebug("Downloading %s", url.toLocal8Bit().data()); qDebug("Downloading %s", url.toUtf8().data());
if(!abort)
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
/* always cleanup */ /* always cleanup */
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
fclose(f); fclose(f);
if(abort)
return;
if(res) { if(res) {
emit downloadFailureST(this, url, errorCodeToString(res)); emit downloadFailureST(this, url, errorCodeToString(res));
} else { } else {

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
#include "downloadingTorrents.h" #include "downloadingTorrents.h"
@@ -42,19 +33,20 @@
#include <QTime> #include <QTime>
#include <QMenu> #include <QMenu>
DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbTorrents(0) { DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), delayedSorting(false), nbTorrents(0) {
setupUi(this); setupUi(this);
// Setting icons // Setting icons
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png"))); actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png"))); actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png"))); actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
actionClearLog->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png"))); actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))); actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))); actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png"))); actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png"))); actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/oxygen/log.png"))); // tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/oxygen/filter.png"))); // tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.png")));
// Set Download list model // Set Download list model
DLListModel = new QStandardItemModel(0,10); DLListModel = new QStandardItemModel(0,10);
@@ -68,8 +60,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
DLListModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left")); DLListModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left"));
DLListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority")); DLListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority"));
downloadList->setModel(DLListModel); downloadList->setModel(DLListModel);
downloadList->setRootIsDecorated(false);
downloadList->setAllColumnsShowFocus(true);
DLDelegate = new DLListDelegate(downloadList); DLDelegate = new DLListDelegate(downloadList);
downloadList->setItemDelegate(DLDelegate); downloadList->setItemDelegate(DLDelegate);
// Hide priority column // Hide priority column
@@ -78,7 +68,17 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
downloadList->hideColumn(HASH); downloadList->hideColumn(HASH);
loadHiddenColumns(); loadHiddenColumns();
connect(BTSession, SIGNAL(torrentFinishedChecking(QTorrentHandle&)), this, SLOT(sortProgressColumn(QTorrentHandle&))); connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool)));
connect(BTSession, SIGNAL(duplicateTorrent(QString)), this, SLOT(torrentDuplicate(QString)));
connect(BTSession, SIGNAL(invalidTorrent(QString)), this, SLOT(torrentCorrupted(QString)));
connect(BTSession, SIGNAL(portListeningFailure()), this, SLOT(portListeningFailure()));
connect(BTSession, SIGNAL(peerBlocked(QString)), this, SLOT(addLogPeerBlocked(const QString)));
connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString)));
connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString)));
connect(BTSession, SIGNAL(urlSeedProblem(QString, QString)), this, SLOT(addUrlSeedError(QString, QString)));
connect(BTSession, SIGNAL(UPnPError(QString)), this, SLOT(displayUPnPError(QString)));
connect(BTSession, SIGNAL(UPnPSuccess(QString)), this, SLOT(displayUPnPSuccess(QString)));
connect(BTSession, SIGNAL(forceUnfinishedListUpdate()), this, SLOT(updateDlList()));
// Load last columns width for download list // Load last columns width for download list
if(!loadColWidthDLList()) { if(!loadColWidthDLList()) {
@@ -89,10 +89,11 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
downloadList->header()->setSortIndicatorShown(true); downloadList->header()->setSortIndicatorShown(true);
// Connecting Actions to slots // Connecting Actions to slots
connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&))); connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(toggleDownloadListSortOrder(int))); connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortDownloadList(int)));
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&))); connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&)));
downloadList->header()->setContextMenuPolicy(Qt::CustomContextMenu); downloadList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(downloadList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLHoSMenu(const QPoint&))); connect(downloadList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLHoSMenu(const QPoint&)));
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&)));
// Actions // Actions
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered())); connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered())); connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered()));
@@ -103,7 +104,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered())); connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder())); connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection())); connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
connect(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage())); connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName())); connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
@@ -117,7 +117,7 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
connect(actionHOSColPriority, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPriority())); connect(actionHOSColPriority, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPriority()));
// Set info Bar infos // Set info Bar infos
BTSession->addConsoleMessage(tr("qBittorrent %1 started.", "e.g: qBittorrent v0.x started.").arg(QString::fromUtf8(""VERSION))); setInfoBar(tr("qBittorrent %1 started.", "e.g: qBittorrent v0.x started.").arg(QString::fromUtf8(""VERSION)));
qDebug("Download tab built"); qDebug("Download tab built");
} }
@@ -142,6 +142,16 @@ void DownloadingTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
emit torrentDoubleClicked(hash, false); emit torrentDoubleClicked(hash, false);
} }
void DownloadingTorrents::addLogPeerBlocked(QString ip) {
static unsigned int nbLines = 0;
++nbLines;
if(nbLines > 200) {
textBlockedUsers->clear();
nbLines = 1;
}
textBlockedUsers->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - ")+tr("<font color='red'>%1</font> <i>was blocked</i>", "x.y.z.w was blocked").arg(ip));
}
unsigned int DownloadingTorrents::getNbTorrentsInList() const { unsigned int DownloadingTorrents::getNbTorrentsInList() const {
return nbTorrents; return nbTorrents;
} }
@@ -157,7 +167,7 @@ void DownloadingTorrents::pauseTorrent(QString hash) {
DLListModel->setData(DLListModel->index(row, NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
//DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
setRowColor(row, QString::fromUtf8("red")); setRowColor(row, QString::fromUtf8("red"));
} }
@@ -166,6 +176,12 @@ QString DownloadingTorrents::getHashFromRow(unsigned int row) const {
return DLListModel->data(DLListModel->index(row, HASH)).toString(); return DLListModel->data(DLListModel->index(row, HASH)).toString();
} }
void DownloadingTorrents::setBottomTabEnabled(unsigned int index, bool b){
if(index and !b)
tabBottom->setCurrentIndex(0);
tabBottom->setTabEnabled(index, b);
}
// Show torrent properties dialog // Show torrent properties dialog
void DownloadingTorrents::showProperties(const QModelIndex &index) { void DownloadingTorrents::showProperties(const QModelIndex &index) {
showPropertiesFromHash(DLListModel->data(DLListModel->index(index.row(), HASH)).toString()); showPropertiesFromHash(DLListModel->data(DLListModel->index(index.row(), HASH)).toString());
@@ -179,6 +195,13 @@ void DownloadingTorrents::showPropertiesFromHash(QString hash) {
prop->show(); prop->show();
} }
void DownloadingTorrents::resumeTorrent(QString hash){
int row = getRowFromHash(hash);
Q_ASSERT(row != -1);
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
// Remove a torrent from the download list but NOT from the BT Session // Remove a torrent from the download list but NOT from the BT Session
void DownloadingTorrents::deleteTorrent(QString hash) { void DownloadingTorrents::deleteTorrent(QString hash) {
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
@@ -191,10 +214,39 @@ void DownloadingTorrents::deleteTorrent(QString hash) {
emit unfinishedTorrentsNumberChanged(nbTorrents); emit unfinishedTorrentsNumberChanged(nbTorrents);
} }
void DownloadingTorrents::displayUPnPError(QString msg) {
setInfoBar(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(msg), QColor("red"));
}
void DownloadingTorrents::displayUPnPSuccess(QString msg) {
DownloadingTorrents::setInfoBar(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(msg), QColor("blue"));
}
// Update Info Bar information
void DownloadingTorrents::setInfoBar(QString info, QColor color) {
static unsigned int nbLines = 0;
++nbLines;
// Check log size, clear it if too big
if(nbLines > 200) {
infoBar->clear();
nbLines = 1;
}
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>"));
}
void DownloadingTorrents::addFastResumeRejectedAlert(QString name) {
setInfoBar(tr("Fast resume data was rejected for torrent %1, checking again...").arg(name), QString::fromUtf8("red"));
}
void DownloadingTorrents::addUrlSeedError(QString url, QString msg) {
setInfoBar(tr("Url seed lookup failed for url: %1, message: %2").arg(url).arg(msg), QString::fromUtf8("red"));
}
void DownloadingTorrents::on_actionSet_download_limit_triggered() { void DownloadingTorrents::on_actionSet_download_limit_triggered() {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QModelIndex index;
QStringList hashes; QStringList hashes;
foreach(const QModelIndex &index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == NAME) { if(index.column() == NAME) {
// Get the file hash // Get the file hash
hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
@@ -206,8 +258,9 @@ void DownloadingTorrents::on_actionSet_download_limit_triggered() {
void DownloadingTorrents::on_actionSet_upload_limit_triggered() { void DownloadingTorrents::on_actionSet_upload_limit_triggered() {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QModelIndex index;
QStringList hashes; QStringList hashes;
foreach(const QModelIndex &index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == NAME) { if(index.column() == NAME) {
// Get the file hash // Get the file hash
hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
@@ -220,30 +273,21 @@ void DownloadingTorrents::on_actionSet_upload_limit_triggered() {
// display properties of selected items // display properties of selected items
void DownloadingTorrents::propertiesSelection(){ void DownloadingTorrents::propertiesSelection(){
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){ QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == NAME){ if(index.column() == NAME){
showProperties(index); showProperties(index);
} }
} }
} }
void DownloadingTorrents::forceRecheck() { void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){
if(index.column() == NAME){
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
QTorrentHandle h = BTSession->getTorrentHandle(hash);
h.force_recheck();
}
}
}
void DownloadingTorrents::displayDLListMenu(const QPoint&) {
QMenu myDLLlistMenu(this); QMenu myDLLlistMenu(this);
QModelIndex index;
// Enable/disable pause/start action given the DL state // Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
bool has_pause = false, has_start = false, has_preview = false; bool has_pause = false, has_start = false, has_preview = false;
foreach(const QModelIndex &index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == NAME) { if(index.column() == NAME) {
// Get the file name // Get the file name
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
@@ -275,8 +319,6 @@ void DownloadingTorrents::displayDLListMenu(const QPoint&) {
myDLLlistMenu.addAction(actionSet_download_limit); myDLLlistMenu.addAction(actionSet_download_limit);
myDLLlistMenu.addAction(actionSet_upload_limit); myDLLlistMenu.addAction(actionSet_upload_limit);
myDLLlistMenu.addSeparator(); myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionForce_recheck);
myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionOpen_destination_folder); myDLLlistMenu.addAction(actionOpen_destination_folder);
myDLLlistMenu.addAction(actionTorrent_Properties); myDLLlistMenu.addAction(actionTorrent_Properties);
if(BTSession->isQueueingEnabled()) { if(BTSession->isQueueingEnabled()) {
@@ -287,7 +329,8 @@ void DownloadingTorrents::displayDLListMenu(const QPoint&) {
myDLLlistMenu.addSeparator(); myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionBuy_it); myDLLlistMenu.addAction(actionBuy_it);
// Call menu // Call menu
myDLLlistMenu.exec(QCursor::pos()); // XXX: why mapToGlobal() is not enough?
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,35));
} }
@@ -327,13 +370,21 @@ void DownloadingTorrents::hideOrShowColumn(int index) {
if(nbVisibleColumns <= 1) return; if(nbVisibleColumns <= 1) return;
// User can hide the column, do it. // User can hide the column, do it.
downloadList->setColumnHidden(index, true); downloadList->setColumnHidden(index, true);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png"))); getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
--nbVisibleColumns; --nbVisibleColumns;
if(index == ETA) {
BTSession->setETACalculation(false);
qDebug("Disable ETA calculation");
}
} else { } else {
// User want to display the column // User want to display the column
downloadList->setColumnHidden(index, false); downloadList->setColumnHidden(index, false);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png"))); getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
++nbVisibleColumns; ++nbVisibleColumns;
if(index == ETA) {
BTSession->setETACalculation(true);
qDebug("Enable ETA calculation");
}
} }
//resize all others non-hidden columns //resize all others non-hidden columns
for(unsigned int i=0; i<nbCols; ++i) { for(unsigned int i=0; i<nbCols; ++i) {
@@ -345,10 +396,6 @@ void DownloadingTorrents::hideOrShowColumn(int index) {
void DownloadingTorrents::hidePriorityColumn(bool hide) { void DownloadingTorrents::hidePriorityColumn(bool hide) {
downloadList->setColumnHidden(PRIORITY, hide); downloadList->setColumnHidden(PRIORITY, hide);
if(hide)
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png")));
else
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png")));
} }
// save the hidden columns in settings // save the hidden columns in settings
@@ -386,9 +433,9 @@ bool DownloadingTorrents::loadHiddenColumns() {
for(int i=0; i<DLListModel->columnCount()-1; i++) { for(int i=0; i<DLListModel->columnCount()-1; i++) {
if(loaded && ishidden_list.at(i) == "0") { if(loaded && ishidden_list.at(i) == "0") {
downloadList->setColumnHidden(i, true); downloadList->setColumnHidden(i, true);
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png"))); getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
} else { } else {
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png"))); getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
} }
} }
return loaded; return loaded;
@@ -430,6 +477,10 @@ void DownloadingTorrents::hideOrShowColumnPriority() {
hideOrShowColumn(PRIORITY); hideOrShowColumn(PRIORITY);
} }
void DownloadingTorrents::on_actionClearLog_triggered() {
infoBar->clear();
}
// getter, return the action hide or show whose id is index // getter, return the action hide or show whose id is index
QAction* DownloadingTorrents::getActionHoSCol(int index) { QAction* DownloadingTorrents::getActionHoSCol(int index) {
switch(index) { switch(index) {
@@ -467,8 +518,9 @@ QAction* DownloadingTorrents::getActionHoSCol(int index) {
QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
QStringList res; QStringList res;
QModelIndex index;
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == NAME) { if(index.column() == NAME) {
// Get the file hash // Get the file hash
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
@@ -479,11 +531,33 @@ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
return res; return res;
} }
void DownloadingTorrents::displayInfoBarMenu(const QPoint& pos) {
// Log Menu
QMenu myLogMenu(this);
myLogMenu.addAction(actionClearLog);
// XXX: Why mapToGlobal() is not enough?
myLogMenu.exec(mapToGlobal(pos)+QPoint(44,305));
}
void DownloadingTorrents::sortProgressColumnDelayed() {
if(delayedSorting) {
sortDownloadListFloat(PROGRESS, delayedSortingOrder);
qDebug("Delayed sorting of progress column");
}
}
// get information from torrent handles and // get information from torrent handles and
// update download list accordingly // update download list accordingly
bool DownloadingTorrents::updateTorrent(QTorrentHandle h) { void DownloadingTorrents::updateDlList() {
if(!h.is_valid()) return false; // browse handles
bool added = false; QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents();
QString hash;
foreach(hash, unfinishedTorrents) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(!h.is_valid()){
qDebug("We have an invalid handle for: %s", qPrintable(hash));
continue;
}
try{ try{
QString hash = h.hash(); QString hash = h.hash();
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
@@ -491,43 +565,69 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
qDebug("Info: Could not find filename in download list, adding it..."); qDebug("Info: Could not find filename in download list, adding it...");
addTorrent(hash); addTorrent(hash);
row = getRowFromHash(hash); row = getRowFromHash(hash);
added = true;
} }
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
// Update Priority // Update Priority
if(BTSession->isQueueingEnabled()) { if(BTSession->isQueueingEnabled()) {
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash))); DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
if(h.is_queued()) { if(h.is_paused() && BTSession->isDownloadQueued(hash)) {
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
}else {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole);
if(!downloadList->isColumnHidden(ETA)) { if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
} }
}
// Reset speeds and seeds/leech
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant("0/0"));
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
return added;
} }
} }
if(!downloadList->isColumnHidden(PROGRESS))
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
// No need to update a paused torrent // No need to update a paused torrent
if(h.is_paused()) return added; if(h.is_paused()) continue;
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
continue;
}
// Parse download state // Parse download state
// Setting download state // Setting download state
switch(h.state()) { switch(h.state()) {
case torrent_status::finished:
case torrent_status::seeding:
qDebug("A torrent that was in download tab just finished, moving it to finished tab");
BTSession->setUnfinishedTorrent(hash);
emit torrentFinished(hash);
deleteTorrent(hash);
continue;
case torrent_status::checking_files: case torrent_status::checking_files:
case torrent_status::queued_for_checking: case torrent_status::queued_for_checking:
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
break;
case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0) {
// Display "Downloading" status when connecting if download speed > 0
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
}
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("green"));
}else{
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
}
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
if(!downloadList->isColumnHidden(DLSPEED)) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
}
if(!downloadList->isColumnHidden(UPSPEED)) {
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate()));
}
break; break;
case torrent_status::downloading: case torrent_status::downloading:
case torrent_status::downloading_metadata: case torrent_status::downloading_metadata:
@@ -544,6 +644,9 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
} }
setRowColor(row, QApplication::palette().color(QPalette::WindowText)); setRowColor(row, QApplication::palette().color(QPalette::WindowText));
} }
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
if(!downloadList->isColumnHidden(DLSPEED)) { if(!downloadList->isColumnHidden(DLSPEED)) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate())); DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
} }
@@ -557,25 +660,24 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
} }
} }
if(!downloadList->isColumnHidden(SEEDSLEECH)) { if(!downloadList->isColumnHidden(SEEDSLEECH)) {
QString tmp = misc::toQString(h.num_seeds(), true); DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+QString::fromUtf8("/")+misc::toQString(h.num_peers() - h.num_seeds(), true)));
if(h.num_complete() >= 0)
tmp.append(QString("(")+misc::toQString(h.num_complete())+QString(")"));
tmp.append(QString("/")+misc::toQString(h.num_peers() - h.num_seeds(), true));
if(h.num_incomplete() >= 0)
tmp.append(QString("(")+misc::toQString(h.num_incomplete())+QString(")"));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(tmp));
} }
if(!downloadList->isColumnHidden(RATIO)) { if(!downloadList->isColumnHidden(RATIO)) {
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
} }
}catch(invalid_handle e) {} }catch(invalid_handle e) {
return added; continue;
}
}
} }
void DownloadingTorrents::addTorrent(QString hash) { void DownloadingTorrents::addTorrent(QString hash) {
if(BTSession->isFinished(hash)){
BTSession->setUnfinishedTorrent(hash);
}
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toLocal8Bit(), row); qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toUtf8(), row);
if(row != -1) return; if(row != -1) return;
row = DLListModel->rowCount(); row = DLListModel->rowCount();
// Adding torrent to download list // Adding torrent to download list
@@ -585,24 +687,20 @@ void DownloadingTorrents::addTorrent(QString hash) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.)); DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.)); DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
DLListModel->setData(DLListModel->index(row, RATIO), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
if(BTSession->isQueueingEnabled()) if(BTSession->isQueueingEnabled())
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash))); DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash)); DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash));
// Pause torrent if it is // Pause torrent if it was paused last time
if(h.is_paused()) { if(BTSession->isPaused(hash)) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("red")); setRowColor(row, QString::fromUtf8("red"));
}else{ }else{
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
} }
++nbTorrents; ++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents); emit unfinishedTorrentsNumberChanged(nbTorrents);
// sort List
sortDownloadList();
} }
void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) { void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) {
@@ -651,51 +749,27 @@ void DownloadingTorrents::sortDownloadListString(int index, Qt::SortOrder sortOr
DLListModel->removeRows(0, nbRows_old); DLListModel->removeRows(0, nbRows_old);
} }
void DownloadingTorrents::toggleDownloadListSortOrder(int index) { void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder startSortOrder, bool fromLoadColWidth) {
Qt::SortOrder sortOrder = Qt::AscendingOrder; qDebug("Called sort download list");
qDebug("Toggling column sort order"); static Qt::SortOrder sortOrder = startSortOrder;
if(downloadList->header()->sortIndicatorSection() == index) { if(!fromLoadColWidth && downloadList->header()->sortIndicatorSection() == index) {
sortOrder = (Qt::SortOrder)!(bool)downloadList->header()->sortIndicatorOrder(); if(sortOrder == Qt::AscendingOrder) {
sortOrder = Qt::DescendingOrder;
}else{
sortOrder = Qt::AscendingOrder;
} }
switch(index) {
case SIZE:
case ETA:
case UPSPEED:
case DLSPEED:
case PROGRESS:
case PRIORITY:
case RATIO:
sortDownloadListFloat(index, sortOrder);
break;
default:
sortDownloadListString(index, sortOrder);
} }
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortOrderLetter; QString sortOrderLetter;
if(sortOrder == Qt::AscendingOrder) if(sortOrder == Qt::AscendingOrder)
sortOrderLetter = QString::fromUtf8("a"); sortOrderLetter = QString::fromUtf8("a");
else else
sortOrderLetter = QString::fromUtf8("d"); sortOrderLetter = QString::fromUtf8("d");
settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter); if(fromLoadColWidth) {
} // XXX: Why is this needed?
if(sortOrder == Qt::DescendingOrder)
void DownloadingTorrents::sortProgressColumn(QTorrentHandle& h) { downloadList->header()->setSortIndicator(index, Qt::AscendingOrder);
QString hash = h.hash(); else
int index = downloadList->header()->sortIndicatorSection(); downloadList->header()->setSortIndicator(index, Qt::DescendingOrder);
if(index == PROGRESS) {
int row = getRowFromHash(hash);
if(row >= 0) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
Qt::SortOrder sortOrder = downloadList->header()->sortIndicatorOrder();
sortDownloadListFloat(index, sortOrder);
}
}
}
void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder sortOrder) {
if(index == -1) {
index = downloadList->header()->sortIndicatorSection();
sortOrder = downloadList->header()->sortIndicatorOrder();
} else { } else {
downloadList->header()->setSortIndicator(index, sortOrder); downloadList->header()->setSortIndicator(index, sortOrder);
} }
@@ -704,13 +778,23 @@ void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder sortOrder) {
case ETA: case ETA:
case UPSPEED: case UPSPEED:
case DLSPEED: case DLSPEED:
case PRIORITY:
case PROGRESS:
sortDownloadListFloat(index, sortOrder); sortDownloadListFloat(index, sortOrder);
break; break;
case PROGRESS:
if(fromLoadColWidth) {
// Progress sorting must be delayed until files are checked (on startup)
delayedSorting = true;
qDebug("Delayed sorting of the progress column");
delayedSortingOrder = sortOrder;
}else{
sortDownloadListFloat(index, sortOrder);
}
break;
default: default:
sortDownloadListString(index, sortOrder); sortDownloadListString(index, sortOrder);
} }
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter);
} }
// Save columns width in a file to remember them // Save columns width in a file to remember them
@@ -726,7 +810,7 @@ void DownloadingTorrents::saveColWidthDLList() const{
width_list = line.split(' '); width_list = line.split(' ');
} }
for(short i=0; i<nbColumns; ++i){ for(short i=0; i<nbColumns; ++i){
if(downloadList->columnWidth(i)<1 && width_list.size() == nbColumns && width_list.at(i).toInt()>=1) { if(downloadList->columnWidth(i)<1 && width_list.size() == DLListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
// load the former width // load the former width
new_width_list << width_list.at(i); new_width_list << width_list.at(i);
} else if(downloadList->columnWidth(i)>=1) { } else if(downloadList->columnWidth(i)>=1) {
@@ -739,11 +823,6 @@ void DownloadingTorrents::saveColWidthDLList() const{
} }
} }
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), new_width_list.join(QString::fromUtf8(" "))); settings.setValue(QString::fromUtf8("DownloadListColsWidth"), new_width_list.join(QString::fromUtf8(" ")));
QVariantList visualIndexes;
for(int i=0; i<nbColumns; ++i) {
visualIndexes.append(downloadList->header()->visualIndex(i));
}
settings.setValue(QString::fromUtf8("DownloadListVisualIndexes"), visualIndexes);
qDebug("Download list columns width saved"); qDebug("Download list columns width saved");
} }
@@ -764,30 +843,7 @@ bool DownloadingTorrents::loadColWidthDLList() {
for(unsigned int i=0; i<listSize; ++i) { for(unsigned int i=0; i<listSize; ++i) {
downloadList->header()->resizeSection(i, width_list.at(i).toInt()); downloadList->header()->resizeSection(i, width_list.at(i).toInt());
} }
QVariantList visualIndexes = settings.value(QString::fromUtf8("DownloadListVisualIndexes"), QVariantList()).toList();
if(visualIndexes.size() != DLListModel->columnCount()-1) {
qDebug("Corrupted values for download list columns sizes");
return false;
}
bool change = false;
do {
change = false;
for(int i=0;i<visualIndexes.size(); ++i) {
int new_visual_index = visualIndexes.at(downloadList->header()->logicalIndex(i)).toInt();
if(i != new_visual_index) {
qDebug("Moving column from %d to %d", downloadList->header()->logicalIndex(i), new_visual_index);
downloadList->header()->moveSection(i, new_visual_index);
change = true;
}
}
}while(change);
qDebug("Download list columns width loaded");
return true;
}
void DownloadingTorrents::loadLastSortedColumn() {
// Loading last sorted column // Loading last sorted column
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortedCol = settings.value(QString::fromUtf8("DownloadListSortedCol"), QString()).toString(); QString sortedCol = settings.value(QString::fromUtf8("DownloadListSortedCol"), QString()).toString();
if(!sortedCol.isEmpty()) { if(!sortedCol.isEmpty()) {
Qt::SortOrder sortOrder; Qt::SortOrder sortOrder;
@@ -797,8 +853,56 @@ void DownloadingTorrents::loadLastSortedColumn() {
sortOrder = Qt::AscendingOrder; sortOrder = Qt::AscendingOrder;
sortedCol = sortedCol.left(sortedCol.size()-1); sortedCol = sortedCol.left(sortedCol.size()-1);
int index = sortedCol.toInt(); int index = sortedCol.toInt();
sortDownloadList(index, sortOrder); sortDownloadList(index, sortOrder, true);
} }
qDebug("Download list columns width loaded");
return true;
}
// Called when a torrent is added
void DownloadingTorrents::torrentAdded(QString path, QTorrentHandle& h, bool fastResume) {
QString hash = h.hash();
if(BTSession->isFinished(hash)) {
return;
}
if(getRowFromHash(hash) != -1) return;
int row = DLListModel->rowCount();
// Adding torrent to download list
DLListModel->insertRow(row);
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.name()));
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size()));
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash));
// Pause torrent if it was paused last time
// Not using isPaused function because torrents are paused after checking now
if(QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".paused"))) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("red"));
}else{
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
if(!fastResume) {
setInfoBar(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(path));
}else{
setInfoBar(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(path));
}
++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents);
}
// Called when trying to add a duplicate torrent
void DownloadingTorrents::torrentDuplicate(QString path) {
setInfoBar(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(path));
}
void DownloadingTorrents::torrentCorrupted(QString path) {
setInfoBar(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(path), QString::fromUtf8("red"));
setInfoBar(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red"));
} }
void DownloadingTorrents::updateFileSizeAndProgress(QString hash) { void DownloadingTorrents::updateFileSizeAndProgress(QString hash) {
@@ -806,7 +910,13 @@ void DownloadingTorrents::updateFileSizeAndProgress(QString hash) {
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size())); DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size()));
//DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
// Called when we couldn't listen on any port
// in the given range.
void DownloadingTorrents::portListeningFailure() {
setInfoBar(tr("Couldn't listen on any of the given ports."), QString::fromUtf8("red"));
} }
// Set the color of a row in data model // Set the color of a row in data model
@@ -828,3 +938,7 @@ int DownloadingTorrents::getRowFromHash(QString hash) const{
} }
return -1; return -1;
} }
void DownloadingTorrents::displayDownloadingUrlInfos(QString url) {
setInfoBar(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url), QPalette::WindowText);
}

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
@@ -47,7 +38,9 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
bittorrent *BTSession; bittorrent *BTSession;
DLListDelegate *DLDelegate; DLListDelegate *DLDelegate;
QStandardItemModel *DLListModel; QStandardItemModel *DLListModel;
bool delayedSorting;
unsigned int nbTorrents; unsigned int nbTorrents;
Qt::SortOrder delayedSortingOrder;
void hideOrShowColumn(int index); void hideOrShowColumn(int index);
bool loadHiddenColumns(); bool loadHiddenColumns();
void saveHiddenColumns(); void saveHiddenColumns();
@@ -67,19 +60,30 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
signals: signals:
void unfinishedTorrentsNumberChanged(unsigned int); void unfinishedTorrentsNumberChanged(unsigned int);
void torrentDoubleClicked(QString hash, bool finished); void torrentDoubleClicked(QString hash, bool finished);
void torrentFinished(QString hash);
protected slots: protected slots:
void addLogPeerBlocked(QString);
void addFastResumeRejectedAlert(QString);
void addUrlSeedError(QString url, QString msg);
void on_actionSet_download_limit_triggered(); void on_actionSet_download_limit_triggered();
void notifyTorrentDoubleClicked(const QModelIndex& index); void notifyTorrentDoubleClicked(const QModelIndex& index);
void on_actionSet_upload_limit_triggered(); void on_actionSet_upload_limit_triggered();
void displayDLListMenu(const QPoint& pos); void displayDLListMenu(const QPoint& pos);
void displayDLHoSMenu(const QPoint&); void displayDLHoSMenu(const QPoint&);
void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder); void on_actionClearLog_triggered();
void toggleDownloadListSortOrder(int index); void displayInfoBarMenu(const QPoint& pos);
void addTorrent(QString hash);
void sortDownloadList(int index, Qt::SortOrder startSortOrder=Qt::AscendingOrder, bool fromLoadColWidth=false);
void sortDownloadListFloat(int index, Qt::SortOrder sortOrder); void sortDownloadListFloat(int index, Qt::SortOrder sortOrder);
void sortDownloadListString(int index, Qt::SortOrder sortOrder); void sortDownloadListString(int index, Qt::SortOrder sortOrder);
void saveColWidthDLList() const; void saveColWidthDLList() const;
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume);
void torrentDuplicate(QString path);
void torrentCorrupted(QString path);
void portListeningFailure();
void setRowColor(int row, QColor color); void setRowColor(int row, QColor color);
void displayDownloadingUrlInfos(QString url);
void showProperties(const QModelIndex &index); void showProperties(const QModelIndex &index);
void hideOrShowColumnName(); void hideOrShowColumnName();
void hideOrShowColumnSize(); void hideOrShowColumnSize();
@@ -90,19 +94,21 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void hideOrShowColumnRatio(); void hideOrShowColumnRatio();
void hideOrShowColumnEta(); void hideOrShowColumnEta();
void hideOrShowColumnPriority(); void hideOrShowColumnPriority();
void forceRecheck(); void displayUPnPError(QString msg);
void displayUPnPSuccess(QString msg);
public slots: public slots:
bool updateTorrent(QTorrentHandle h); void updateDlList();
void setInfoBar(QString info, QColor color=QApplication::palette().color(QPalette::WindowText));
void pauseTorrent(QString hash); void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
void setBottomTabEnabled(unsigned int index, bool b);
void propertiesSelection(); void propertiesSelection();
void sortProgressColumnDelayed();
void updateFileSizeAndProgress(QString hash); void updateFileSizeAndProgress(QString hash);
void showPropertiesFromHash(QString hash); void showPropertiesFromHash(QString hash);
void hidePriorityColumn(bool hide); void hidePriorityColumn(bool hide);
void sortProgressColumn(QTorrentHandle& h);
void loadLastSortedColumn();
void addTorrent(QString hash);
}; };

View File

@@ -16,22 +16,12 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */
#include "engineSelectDlg.h" #include "engineSelectDlg.h"
#include "downloadThread.h" #include "downloadThread.h"
#include "misc.h" #include "misc.h"
#include "ico.h"
#include "pluginSource.h" #include "pluginSource.h"
#include <QProcess> #include <QProcess>
#include <QHeaderView> #include <QHeaderView>
@@ -42,6 +32,11 @@
#include <QDropEvent> #include <QDropEvent>
#include <QInputDialog> #include <QInputDialog>
#ifdef HAVE_MAGICK
#include <Magick++.h>
using namespace Magick;
#endif
#ifdef HAVE_ZZIP #ifdef HAVE_ZZIP
#include <zzip/zzip.h> #include <zzip/zzip.h>
#endif #endif
@@ -57,8 +52,8 @@ engineSelectDlg::engineSelectDlg(QWidget *parent) : QDialog(parent) {
pluginsTree->header()->resizeSection(0, 170); pluginsTree->header()->resizeSection(0, 170);
pluginsTree->header()->resizeSection(1, 220); pluginsTree->header()->resizeSection(1, 220);
pluginsTree->hideColumn(ENGINE_ID); pluginsTree->hideColumn(ENGINE_ID);
actionEnable->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png"))); actionEnable->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
actionDisable->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png"))); actionDisable->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
actionUninstall->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/remove.png"))); actionUninstall->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/remove.png")));
connect(actionEnable, SIGNAL(triggered()), this, SLOT(enableSelection())); connect(actionEnable, SIGNAL(triggered()), this, SLOT(enableSelection()));
connect(actionDisable, SIGNAL(triggered()), this, SLOT(disableSelection())); connect(actionDisable, SIGNAL(triggered()), this, SLOT(disableSelection()));
@@ -85,7 +80,7 @@ void engineSelectDlg::dropEvent(QDropEvent *event) {
QStringList files=event->mimeData()->text().split(QString::fromUtf8("\n")); QStringList files=event->mimeData()->text().split(QString::fromUtf8("\n"));
QString file; QString file;
foreach(file, files) { foreach(file, files) {
qDebug("dropped %s", file.toLocal8Bit().data()); qDebug("dropped %s", file.toUtf8().data());
file = file.replace("file://", ""); file = file.replace("file://", "");
if(file.startsWith("http://", Qt::CaseInsensitive) || file.startsWith("https://", Qt::CaseInsensitive) || file.startsWith("ftp://", Qt::CaseInsensitive)) { if(file.startsWith("http://", Qt::CaseInsensitive) || file.startsWith("https://", Qt::CaseInsensitive) || file.startsWith("ftp://", Qt::CaseInsensitive)) {
downloader->downloadUrl(file); downloader->downloadUrl(file);
@@ -108,7 +103,7 @@ void engineSelectDlg::dropEvent(QDropEvent *event) {
void engineSelectDlg::dragEnterEvent(QDragEnterEvent *event) { void engineSelectDlg::dragEnterEvent(QDragEnterEvent *event) {
QString mime; QString mime;
foreach(mime, event->mimeData()->formats()){ foreach(mime, event->mimeData()->formats()){
qDebug("mimeData: %s", mime.toLocal8Bit().data()); qDebug("mimeData: %s", mime.toUtf8().data());
} }
if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) { if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) {
event->acceptProposedAction(); event->acceptProposedAction();
@@ -123,7 +118,7 @@ void engineSelectDlg::saveSettings() {
foreach(engine, installed_engines.keys()) { foreach(engine, installed_engines.keys()) {
known_engines << engine; known_engines << engine;
known_enginesEnabled << QVariant(installed_engines.value(engine, true)); known_enginesEnabled << QVariant(installed_engines.value(engine, true));
qDebug("Engine %s has state: %d", engine.toLocal8Bit().data(), installed_engines.value(engine, true)); qDebug("Engine %s has state: %d", engine.toUtf8().data(), installed_engines.value(engine, true));
} }
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.setValue(QString::fromUtf8("SearchEngines/knownEngines"), known_engines); settings.setValue(QString::fromUtf8("SearchEngines/knownEngines"), known_engines);
@@ -132,7 +127,7 @@ void engineSelectDlg::saveSettings() {
void engineSelectDlg::on_updateButton_clicked() { void engineSelectDlg::on_updateButton_clicked() {
// Download version file from primary server // Download version file from primary server
downloader->downloadUrl("http://www.dchris.eu/search_engine2/versions.txt"); downloader->downloadUrl("http://www.dchris.eu/search_engine/versions.txt");
} }
void engineSelectDlg::toggleEngineState(QTreeWidgetItem *item, int) { void engineSelectDlg::toggleEngineState(QTreeWidgetItem *item, int) {
@@ -264,7 +259,7 @@ bool engineSelectDlg::checkInstalled(QString plugin_name) const {
result = result.replace("\r", ""); result = result.replace("\r", "");
result = result.replace("\n", ""); result = result.replace("\n", "");
QList<QByteArray> plugins_list = result.split(','); QList<QByteArray> plugins_list = result.split(',');
return plugins_list.contains(plugin_name.toLocal8Bit()); return plugins_list.contains(plugin_name.toUtf8());
} }
void engineSelectDlg::loadSupportedSearchEngines(bool first) { void engineSelectDlg::loadSupportedSearchEngines(bool first) {
@@ -332,15 +327,10 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
if(QFile::exists(iconPath)) { if(QFile::exists(iconPath)) {
// Good, we already have the icon // Good, we already have the icon
item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath))); item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath)));
} else {
iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".ico";
if(QFile::exists(iconPath)) { // ICO support
item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath)));
} else { } else {
// Icon is missing, we must download it // Icon is missing, we must download it
downloader->downloadUrl(line.at(1)+"/favicon.ico"); downloader->downloadUrl(line.at(1)+"/favicon.ico");
} }
}
if(installed_engines.value(id, true)) if(installed_engines.value(id, true))
setRowColor(i, "green"); setRowColor(i, "green");
else else
@@ -379,7 +369,7 @@ bool engineSelectDlg::isUpdateNeeded(QString plugin_name, float new_version) con
void engineSelectDlg::installZipPlugin(QString path) { void engineSelectDlg::installZipPlugin(QString path) {
QStringList plugins; QStringList plugins;
QStringList favicons; QStringList favicons;
ZZIP_DIR* dir = zzip_dir_open(path.toLocal8Bit().data(), 0); ZZIP_DIR* dir = zzip_dir_open(path.toUtf8().data(), 0);
if(!dir) { if(!dir) {
QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("Search engine plugin archive could not be read.")); QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("Search engine plugin archive could not be read."));
return; return;
@@ -412,8 +402,8 @@ void engineSelectDlg::installZipPlugin(QString path) {
foreach(plugin, plugins) { foreach(plugin, plugins) {
QString plugin_name = plugin.split(QDir::separator()).last(); QString plugin_name = plugin.split(QDir::separator()).last();
plugin_name.chop(3); // Remove .py extension plugin_name.chop(3); // Remove .py extension
qDebug("Detected plugin %s in archive", plugin_name.toLocal8Bit().data()); qDebug("Detected plugin %s in archive", plugin_name.toUtf8().data());
ZZIP_FILE* fp = zzip_file_open(dir, plugin.toLocal8Bit().data(), 0); ZZIP_FILE* fp = zzip_file_open(dir, plugin.toUtf8().data(), 0);
if(fp) { if(fp) {
QTemporaryFile *tmpfile = new QTemporaryFile(); QTemporaryFile *tmpfile = new QTemporaryFile();
QString tmpPath; QString tmpPath;
@@ -430,7 +420,7 @@ void engineSelectDlg::installZipPlugin(QString path) {
tmpfile->close(); tmpfile->close();
} else { } else {
qDebug("Could not open tmp file"); qDebug("Could not open tmp file");
QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
delete tmpfile; delete tmpfile;
continue; continue;
} }
@@ -441,12 +431,12 @@ void engineSelectDlg::installZipPlugin(QString path) {
qDebug("Deleted tmpfile"); qDebug("Deleted tmpfile");
} else { } else {
qDebug("Cannot read file in archive"); qDebug("Cannot read file in archive");
QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
} }
} }
QString favicon; QString favicon;
foreach(favicon, favicons) { foreach(favicon, favicons) {
qDebug("Detected favicon %s in archive", favicon.toLocal8Bit().data()); qDebug("Detected favicon %s in archive", favicon.toUtf8().data());
// Ok we have a favicon here // Ok we have a favicon here
QString plugin_name = favicon.split(QDir::separator()).last(); QString plugin_name = favicon.split(QDir::separator()).last();
plugin_name.chop(4); // Remove .png extension plugin_name.chop(4); // Remove .png extension
@@ -454,10 +444,8 @@ void engineSelectDlg::installZipPlugin(QString path) {
continue; continue;
// Check if we already have a favicon for this plugin // Check if we already have a favicon for this plugin
QString iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+plugin_name+".png"; QString iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+plugin_name+".png";
if(QFile::exists(iconPath)) { if(QFile::exists(iconPath)) continue;
QFile::remove(iconPath); ZZIP_FILE* fp = zzip_file_open(dir, favicon.toUtf8().data(), 0);
}
ZZIP_FILE* fp = zzip_file_open(dir, favicon.toLocal8Bit().data(), 0);
if(fp) { if(fp) {
QFile dest_icon(iconPath); QFile dest_icon(iconPath);
// Write icon // Write icon
@@ -482,12 +470,12 @@ void engineSelectDlg::installZipPlugin(QString path) {
#endif #endif
void engineSelectDlg::installPlugin(QString path, QString plugin_name) { void engineSelectDlg::installPlugin(QString path, QString plugin_name) {
qDebug("Asked to install plugin at %s", path.toLocal8Bit().data()); qDebug("Asked to install plugin at %s", path.toUtf8().data());
float new_version = misc::getPluginVersion(path); float new_version = misc::getPluginVersion(path);
qDebug("Version to be installed: %.2f", new_version); qDebug("Version to be installed: %.2f", new_version);
if(!isUpdateNeeded(plugin_name, new_version)) { if(!isUpdateNeeded(plugin_name, new_version)) {
qDebug("Apparently update it not needed, we have a more recent version"); qDebug("Apparently update it not needed, we have a more recent version");
QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("A more recent version of %1 search engine plugin is already installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("A more recent version of %1 search engine plugin is already installed.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
return; return;
} }
// Process with install // Process with install
@@ -509,12 +497,12 @@ void engineSelectDlg::installPlugin(QString path, QString plugin_name) {
// restore backup // restore backup
QFile::copy(dest_path+".bak", dest_path); QFile::copy(dest_path+".bak", dest_path);
QFile::remove(dest_path+".bak"); QFile::remove(dest_path+".bak");
QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be updated, keeping old version.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be updated, keeping old version.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
return; return;
} else { } else {
// Remove broken file // Remove broken file
QFile::remove(dest_path); QFile::remove(dest_path);
QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
return; return;
} }
} }
@@ -525,10 +513,10 @@ void engineSelectDlg::installPlugin(QString path, QString plugin_name) {
// Refresh plugin list // Refresh plugin list
loadSupportedSearchEngines(); loadSupportedSearchEngines();
if(update) { if(update) {
QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully updated.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully updated.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
return; return;
} else { } else {
QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully installed.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
return; return;
} }
} }
@@ -595,17 +583,17 @@ bool engineSelectDlg::parseVersionsFile(QString versions_file, QString updateSer
plugin_name.chop(1); // remove trailing ':' plugin_name.chop(1); // remove trailing ':'
bool ok; bool ok;
float version = list.last().toFloat(&ok); float version = list.last().toFloat(&ok);
qDebug("read line %s: %.2f", plugin_name.toLocal8Bit().data(), version); qDebug("read line %s: %.2f", plugin_name.toUtf8().data(), version);
if(!ok) continue; if(!ok) continue;
file_correct = true; file_correct = true;
if(isUpdateNeeded(plugin_name, version)) { if(isUpdateNeeded(plugin_name, version)) {
qDebug("Plugin: %s is outdated", plugin_name.toLocal8Bit().data()); qDebug("Plugin: %s is outdated", plugin_name.toUtf8().data());
// Downloading update // Downloading update
downloader->downloadUrl(updateServer+plugin_name+".pyqBT"); // Actually this is really a .py downloader->downloadUrl(updateServer+plugin_name+".pyqBT"); // Actually this is really a .py
downloader->downloadUrl(updateServer+plugin_name+".png"); downloader->downloadUrl(updateServer+plugin_name+".png");
updated = true; updated = true;
}else { }else {
qDebug("Plugin: %s is up to date", plugin_name.toLocal8Bit().data()); qDebug("Plugin: %s is up to date", plugin_name.toUtf8().data());
} }
} }
// Close file // Close file
@@ -619,22 +607,30 @@ bool engineSelectDlg::parseVersionsFile(QString versions_file, QString updateSer
} }
void engineSelectDlg::processDownloadedFile(QString url, QString filePath) { void engineSelectDlg::processDownloadedFile(QString url, QString filePath) {
qDebug("engineSelectDlg received %s", url.toLocal8Bit().data()); qDebug("engineSelectDlg received %s", url.toUtf8().data());
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
// Icon downloaded // Icon downloaded
QImage fileIcon; 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)) { if(fileIcon.load(filePath)) {
QList<QTreeWidgetItem*> items = findItemsWithUrl(url); QList<QTreeWidgetItem*> items = findItemsWithUrl(url);
QTreeWidgetItem *item; QTreeWidgetItem *item;
foreach(item, items){ foreach(item, items){
QString id = item->text(ENGINE_ID); QString id = item->text(ENGINE_ID);
QString iconPath; QString iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".png";
QFile icon(filePath);
icon.open(QIODevice::ReadOnly);
if(ICOHandler::canRead(&icon))
iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".ico";
else
iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".png";
QFile::copy(filePath, iconPath); QFile::copy(filePath, iconPath);
item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath))); item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath)));
} }
@@ -643,16 +639,16 @@ void engineSelectDlg::processDownloadedFile(QString url, QString filePath) {
QFile::remove(filePath); QFile::remove(filePath);
return; return;
} }
if(url == "http://www.dchris.eu/search_engine2/versions.txt") { if(url == "http://www.dchris.eu/search_engine/versions.txt") {
if(!parseVersionsFile(filePath, "http://www.dchris.eu/search_engine2/")) { if(!parseVersionsFile(filePath, "http://www.dchris.eu/search_engine/")) {
qDebug("Primary update server failed, try secondary"); qDebug("Primary update server failed, try secondary");
downloader->downloadUrl("http://hydr0g3n.free.fr/search_engine2/versions.txt"); downloader->downloadUrl("http://hydr0g3n.free.fr/search_engine/versions.txt");
} }
QFile::remove(filePath); QFile::remove(filePath);
return; return;
} }
if(url == "http://hydr0g3n.free.fr/search_engine2/versions.txt") { if(url == "http://hydr0g3n.free.fr/search_engine/versions.txt") {
if(!parseVersionsFile(filePath, "http://hydr0g3n.free.fr/search_engine2/")) { if(!parseVersionsFile(filePath, "http://hydr0g3n.free.fr/search_engine/")) {
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable.")); QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable."));
} }
QFile::remove(filePath); QFile::remove(filePath);
@@ -677,16 +673,16 @@ void engineSelectDlg::processDownloadedFile(QString url, QString filePath) {
void engineSelectDlg::handleDownloadFailure(QString url, QString reason) { void engineSelectDlg::handleDownloadFailure(QString url, QString reason) {
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
qDebug("Could not download favicon: %s, reason: %s", url.toLocal8Bit().data(), reason.toLocal8Bit().data()); qDebug("Could not download favicon: %s, reason: %s", url.toUtf8().data(), reason.toUtf8().data());
return; return;
} }
if(url == "http://www.dchris.eu/search_engine2/versions.txt") { if(url == "http://www.dchris.eu/search_engine/versions.txt") {
// Primary update server failed, try secondary // Primary update server failed, try secondary
qDebug("Primary update server failed, try secondary"); qDebug("Primary update server failed, try secondary");
downloader->downloadUrl("http://hydr0g3n.free.fr/search_engine2/versions.txt"); downloader->downloadUrl("http://hydr0g3n.free.fr/search_engine/versions.txt");
return; return;
} }
if(url == "http://hydr0g3n.free.fr/search_engine2/versions.txt") { if(url == "http://hydr0g3n.free.fr/search_engine/versions.txt") {
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable.")); QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable."));
return; return;
} }
@@ -695,13 +691,13 @@ void engineSelectDlg::handleDownloadFailure(QString url, QString reason) {
QString plugin_name = url.split('/').last(); QString plugin_name = url.split('/').last();
plugin_name.replace(".pyqBT", "", Qt::CaseInsensitive); plugin_name.replace(".pyqBT", "", Qt::CaseInsensitive);
plugin_name.replace(".py", "", Qt::CaseInsensitive); plugin_name.replace(".py", "", Qt::CaseInsensitive);
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
} }
#ifdef HAVE_ZZIP #ifdef HAVE_ZZIP
if(url.endsWith(".zip", Qt::CaseInsensitive)) { if(url.endsWith(".zip", Qt::CaseInsensitive)) {
QString plugin_name = url.split('/').last(); QString plugin_name = url.split('/').last();
plugin_name.replace(".zip", "", Qt::CaseInsensitive); plugin_name.replace(".zip", "", Qt::CaseInsensitive);
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name.toUtf8().data()));
} }
#endif #endif
} }

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org * Contact : chris@qbittorrent.org
*/ */

View File

@@ -1,11 +1,11 @@
/* /*
* Bittorrent Client using Qt4 and libtorrent. * Copyright (C) 2007 by Ishan Arora
* Copyright (C) 2006 Ishan Arora and Christophe Dumez * ishanarora@gmail.com
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or modify
* modify it under the terms of the GNU General Public License * it under the terms of the GNU General Public License as published by
* as published by the Free Software Foundation; either version 2 * the Free Software Foundation; either version 2 of the License, or
* of the License, or (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,93 +13,177 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Free Software Foundation, Inc.,
* * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/ */
#include "eventmanager.h" #include "eventmanager.h"
#include "bittorrent.h" #include "bittorrent.h"
#include "json.h"
#include <QDebug> #include <QDebug>
EventManager::EventManager(QObject *parent, bittorrent *BTSession) EventManager::EventManager(QObject *parent, bittorrent *BTSession)
: QObject(parent), BTSession(BTSession) : QObject(parent), BTSession(BTSession)
{ {
revision = 0;
} }
QList<QVariantMap> EventManager::getEventList() const { void EventManager::update(QVariantMap event)
return event_list.values();
}
void EventManager::addedTorrent(QTorrentHandle& h)
{ {
modifiedTorrent(h); 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(QString, QTorrentHandle& h)
{
QVariantMap event;
event["type"] = QVariant("add");
event["hash"] = QVariant(h.hash());
event["name"] = QVariant(h.name());
update(event);
} }
void EventManager::deletedTorrent(QString hash) 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) void EventManager::modifiedTorrent(QTorrentHandle h)
{ {
QString hash = h.hash(); QString hash = h.hash();
QVariantMap event; QVariantMap event;
QVariant v;
if(h.is_paused()) { if(h.is_paused()) {
event["state"] = QVariant("paused"); if(BTSession->isDownloadQueued(hash) || BTSession->isUploadQueued(hash))
} else { v = QVariant("queued");
if(BTSession->isQueueingEnabled() && h.is_queued()) { else
event["state"] = QVariant("queued"); v = QVariant("paused");
} else { } else {
switch(h.state()) switch(h.state())
{ {
case torrent_status::finished: case torrent_status::finished:
case torrent_status::seeding: case torrent_status::seeding:
event["state"] = QVariant("seeding"); v = QVariant("seeding");
break; break;
case torrent_status::checking_files: case torrent_status::checking_files:
case torrent_status::queued_for_checking: case torrent_status::queued_for_checking:
event["state"] = QVariant("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; break;
case torrent_status::allocating:
case torrent_status::downloading: case torrent_status::downloading:
case torrent_status::downloading_metadata: case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0) if(h.download_payload_rate() > 0)
event["state"] = QVariant("downloading"); v = QVariant("downloading");
else else
event["state"] = QVariant("stalled"); v = QVariant("stalled");
break; break;
default: default:
qDebug("No status, should not happen!!! status is %d", h.state()); v = QVariant();
event["state"] = QVariant();
} }
} }
} if(modify(hash, "state", v))
event["name"] = QVariant(h.name()); event["state"] = v;
event["size"] = QVariant((qlonglong)h.actual_size());
if(!h.is_seed()) { v = QVariant((qlonglong)h.actual_size());
event["progress"] = QVariant(h.progress()); if(modify(hash, "size", v))
event["dlspeed"] = QVariant(h.download_payload_rate()); event["size"] = v;
if(BTSession->isQueueingEnabled()) {
event["priority"] = QVariant(h.queue_position()); v = QVariant(h.progress());
} else { if(modify(hash, "progress", v))
event["priority"] = -1; event["progress"] = v;
}
} v = QVariant(h.download_payload_rate());
event["upspeed"] = QVariant(h.upload_payload_rate()); if(modify(hash, "dlspeed", v))
event["seed"] = QVariant(h.is_seed()); 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); event["hash"] = QVariant(hash);
event_list[hash] = event; update(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