Compare commits
1 Commits
release-1.
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2ffb4c7c5 |
74
AUTHORS
@@ -3,77 +3,3 @@ Author:
|
||||
|
||||
Contributors:
|
||||
* Arnaud Demaizière <arnaud@qbittorrent.org>
|
||||
* Ishan Arora <ishan@qbittorrent.org>
|
||||
* Grigis Gaëtan <cipher16@gmail.com>
|
||||
|
||||
Code from other projects:
|
||||
* files src/ico.cpp src/ico.h
|
||||
copyright: Malte Starostik <malte@kde.org>
|
||||
license: LGPL
|
||||
|
||||
Images Authors:
|
||||
* files: src/Icons/*.png
|
||||
copyright: Gnome Icon Theme
|
||||
license: GPLv2
|
||||
url: http://ftp.acc.umu.se/pub/GNOME/sources/gnome-icon-theme
|
||||
|
||||
* files: src/Icons/flags/*.png
|
||||
copyright: Open Clip Art Library
|
||||
license: Creative Commons Public Domain Dedication
|
||||
url: http://www.openclipart.org
|
||||
|
||||
* files: src/Icons/skin/*.png
|
||||
files: src/menuicons/YYxYY/*.png
|
||||
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
|
||||
license: GPLv2
|
||||
|
||||
* file: src/Icons/skin/tabs.gif
|
||||
copyright: Greg Houston <gregory.houston@gmail.com>
|
||||
license: MIT
|
||||
|
||||
* file: src/search_engine/engines/btjunkie.png
|
||||
copyright: Downloaded from btjunkie.org
|
||||
|
||||
* file: src/search_engine/engines/isohunt.png
|
||||
copyright: Downloaded from isohunt.com
|
||||
|
||||
* file: src/search_engine/engines/mininova.png
|
||||
copyright: Downloaded from mininova.org
|
||||
|
||||
* file: src/search_engine/engines/piratebay.png
|
||||
copyright: Downloaded from thepiratebay.org
|
||||
|
||||
* file: src/search_engine/engines/torrentreactor.png
|
||||
copyright: Downloaded from torrentreactor.net
|
||||
|
||||
Translations authors:
|
||||
* files: src/lang/*.ts
|
||||
copyright:
|
||||
- Brazilian: Nick Marinho (nickmarinho@gmail.com)
|
||||
- Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)
|
||||
- Catalan: Gekko Dam Beer (gekko04@users.sourceforge.net)
|
||||
- Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com)
|
||||
- Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com)
|
||||
- Czech: Jirka Vilim (web@tets.cz)
|
||||
- Danish: Mathias Nielsen (comoneo@gmail.com)
|
||||
- Dutch: Joost Schipper (heavyjoost@users.sourceforge.net)
|
||||
- English: Christophe Dumez (chris@qbittorrent.org)
|
||||
- Finnish: Niklas Laxström (nikerabbit@users.sourceforge.net)
|
||||
- French: Christophe Dumez (chris@qbittorrent.org)
|
||||
- German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
|
||||
- Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net)
|
||||
- Hungarian: Majoros Péter (majoros.j.p@t-online.hu)
|
||||
- Italian: Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)
|
||||
- Japanese: Nardog (nardog@e2umail.com)
|
||||
- Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
|
||||
- Norwegian: Lars-Erik Labori (hamil@users.sourceforge.net)
|
||||
- Polish: Jarek Smieja (ajep9691@wp.pl)
|
||||
- Portuguese: Nick Marinho (nickmarinho@gmail.com)
|
||||
- Romanian: Obada Denis (obadadenis@users.sourceforge.net)
|
||||
- Russian: Nick Khazov (m2k3d0n at users.sourceforge.net)
|
||||
- Slovak: helix84
|
||||
- Spanish: Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net)
|
||||
- Swedish: Daniel Nylander (po@danielnylander.se)
|
||||
- Turkish: Erdem Bingöl (erdem84@gmail.com)
|
||||
- Ukrainian: Andrey Shpachenko (masterfix@users.sourceforge.net)
|
||||
license: GPLv2
|
||||
|
||||
111
Changelog
@@ -1,111 +1,4 @@
|
||||
* 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: The number of DHT nodes is displayed
|
||||
- FEATURE: RSS can now be disabled from program preferences
|
||||
- FEATURE: Added collapse/expand all buttons in addition and properties dialogs
|
||||
- FEATURE: Can have different proxies for Bittorrent and search engine
|
||||
- FEATURE: Allow multiple item selection in Web UI transfer list
|
||||
- FEATURE: Moved uploads to a separate list in Web UI
|
||||
- BUGFIX: Totally rewritten Web UI list refresh system (fixed memory leak)
|
||||
- BUGFIX: Disable ETA calculation when ETA column is hidden
|
||||
- BUGFIX: Removed "disconnected" connection state, detection was far from perfect
|
||||
- BUGFIX: Torrents are no longer starting from scratch when changing default save path (when torrent addition dialog is disabled)
|
||||
- BUGFIX: Single instance code is now more reliable on Qt >= 4.4
|
||||
- COSMETIC: Transfer speed, ratio, connection status and DHT nodes are displayed in status bar
|
||||
- COSMETIC: RSS Tab is now hidden as a default
|
||||
- COSMETIC: Allow to hide or display top toolbar
|
||||
- COSMETIC: Log is now in a separate dialog
|
||||
|
||||
* 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
|
||||
- FEATURE: Web interface to control qbittorrent (Ishan Arora)
|
||||
- FEATURE: Can spoof Azureus peer id to avoid ban
|
||||
- FEATURE: Allow to hide/show some columns in download and seeding lists
|
||||
- FEATURE: Option to start qBittorrent minimized in systray
|
||||
- FEATURE: Multi-tab support in search engine (Grigis Gaëtan)
|
||||
- FEATURE: Allow to define double-click actions in torrents lists
|
||||
- FEATURE: Allow to open torrent destination folder
|
||||
- FEATURE: Real progress bar in torrent properties that displays downloaded pieces
|
||||
- FEATURE: Allow to buy downloads using ShareMonkey
|
||||
- FEATURE: Display if UPnP/NAT-PMP was successful or not
|
||||
- FEATURE: Threadified torrent creation
|
||||
- FEATURE: Improved eMule DAT ip filter parser
|
||||
- FEATURE: Added support for PeerGuardian p2p filters (text)
|
||||
- FEATURE: Added support for PeerGuardian p2b filters (binary)
|
||||
- FEATURE: Allow to customize folder scan interval
|
||||
- FEATURE: Allow to add several trackers at once
|
||||
- BUGFIX: Allow to run one instance of qBittorrent per user
|
||||
- BUGFIX: Do not display seeds number in seeding list (always 0)
|
||||
- BUGFIX: Threadified IP filter file parser to avoid GUI freeze
|
||||
- BUGFIX: Ask if we want to redownload if content was deleted from hard drive
|
||||
- BUGFIX: Added missing copyright/licensing information for some files
|
||||
- BUGFIX: qBittorrent is no longer conflicting with rTorrent (libtorrent renamed to libtorrent-rasterbar)
|
||||
- COSMETIC: Do not display progress bar in seeding list (always 100%)
|
||||
- COSMETIC: Added a progress bar for torrent creation
|
||||
- COSMETIC: Display tracker errors in a cleaner way
|
||||
- COSMETIC: Display "unpaused/total_torrent" in download/upload tabs
|
||||
- COSMETIC: Allow to resize RSS column
|
||||
- COSMETIC: Global UP/DL speeds and ratio are displayed above tabs
|
||||
- COSMETIC: Use infinity symbol for ETA when time is infinite
|
||||
|
||||
* Fri Apr 11 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.0.0
|
||||
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.0.0
|
||||
- FEATURE: Based on new libtorrent v0.13
|
||||
- FEATURE: Added UPnP / NAT-PMP port forwarding support
|
||||
- FEATURE: Added encryption support (compatible with Azureus)
|
||||
@@ -171,8 +64,6 @@
|
||||
- BUGFIX: Prevent downloadFromUrl flooding
|
||||
- BUGFIX: ETA was wrong for torrents with filtered files
|
||||
- BUGFIX: Fixed drag'n drop on non-KDE systems
|
||||
- BUGFIX: Removed build dependency on Python
|
||||
- BUGFIX: Catching DHT exception in case there is a problem
|
||||
- COSMETIC: Redesigned torrent properties a little
|
||||
- COSMETIC: Totally redesigned program preferences
|
||||
- COSMETIC: Display more logs messages concerning features
|
||||
|
||||
9
INSTALL
@@ -15,16 +15,17 @@ will install and execute qBittorrent hopefully without any problems.
|
||||
|
||||
Dependencies:
|
||||
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||
Qt >= 4.4.0 is advised
|
||||
|
||||
- libtorrent-rasterbar by Arvid Norberg (>= v0.14.0 REQUIRED)
|
||||
- rblibtorrent by Arvid Norberg (>= v0.13 REQUIRED)
|
||||
-> http://www.qbittorrent.org/download.php (advised)
|
||||
-> http://www.libtorrent.net
|
||||
Be careful: another library (the one used by rTorrent) uses a similar name.
|
||||
Be careful: another library (the one used by rTorrent) use the same name.
|
||||
These are TWO different libraries and qBittorrent will only work with the one provided
|
||||
on sourceforge (created by Arvid Norberg). The two libraries conflicts with each other.
|
||||
|
||||
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
|
||||
|
||||
- libcurl
|
||||
- libcommoncpp2
|
||||
|
||||
- python >= 2.3 (needed by search engine)
|
||||
|
||||
|
||||
83
TODO
@@ -1,18 +1,67 @@
|
||||
See https://blueprints.launchpad.net/qbittorrent/
|
||||
// Easy
|
||||
- Translations into as many languages as possible
|
||||
- Use Launchpad/Rosetta for translations once it supports TS files
|
||||
|
||||
// translations done in v1.3.0
|
||||
- Romanian
|
||||
- Russian
|
||||
- Hungarian
|
||||
- German
|
||||
- Chinese (traditional)
|
||||
- Chinese (simplified)
|
||||
- Italian
|
||||
- Swedish
|
||||
- Turkish
|
||||
- French
|
||||
- Slovak
|
||||
- Czech
|
||||
- Korean
|
||||
- Portuguese
|
||||
- Brazilian
|
||||
// Intermediate
|
||||
- Port on MacOS, Windows (and create an installer for Windows) - Slow progress
|
||||
- Add some transparency (menus,...), improve look / usabilty
|
||||
- Skins support? (contact Mateusz)
|
||||
|
||||
// Harder
|
||||
- Display a progress bar that really represents the pieces we have (like in eMule)
|
||||
- Torrent scheduler ala µtorrent/Bitcomet
|
||||
|
||||
// Waiting for libtorrent
|
||||
- File selection in a torrent in compact mode
|
||||
- Allow to prioritize torrents (may code this in qBittorrent?)
|
||||
|
||||
// Unsure
|
||||
- Display the peers we are connected to for each torrent with infos (like flag, dl/up speeds, ...)
|
||||
- Azureus spoofing to prevent ban from trackers?
|
||||
- Option to shutdown computer when downloads are finished
|
||||
- NAT checker/Tester
|
||||
- Display hard drive space left?
|
||||
- Make use of dbus on Linux for the single instance instead of socket communication?
|
||||
(http://techbase.kde.org/Development/Tutorials/D-Bus/Accessing_Interfaces)
|
||||
- When favicon can't be downloaded, try to parse the webpage for:
|
||||
<link rel="icon" href="http://example.com/favicon.ico" type="image/vnd.microsoft.icon">
|
||||
* Be carefull, the link can be relative
|
||||
|
||||
// in v1.2.0
|
||||
- Allow user to organize the downloads into categories/folders?
|
||||
|
||||
// in v1.1.0
|
||||
- Tabs support in search
|
||||
- Allow to hide columns?
|
||||
- Allow to scan multiple directories? (useful?)
|
||||
- Web interface (turbogears? php? python?)
|
||||
* Webserver? Try to write a webserver as a plugin for qBittorrent in Python
|
||||
* http://fragments.turtlemeat.com/pythonwebserver.php
|
||||
- improve and test tracker authentication code (remember login/pass) (need a tracker to test this)
|
||||
- support zipped torrents? (useful?)
|
||||
- Allow to limit the number of downloading torrents simultaneously (other are paused until a download finishes)
|
||||
- Improve search plugin install (choose in a list taken from plugins.qbittorrent.org)
|
||||
- Display the number of DHT node if possible
|
||||
- When adding a duplicate torrent, check if the trackers are different from the existing one and ask the user if he wants to add them
|
||||
- Display in torrent addition dialog:
|
||||
* free disk space on selected drive
|
||||
* free disk space after torrent download (and/or torrent size)
|
||||
- Allow to change action on double-click
|
||||
-> in download list
|
||||
-> in seeding list
|
||||
|
||||
// in v1.0.0 - FEATURE FREEZE
|
||||
- Fix all (or almost all) opened bugs in bug tracker
|
||||
- Recheck doc
|
||||
- Translations update (IN PROGRESS)
|
||||
- add qt4-qtconfig as package dependency
|
||||
|
||||
rc4->rc5 changelog:
|
||||
- BUGFIX: Now filtered don't appear on hard drive anymore (libtorrent >= r1659)
|
||||
- BUGFIX: AddInPause setting doesn't pause downloads on startup anymore
|
||||
- BUGFIX: Fixed an ETA calculation problem when the torrent has filtered files
|
||||
- BUGFIX: Fixed possible overflow in ETA calculation
|
||||
- BUGFIX: Fixed "Missing Input path" error when creating a torrent
|
||||
- BUGFIX: Fixed some notification messages for torrent addition dialog
|
||||
- BUGFIX: Fixed "Automatically start seeding" feature in torrent creation tool
|
||||
- COSMETIC: Improved progress bar text rendering
|
||||
254
configure
vendored
@@ -18,14 +18,15 @@ Main options:
|
||||
--help This help text.
|
||||
|
||||
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-libtorrent-inc=[path] Path to libtorrent include files
|
||||
--with-libtorrent-lib=[path] Path to libtorrent library files
|
||||
--with-libtorrent-static-lib=[path] Path to libtorrent .a file
|
||||
--with-libboost-inc=[path] Path to libboost include files
|
||||
--with-libcurl-inc=[path] Path to libcurl include files
|
||||
--with-libcurl-lib=[path] Path to libcurl library files
|
||||
--with-libcommoncpp2-inc=[path] Path to libcommoncpp2 include files
|
||||
--with-libcommoncpp2-lib=[path] Path to libcommoncpp2 library files
|
||||
--disable-libmagick Disable use of libmagick
|
||||
--with-libmagick-inc=[path] Path to libmagick++ include files
|
||||
--with-libmagick-lib=[path] Path to libmagick++ library files
|
||||
--disable-libzzip Disable use of libzzip
|
||||
--with-libzzip-inc=[path] Path to libzzip++ include files
|
||||
--with-libzzip-lib=[path] Path to libzzip++ library files
|
||||
@@ -165,13 +166,28 @@ while [ $# -gt 0 ]; do
|
||||
shift
|
||||
;;
|
||||
|
||||
--with-libcurl-inc=*)
|
||||
QC_WITH_LIBCURL_INC=$optarg
|
||||
--with-libcommoncpp2-inc=*)
|
||||
QC_WITH_LIBCOMMONCPP2_INC=$optarg
|
||||
shift
|
||||
;;
|
||||
|
||||
--with-libcurl-lib=*)
|
||||
QC_WITH_LIBCURL_LIB=$optarg
|
||||
--with-libcommoncpp2-lib=*)
|
||||
QC_WITH_LIBCOMMONCPP2_LIB=$optarg
|
||||
shift
|
||||
;;
|
||||
|
||||
--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
|
||||
;;
|
||||
|
||||
@@ -215,8 +231,11 @@ echo QC_WITH_LIBTORRENT_INC=$QC_WITH_LIBTORRENT_INC
|
||||
echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB
|
||||
echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB
|
||||
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
||||
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
|
||||
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
|
||||
echo QC_WITH_LIBCOMMONCPP2_INC=$QC_WITH_LIBCOMMONCPP2_INC
|
||||
echo QC_WITH_LIBCOMMONCPP2_LIB=$QC_WITH_LIBCOMMONCPP2_LIB
|
||||
echo QC_DISABLE_libmagick=$QC_DISABLE_libmagick
|
||||
echo QC_WITH_LIBMAGICK_INC=$QC_WITH_LIBMAGICK_INC
|
||||
echo QC_WITH_LIBMAGICK_LIB=$QC_WITH_LIBMAGICK_LIB
|
||||
echo QC_DISABLE_libzzip=$QC_DISABLE_libzzip
|
||||
echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC
|
||||
echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB
|
||||
@@ -335,33 +354,29 @@ public:
|
||||
QString shortname() const { return "Qt 4.3"; }
|
||||
bool exec()
|
||||
{
|
||||
if(QT_VERSION >= 0x040400) {
|
||||
conf->addDefine("QT_4_4");
|
||||
}
|
||||
return(QT_VERSION >= 0x040300);
|
||||
|
||||
}
|
||||
};
|
||||
#line 1 "libtorrent-rasterbar.qcm"
|
||||
#line 1 "libtorrent.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
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
|
||||
name: libtorrent
|
||||
arg: with-libtorrent-inc=[path], Path to libtorrent include files
|
||||
arg: with-libtorrent-lib=[path], Path to libtorrent library files
|
||||
arg: with-libtorrent-static-lib=[path], Path to libtorrent .a file
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_libtorrent_rasterbar : public ConfObj
|
||||
class qc_libtorrent : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
|
||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
||||
qc_libtorrent(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libtorrent >= 0.13"; }
|
||||
QString shortname() const { return "libtorrent"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
|
||||
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
@@ -370,7 +385,7 @@ public:
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
|
||||
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -390,19 +405,17 @@ public:
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkLibrary(s, "torrent-rasterbar")) {
|
||||
if(!conf->checkLibrary(s, "torrent")) {
|
||||
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")){
|
||||
if(conf->checkLibrary(s, "torrent")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -410,6 +423,16 @@ public:
|
||||
if(!found) return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}
|
||||
// BUGFIX for Fedora (doesn't support pkg-config?)
|
||||
QFile issue_file("/etc/issue");
|
||||
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||
QString content = issue_file.readAll();
|
||||
issue_file.close();
|
||||
if(content.indexOf("Fedora") != -1){
|
||||
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
|
||||
conf->addLib("-lssl -lcrypto -lboost_date_time -lboost_filesystem -lboost_thread -lz -ltorrent");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -470,25 +493,25 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#line 1 "libcurl.qcm"
|
||||
#line 1 "libcommoncpp2.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libcommoncpp2
|
||||
arg: with-libcurl-inc=[path], Path to libcurl include files
|
||||
arg: with-libcurl-lib=[path], Path to libcurl library files
|
||||
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files
|
||||
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_libcurl : public ConfObj
|
||||
class qc_libcommoncpp2 : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libcurl(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libcurl"; }
|
||||
QString shortname() const { return "libcurl"; }
|
||||
qc_libcommoncpp2(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "GNU Common C++ library (libcommoncpp2)"; }
|
||||
QString shortname() const { return "libcommoncpp2"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "curl/curl.h")) {
|
||||
if(!conf->checkHeader(s, "cc++/url.h")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
@@ -497,7 +520,7 @@ public:
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "curl/curl.h")){
|
||||
if(conf->checkHeader(s, "cc++/url.h")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -508,27 +531,117 @@ public:
|
||||
}
|
||||
conf->addIncludePath(s);
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!QFile::exists(s+QString("/libcurl.so")))
|
||||
return false;
|
||||
if(!QFile::exists(s+QString("libccext2.so")))
|
||||
return false;
|
||||
if(!QFile::exists(s+QString("libccgnu2.so")))
|
||||
return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
sl << "/usr/lib64/";
|
||||
sl << "/usr/local/lib/";
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(QFile::exists(s+QString("libcurl.so"))){
|
||||
found = true;
|
||||
break;
|
||||
if(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);
|
||||
}
|
||||
// BUGFIX for Fedora (doesn't support pkg-config?)
|
||||
QFile issue_file("/etc/issue");
|
||||
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||
QString content = issue_file.readAll();
|
||||
issue_file.close();
|
||||
if(content.indexOf("Fedora") != -1){
|
||||
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
|
||||
conf->addLib("-pthread -lccext2 -lz -lccgnu2 -ldl -lrt");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#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(!QFile::exists(s+QString("libMagick++.so"))){
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
sl << "/usr/local/lib/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(QFile::exists(s+QString("libMagick++.so"))){
|
||||
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;
|
||||
}
|
||||
};
|
||||
@@ -579,15 +692,13 @@ public:
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!QFile::exists(s+QString("/libzzip.so"))){
|
||||
if(!QFile::exists(s+QString("libzzip.so"))){
|
||||
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(QFile::exists(s+QString("libzzip.so"))){
|
||||
@@ -604,24 +715,50 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#line 1 "python.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: python
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_python : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_python(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "python >= 2.3"; }
|
||||
QString shortname() const { return "python"; }
|
||||
bool exec(){
|
||||
int r = conf->doCommand("python testpython.py");
|
||||
if(r == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
EOT
|
||||
cat >$1/modules_new.cpp <<EOT
|
||||
o = new qc_qt4(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libtorrent_rasterbar(conf);
|
||||
o = new qc_libtorrent(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libboost(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libcurl(conf);
|
||||
o = new qc_libcommoncpp2(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libmagick(conf);
|
||||
o->required = false;
|
||||
o->disabled = false;
|
||||
o = new qc_libzzip(conf);
|
||||
o->required = false;
|
||||
o->disabled = false;
|
||||
o = new qc_python(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
|
||||
EOT
|
||||
cat >$1/conf4.h <<EOT
|
||||
@@ -1571,8 +1708,11 @@ export QC_WITH_LIBTORRENT_INC
|
||||
export QC_WITH_LIBTORRENT_LIB
|
||||
export QC_WITH_LIBTORRENT_STATIC_LIB
|
||||
export QC_WITH_LIBBOOST_INC
|
||||
export QC_WITH_LIBCURL_INC
|
||||
export QC_WITH_LIBCURL_LIB
|
||||
export QC_WITH_LIBCOMMONCPP2_INC
|
||||
export QC_WITH_LIBCOMMONCPP2_LIB
|
||||
export QC_DISABLE_libmagick
|
||||
export QC_WITH_LIBMAGICK_INC
|
||||
export QC_WITH_LIBMAGICK_LIB
|
||||
export QC_DISABLE_libzzip
|
||||
export QC_WITH_LIBZZIP_INC
|
||||
export QC_WITH_LIBZZIP_LIB
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
.\" This manpage has been automatically generated by docbook2man
|
||||
.\" from a DocBook document. This tool can be found at:
|
||||
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>.
|
||||
.TH "QBITTORRENT" "1" "September 1st 2007" "Bittorrent client written in C++ / Qt4" ""
|
||||
|
||||
.SH NAME
|
||||
qBittorrent \- a Bittorrent client written in C++ / Qt4
|
||||
.SH SYNOPSIS
|
||||
|
||||
\fBqbittorrent\fR [FILE | URL] [FILE | URL...]
|
||||
|
||||
\fBqbittorrent\fR \-\-help
|
||||
|
||||
\fBqbittorrent\fR \-\-version
|
||||
.PP
|
||||
.SH "DESCRIPTION"
|
||||
|
||||
\fBqBittorrent\fR is an advanced Bittorrent client written in C++ / Qt4,
|
||||
using the \fBrblibtorrent\fR library by Arvid Norberg. qBittorrent aims
|
||||
to be a good alternative to all other bittorrent clients out there. qBittorrent
|
||||
is fast, stable, light, it supports unicode and it provides a good integrated search engine.
|
||||
It also comes with UPnP port forwarding / NAT-PMP, encryption (Azureus compatible), FAST extension (mainline) and PeX support (utorrent compatible).
|
||||
|
||||
Please report any problem to http://bugs.qbittorrent.org
|
||||
.PP
|
||||
.SH "AUTHOR"
|
||||
|
||||
Christophe Dumez <chris@qbittorrent.org>
|
||||
BIN
doc/qbittorrent.1.gz
Normal file
134
packaging/debian-unstable/debian/changelog
Normal file
@@ -0,0 +1,134 @@
|
||||
qbittorrent (0.6.1-1) unstable; urgency=low
|
||||
|
||||
* Disabled debug mode
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Mon, 28 Aug 2006 21:22:48 +0200
|
||||
|
||||
qbittorrent (0.6.1-0) unstable; urgency=low
|
||||
* BUGFIX: Fixed possible segfaults when using context menus
|
||||
* BUGFIX: Cleanup up context menus code
|
||||
* BUGFIX: Used best gzip compressing for manpage
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Thu, 24 Aug 2006 19:53:32 +0200
|
||||
|
||||
qbittorrent (0.6.0) unstable; urgency=low
|
||||
* FEATURE: Rewritten the download list from scratch (more flexible)
|
||||
* FEATURE: Rewritten the search results list from scratch (more flexible)
|
||||
* FEATURE: Rewritten the torrent properties list from scratch (more flexible)
|
||||
* FEATURE: Improved and cleaned up search engine code
|
||||
* FEATURE: Search results are now displayed in real time (not sequentially)
|
||||
* FEATURE: Added two command lines parameters (--version, --help)
|
||||
* FEATURE: Added a popup menu for download list
|
||||
* FEATURE: Double-click on an item now toggles the paused state of a download
|
||||
* FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
|
||||
* FEATURE: Allow to toggle selected state of a file within a torrent using double-click
|
||||
* FEATURE: Remember columns width in download and search results lists
|
||||
* BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
|
||||
* BUGFIX: Fixed ETA calculation when downloading while connecting
|
||||
* BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
|
||||
* BUGFIX: Code cleanup & optimization
|
||||
* BUGFIX: Fixed sorting in download list
|
||||
* BUGFIX: Fixed sorting in search results list
|
||||
* BUGFIX: Fixed Parameters passing between instances
|
||||
* BUGFIX: Fixed missing icon for clear action in infoBar popup menu
|
||||
* BUGFIX: Fixed truncated lines in search results
|
||||
* BUGFIX: Don't refresh download list when user is in search tab (save CPU)
|
||||
* BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
|
||||
* BUGFIX: Save selected search engines only when they have changed (faster program exit)
|
||||
* COSMETIC: Increased icon size in toolbar from 24px to 32px
|
||||
* COSMETIC: Display a progress bar to visualize each download progress
|
||||
* COSMETIC: Size of each result in search are displayed in user friendly units
|
||||
* COSMETIC: Display a progress bar to visualize each file progress within a torrent
|
||||
* COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
|
||||
* COSMETIC: Improved layout of torrent properties window when maximized
|
||||
* COSMETIC: Now number of search results is updated in real time
|
||||
* COSMETIC: Remember last window size
|
||||
* COSMETIC: Improved splash screen look
|
||||
* COSMETIC: Improved default width of columns in download and search results lists
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 22 Aug 2006 10:42:37 +0200
|
||||
|
||||
qbittorrent (0.5.0) unstable; urgency=low
|
||||
* Improved "Download from url" feature (now supports https, ftp & redirections)
|
||||
* Added a torrent creation tool
|
||||
* Display progress for each file within a torrent
|
||||
* Based on new libtorrent v0.10 (lot of improvements)
|
||||
* Now possible to clear log textbox (popup menu)
|
||||
* Added two search engines (isohunt, torrentreactor)
|
||||
* Now Display share ratio on main window
|
||||
* Use OSD (On Screen Display) when a download or a search is finished
|
||||
* Allow only one instance of qBittorrent (and add new parameters to download list)
|
||||
* Remember last selected search engines in search tab
|
||||
* Improved search engines status output (Aborted, timed out, finished, no results)
|
||||
* qBittorrent can now update search plugin from qbittorrent.org
|
||||
* Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
|
||||
* Fixed ThePirateBay parser for search engine (website had changed)
|
||||
* Fixed filenames for results from ThePirateBay search engine
|
||||
* Fixed unicode support for ThePirateBay search engine
|
||||
* Now search results are sorted by seeds
|
||||
* Overwrite nova.py search plugin only if it is outdated
|
||||
* Fixed possible division by 0 in ETA calculation
|
||||
* Improved ETA calculation precision
|
||||
* Fixed default tab in options
|
||||
* When saving options, reconnect only when listening ports changed
|
||||
* qBittorrent has now its own new logo
|
||||
* Display status "downloading" if DL Speed > 0 (even when tracker is down)
|
||||
* Added a splashscreen
|
||||
* qBittorrent has new cute icons
|
||||
* Display number of results in search tab
|
||||
* Added icons for each item in download list according to its state
|
||||
* Redesigned Locale settings
|
||||
* Fixed search engines names width (were cut on the right)
|
||||
* Moved search engines to the left of the window (better ui)
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 2 Aug 2006 19:46:32 +0200
|
||||
|
||||
qbittorrent (0.4.1) unstable; urgency=low
|
||||
* Not counting "protocol chatter" in UP/DL speed anymore
|
||||
* Download speed is now 0 when download is finished
|
||||
* Paused torrents remain paused when qbittorrent is re-started
|
||||
* Added option "go to systray when minimizing"
|
||||
* Added option "Clear finished downloads on exit"
|
||||
* Added option "Ask user for confirmation on exit"
|
||||
* Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
|
||||
* Fixed Search window layout on maximizing
|
||||
* Fixed a bug that caused upload limit not to be always applied
|
||||
* Added Bulgarian translation
|
||||
* Updated Translations
|
||||
* Code optimization
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Thu, 22 Jun 2006 20:14:27 +0200
|
||||
|
||||
qbittorrent (0.4.0) unstable; urgency=low
|
||||
|
||||
* Added a search engine (supports Mininova & thepiratebay websites)
|
||||
* Fixed critical bug: some options were not applied correctly to BT session
|
||||
* Possibility to download a torrent file from an URL
|
||||
* Added confirmation dialog on qbittorrent exit
|
||||
* Enabled sorting in Download list
|
||||
* Added Ukrainian translation
|
||||
* Support urls as program parameters
|
||||
* Added more actions to trayicon menu
|
||||
* Fixed exception catching when retrieving fastresume data
|
||||
* use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
|
||||
* Iconification to systray when minimizing
|
||||
* Code Cleanup & optimization
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 14 Jun 2006 14:47:27 +0200
|
||||
|
||||
qbittorrent (0.3.1) unstable; urgency=low
|
||||
|
||||
* Fixed toolbar layout (spacing).
|
||||
* Added Russian translation.
|
||||
* Resume also finished files on startup (for seeding).
|
||||
* Added colors corresponding to download state.
|
||||
* Fixed a segfault when deleting a download (if no scan dir is set).
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Sat, 6 Jun 2006 21:36:27 +0200
|
||||
|
||||
|
||||
qbittorrent (0.3) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Sat, 3 Jun 2006 21:57:27 +0200
|
||||
1
packaging/debian-unstable/debian/compat
Normal file
@@ -0,0 +1 @@
|
||||
4
|
||||
15
packaging/debian-unstable/debian/control
Normal file
@@ -0,0 +1,15 @@
|
||||
Source: qbittorrent
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Christophe Dumez <chris@qbittorrent.org>
|
||||
Build-Depends: debhelper (>= 4.0.0), autotools-dev, libqt4-core (>= 4.1.0), libqt4-dev (>= 4.1.0), libqt4-gui (>= 4.1.0), rb-libtorrent (>= 0.10), libcurl3-dev
|
||||
Standards-Version: 3.6.2
|
||||
|
||||
Package: qbittorrent
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, rb-libtorrent (>= 0.10), python (>= 2.3)
|
||||
Description: Bittorrent client in Qt4.1 / C++
|
||||
qBittorrent is a bittorrent client programmed in C++ / Qt4.1
|
||||
using rb_libtorrent by Arvid Norberg. It aims to be a good
|
||||
alternative to other bittorrent client out there. It is fast,
|
||||
stable and provides unicode support.
|
||||
26
packaging/debian-unstable/debian/copyright
Normal file
@@ -0,0 +1,26 @@
|
||||
This is qbittorrent, written and maintained by Christophe Dumez <chris@qbittorrent.org>
|
||||
on Sat, 3 Jun 2006 21:57:27 +0200.
|
||||
|
||||
The original source can always be found at:
|
||||
ftp://ftp.debian.org/dists/unstable/main/source/
|
||||
|
||||
Copyright (C) 2006 Christophe Dumez
|
||||
|
||||
License:
|
||||
|
||||
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 package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License can be found in `/usr/share/common-licenses/GPL'.
|
||||
2
packaging/debian-unstable/debian/dirs
Normal file
@@ -0,0 +1,2 @@
|
||||
usr/bin
|
||||
usr/sbin
|
||||
3
packaging/debian-unstable/debian/docs
Normal file
@@ -0,0 +1,3 @@
|
||||
NEWS
|
||||
README
|
||||
TODO
|
||||
107
packaging/debian-unstable/debian/rules
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
|
||||
# These are used for cross-compiling and for saving the configure script
|
||||
# from having to guess our platform (since we know it already)
|
||||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
|
||||
CFLAGS = -Wall
|
||||
|
||||
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
|
||||
CFLAGS += -O0
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
|
||||
config.status: configure
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
CFLAGS="$(CFLAGS) -Wl,-z,defs" ./configure --prefix=/usr
|
||||
|
||||
|
||||
build: build-stamp
|
||||
|
||||
build-stamp: config.status
|
||||
dh_testdir
|
||||
|
||||
# Add here commands to compile the package.
|
||||
$(MAKE)
|
||||
#docbook-to-man debian/qbittorrent.sgml > qbittorrent.1
|
||||
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
-$(MAKE) distclean
|
||||
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
|
||||
cp -f /usr/share/misc/config.sub config.sub
|
||||
endif
|
||||
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
|
||||
cp -f /usr/share/misc/config.guess config.guess
|
||||
endif
|
||||
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/qbittorrent.
|
||||
$(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/qbittorrent
|
||||
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installchangelogs Changelog
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
# dh_install
|
||||
# dh_installmenu
|
||||
# dh_installdebconf
|
||||
# dh_installlogrotate
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installmime
|
||||
# dh_installinit
|
||||
# dh_installcron
|
||||
# dh_installinfo
|
||||
dh_installman
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# dh_perl
|
||||
# dh_python
|
||||
# dh_makeshlibs
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
249
packaging/mandriva/qbittorrent.spec
Normal file
@@ -0,0 +1,249 @@
|
||||
|
||||
%define name qbittorrent
|
||||
%define major 0
|
||||
%define minor 6
|
||||
%define patch 1
|
||||
%define version %{major}.%{minor}.%{patch}
|
||||
%define release %mkrel 2
|
||||
%define _iconsdir %{_datadir}/icons
|
||||
%define _mandir %_datadir/man
|
||||
|
||||
Name: %{name}
|
||||
Summary: A Bittorrent Client using C++ / Qt4
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
Source0: http://sourceforge.net/projects/qbittorrent/%{name}-%{version}.tar.gz
|
||||
URL: http://sourceforge.net/projects/qbittorrent
|
||||
Vendor: http://qbittorrent.sourceforge.net/
|
||||
Group: Internet/File Transfer
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
|
||||
License: GPL
|
||||
BuildRequires: libqt4-devel >= 4.1.2, libqtgui4 >= 4.1.2, libqtcore4 >= 4.1.2, libqtxml4 >= 4.1.2, libqtnetwork4 >= 4.1.2, rb_libtorrent-devel >= 0.10-3, libcurl3-devel
|
||||
Requires: libqtgui4 >= 4.1.2, libqtcore4 >= 4.1.2, libqtxml4 >= 4.1.2, libqtnetwork4 >= 4.1.2, librb_libtorrent0 >= 0.10-3, python >= 2.3, libcurl3
|
||||
|
||||
%description
|
||||
A Bittorrent client using C++ / libtorrent and a Qt4 Graphical User Interface.
|
||||
It aims to be as fast as possible and to provide multi-OS, unicode support.
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
# Export the Environment variables
|
||||
export QTDIR=%_prefix/%_lib/qt4
|
||||
export KDEDIR=%_prefix
|
||||
export LD_LIBRARY_PATH=$QTDIR/%_lib:$KDEDIR/%_lib:$LD_LIBRARY_PATH
|
||||
export PATH=$QTDIR/bin:$KDEDIR/bin:$PATH
|
||||
|
||||
|
||||
# Change to the Source directory and configure
|
||||
#cd src
|
||||
CFLAGS="%optflags" CXXFLAGS="%optflags" \
|
||||
./configure --prefix=%{buildroot}%{_prefix}
|
||||
|
||||
# Necessary to remove old compiled files.. if they exist
|
||||
make clean
|
||||
|
||||
%make
|
||||
|
||||
%install
|
||||
%makeinstall --directory=src
|
||||
|
||||
|
||||
# Create the menu directory
|
||||
install -d %{buildroot}%{_menudir}
|
||||
|
||||
# Build the Menu
|
||||
#<package> <section> <file_in> <file_out> [requires] [title]
|
||||
kdedesktop2mdkmenu.pl %{name} "%{group}" %{buildroot}%{_datadir}/applications/qBittorrent.desktop %{buildroot}%{_menudir}/%{name}
|
||||
|
||||
%clean
|
||||
%{__rm} -rf %{buildroot}
|
||||
|
||||
%post
|
||||
/sbin/ldconfig
|
||||
%{update_menus}
|
||||
|
||||
%postun
|
||||
/sbin/ldconfig
|
||||
%{clean_menus}
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc README INSTALL NEWS COPYING AUTHORS TODO Changelog
|
||||
%doc %{_mandir}/man1/*.bz2
|
||||
|
||||
|
||||
# The binaries
|
||||
%_bindir/*
|
||||
|
||||
|
||||
# Icon files
|
||||
# Hi and Lo colour icons various sizes
|
||||
%_iconsdir/hicolor/128x128/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/16x16/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/192x192/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/22x22/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/24x24/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/32x32/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/36x36/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/48x48/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/64x64/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/72x72/apps/qbittorrent.png
|
||||
%_iconsdir/hicolor/96x96/apps/qbittorrent.png
|
||||
## %_iconsdir/hicolor/scalable/apps/qbittorrent.svgz
|
||||
|
||||
|
||||
# Desktop Link
|
||||
%_datadir/applications/qBittorrent.desktop
|
||||
|
||||
# The qbittorrent Menu directory
|
||||
%dir %{_menudir}
|
||||
%{_menudir}/%{name}
|
||||
|
||||
|
||||
%changelog
|
||||
|
||||
* Wed Aug 23 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.6.0-0.1.2006mdk
|
||||
- FEATURE: Rewritten the download list from scratch (more flexible)
|
||||
- FEATURE: Rewritten the search results list from scratch (more flexible)
|
||||
- FEATURE: Rewritten the torrent properties list from scratch (more flexible)
|
||||
- FEATURE: Improved and cleaned up search engine code
|
||||
- FEATURE: Search results are now displayed in real time (not sequentially)
|
||||
- FEATURE: Added two command lines parameters (--version, --help)
|
||||
- FEATURE: Added a popup menu for download list
|
||||
- FEATURE: Double-click on an item now toggles the paused state of a download
|
||||
- FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
|
||||
- FEATURE: Allow to toggle selected state of a file within a torrent using double-click
|
||||
- FEATURE: Remember columns width in download and search results lists
|
||||
- BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
|
||||
- BUGFIX: Fixed ETA calculation when downloading while connecting
|
||||
- BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
|
||||
- BUGFIX: Code cleanup & optimization
|
||||
- BUGFIX: Fixed sorting in download list
|
||||
- BUGFIX: Fixed sorting in search results list
|
||||
- BUGFIX: Fixed Parameters passing between instances
|
||||
- BUGFIX: Fixed missing icon for clear action in infoBar popup menu
|
||||
- BUGFIX: Fixed truncated lines in search results
|
||||
- BUGFIX: Don't refresh download list when user is in search tab (save CPU)
|
||||
- BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
|
||||
- BUGFIX: Save selected search engines only when they have changed (faster program exit)
|
||||
- COSMETIC: Increased icon size in toolbar from 24px to 32px
|
||||
- COSMETIC: Display a progress bar to visualize each download progress
|
||||
- COSMETIC: Size of each result in search are displayed in user friendly units
|
||||
- COSMETIC: Display a progress bar to visualize each file progress within a torrent
|
||||
- COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
|
||||
- COSMETIC: Improved layout of torrent properties window when maximized
|
||||
- COSMETIC: Now number of search results is updated in real time
|
||||
- COSMETIC: Remember last window size
|
||||
- COSMETIC: Improved splash screen look
|
||||
- COSMETIC: Improved default width of columns in download and search results lists
|
||||
|
||||
* Tue Aug 08 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.5.0-0.1.20060mdk
|
||||
- FEATURE: Improved "Download from url" feature (now supports https, ftp & redirections)
|
||||
- FEATURE: Added a torrent creation tool
|
||||
- FEATURE: Display progress for each file within a torrent
|
||||
- FEATURE: Based on new libtorrent v0.10 (lot of improvements)
|
||||
- FEATURE: Now possible to clear log textbox (popup menu)
|
||||
- FEATURE: Added two search engines (isohunt, torrentreactor)
|
||||
- FEATURE: Now Display share ratio on main window
|
||||
- FEATURE: Use OSD (On Screen Display) when a download or a search is finished
|
||||
- FEATURE: Allow only one instance of qBittorrent (and add new parameters to download list)
|
||||
- FEATURE: Remember last selected search engines in search tab
|
||||
- FEATURE: Improved search engines status output (Aborted, timed out, finished, no results)
|
||||
- FEATURE: qBittorrent can now update search plugin from qbittorrent.org
|
||||
- I18N: Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
|
||||
- BUGFIX: Fixed ThePirateBay parser for search engine (website had changed)
|
||||
- BUGFIX: Fixed filenames for results from ThePirateBay search engine
|
||||
- BUGFIX: Fixed unicode support for ThePirateBay search engine
|
||||
- BUGFIX: Now search results are sorted by seeds
|
||||
- BUGFIX: Overwrite nova.py search plugin only if it is outdated
|
||||
- BUGFIX: Fixed possible division by 0 in ETA calculation
|
||||
- BUGFIX: Improved ETA calculation precision
|
||||
- BUGFIX: Fixed default tab in options
|
||||
- BUGFIX: When saving options, reconnect only when listening ports changed
|
||||
- COSMETIC: qBittorrent has now its own new logo
|
||||
- COSMETIC: Display status "downloading" if DL Speed > 0 (even when tracker is down)
|
||||
- COSMETIC: Added a splashscreen
|
||||
- COSMETIC: qBittorrent has new cute icons
|
||||
- COSMETIC: Display number of results in search tab
|
||||
- COSMETIC: Added icons for each item in download list according to its state
|
||||
- COSMETIC: Redesigned Locale settings
|
||||
- COSMETIC: Fixed search engines names width (were cut on the right)
|
||||
- COSMETIC: Moved search engines to the left of the window (better ui)
|
||||
|
||||
* Fri Jun 23 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.4.1-0.1.20060mdk
|
||||
- Not counting "protocol chatter" in UP/DL speed anymore
|
||||
- Download speed is now 0 when download is finished
|
||||
- Paused torrents remain paused when qbittorrent is re-started
|
||||
- Added option "go to systray when minimizing"
|
||||
- Added option "Clear finished downloads on exit"
|
||||
- Added option "Ask user for confirmation on exit"
|
||||
- Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
|
||||
- Fixed Search window layout on maximizing
|
||||
- Fixed a bug that caused upload limit not to be always applied
|
||||
- Added Bulgarian translation
|
||||
- Updated Translations
|
||||
- Code optimization
|
||||
|
||||
* Tue Jun 13 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.4.0-0.1.20060mdk
|
||||
- Added a search engine (supports Mininova & thepiratebay websites)
|
||||
- Fixed critical bug: some options were not applied correctly to BT session
|
||||
- Possibility to download a torrent file from an URL
|
||||
- Added confirmation dialog on qbittorrent exit
|
||||
- Enabled sorting in Download list
|
||||
- Added Ukrainian translation
|
||||
- Support urls as program parameters
|
||||
- Added more actions to trayicon menu
|
||||
- Fixed exception catching when retrieving fastresume data
|
||||
- use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
|
||||
- Iconification to systray when minimizing
|
||||
- Code Cleanup & optimization
|
||||
|
||||
* Tue Jun 06 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.3.1-0.1.20060mdk
|
||||
- Fixed toolbar layout (spacing)
|
||||
- Added Russian translation
|
||||
- Resume also finished files on startup (for seeding)
|
||||
- Added colors corresponding to download state
|
||||
- Fixed a segfault when deleting a download (if no scan dir is set)
|
||||
|
||||
* Mon Jun 05 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.3-0.1.20060mdk
|
||||
- Fixed auto-resume (worked only once)
|
||||
- Fixed BT_Backup dir creation on first startup (thanks Peter)
|
||||
- Now min port and max port are inverted if (min port > max port)
|
||||
- Fixed memory leaks
|
||||
- Added qbittorrent man page
|
||||
- Allow to disable max connections limit (default is disabled)
|
||||
- Disable upload limit by default
|
||||
- Added Menu Entry with icon (thanks Peter)
|
||||
- Restructured directory, now Makefile is in main directory (not src/)
|
||||
- Updated README / INSTALL
|
||||
|
||||
* Fri Jun 02 2006 - Christophe Dumez <chris@qbittorrent.org> 0.2.3-0.1.20060mdk
|
||||
- Fixed ports checking function (user couldn't type the value he wanted)
|
||||
- Check tracker errors list size and clear it if it becomes too big.
|
||||
- qBittorrent does not remove .torrent file from scanned directory anymore
|
||||
- Small cosmetic change
|
||||
|
||||
* Wed May 31 2006 Christophe Dumez <chris@qbittorrent.org> 0.2.2-0.1.20060mdk
|
||||
- Fixed missing icons
|
||||
|
||||
* Sat May 27 2006 Jeffery Fernandez <developer@jefferyfernandez.id.au> 0.2.1-0.1.20060mdk
|
||||
- Initial Build for Mandriva Linux
|
||||
|
||||
* Thu May 25 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
- Fixed "make install" rule
|
||||
- Disabled debug mode
|
||||
|
||||
* Thu May 25 2006 Christophe Dumez <chris@qbittorrent.org> - v0.2
|
||||
- Fixed a compatibility problem with some versions of qmake
|
||||
- Added translations : Greek, Swedish
|
||||
- Fixed Polish translation selection
|
||||
- Fixed come warning because of two unexisting slots
|
||||
- Improved "Apply" button behaviour in options
|
||||
- Windows are now resizable
|
||||
|
||||
* Tue May 16 2006 Christophe Dumez <chris@qbittorrent.org> - v0.1
|
||||
- Initial release (lack features & still need a lot of improvements)
|
||||
|
||||
147
packaging/mandriva/rb_libtorrent.spec
Normal file
@@ -0,0 +1,147 @@
|
||||
|
||||
%define package_name rb_libtorrent
|
||||
%define orig_name libtorrent
|
||||
%define major 0
|
||||
%define minor .10
|
||||
%define patch .1
|
||||
%define version %{major}%{minor}
|
||||
%define candidate -rc1
|
||||
%define lib_name %mklibname %{package_name} %{major}
|
||||
%define release %mkrel 4
|
||||
|
||||
Summary : libtorrent is a C++ bittorrent library.
|
||||
Name : %{package_name}
|
||||
Version : %{version}
|
||||
Release : %{release}
|
||||
License : GPL
|
||||
Group : Development/C++
|
||||
Source0 : http://www.rasterbar.com/products/libtorrent/libtorrent-%{version}.tar.gz
|
||||
URL : http://www.rasterbar.com
|
||||
BuildRequires : boost >= 1.33.1
|
||||
BuildRoot : %{_tmppath}/%{orig_name}-%{version}-%{release}-root
|
||||
Patch0 : file_progress_arvid.patch.bz2
|
||||
|
||||
%description
|
||||
libtorrent is a C++ library that aims to be a good alternative
|
||||
to all the other bittorrent implementations around.
|
||||
|
||||
|
||||
%package -n %{package_name}-devel
|
||||
Group : Development/C++
|
||||
Summary : Development files for %{package_name}
|
||||
Conflicts : libtorrent7-devel
|
||||
|
||||
%description -n %{package_name}-devel
|
||||
Development files for %{package_name}
|
||||
|
||||
%package -n %{lib_name}
|
||||
Group : Development/C++
|
||||
Summary : Library files for %{package_name}
|
||||
Conflicts : libtorrent7
|
||||
|
||||
%description -n %{lib_name}
|
||||
Library files for %{package_name}
|
||||
|
||||
%prep
|
||||
%setup -n %{orig_name}-%{version}
|
||||
|
||||
%build
|
||||
%configure --prefix=%{_prefix}
|
||||
%make
|
||||
|
||||
|
||||
%install
|
||||
%makeinstall
|
||||
|
||||
# Create directories for the package
|
||||
install -d %{buildroot}%{_includedir}/%{orig_name}
|
||||
install -d %{buildroot}%{_libdir}/pkgconfig
|
||||
|
||||
%clean
|
||||
rm -rf %{buildroot}
|
||||
|
||||
# The binaries
|
||||
%files %(orig_name)
|
||||
%defattr(0644, root, root, 0755)
|
||||
%{_bindir}/*
|
||||
|
||||
# Documentation
|
||||
%defattr(-, root, root)
|
||||
%doc README AUTHORS INSTALL COPYING ChangeLog NEWS
|
||||
%doc docs/*
|
||||
|
||||
|
||||
# Devel Package
|
||||
%files -n %{package_name}-devel
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_includedir}/%{orig_name}/
|
||||
%dir %{_includedir}/%{orig_name}/asio/
|
||||
%dir %{_includedir}/%{orig_name}/asio/detail/
|
||||
%dir %{_includedir}/%{orig_name}/asio/impl/
|
||||
%dir %{_includedir}/%{orig_name}/asio/ip/
|
||||
%dir %{_includedir}/%{orig_name}/asio/ip/detail/
|
||||
%dir %{_includedir}/%{orig_name}/asio/ssl/
|
||||
%dir %{_includedir}/%{orig_name}/asio/ssl/detail/
|
||||
%{_includedir}/%{orig_name}/*.hpp
|
||||
%{_includedir}/%{orig_name}/asio/*.hpp
|
||||
%{_includedir}/%{orig_name}/asio/detail/*.hpp
|
||||
%{_includedir}/%{orig_name}/asio/impl/*.ipp
|
||||
%{_includedir}/%{orig_name}/asio/ip/*.hpp
|
||||
%{_includedir}/%{orig_name}/asio/ip/detail/*.hpp
|
||||
%{_includedir}/%{orig_name}/asio/ssl/*.hpp
|
||||
%{_includedir}/%{orig_name}/asio/ssl/detail/*.hpp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%{_libdir}/%{orig_name}.a
|
||||
%{_libdir}/%{orig_name}.la
|
||||
%{_libdir}/%{orig_name}.so
|
||||
%{_libdir}/pkgconfig/libtorrent.pc
|
||||
|
||||
|
||||
# Library Package
|
||||
%files -n %{lib_name}
|
||||
%defattr(-,root,root,-)
|
||||
%_libdir/%{orig_name}.so.*
|
||||
|
||||
|
||||
%changelog
|
||||
|
||||
* Wed Aug 23 2006 Christophe Dumez <chris@qbittorrent.org> 10.0.1-2006mdk
|
||||
- Added patch for Torrent Properties crash fix
|
||||
|
||||
* Sat Jul 1 2006 %{packager} %{version}-%{release}
|
||||
- fixed a bug where the requested number of peers in a tracker request could
|
||||
be too big.
|
||||
- fixed a bug where empty files were not created in full allocation mode.
|
||||
- fixed a bug in storage that would, in rare cases, fail to do a
|
||||
complete check.
|
||||
- exposed more settings for tweaking parameters in the piece-picker,
|
||||
downloader and uploader (http_settings replaced by session_settings).
|
||||
- tweaked default settings to improve high bandwidth transfers.
|
||||
- improved the piece picker performance and made it possible to download
|
||||
popular pieces in sequence to improve disk performance.
|
||||
- added the possibility to control upload and download limits per peer.
|
||||
- fixed problem with re-requesting skipped pieces when peer was sending pieces
|
||||
out of fifo-order.
|
||||
- added support for http seeding (the GetRight protocol)
|
||||
- renamed identifiers called 'id' in the public interface to support linking
|
||||
with Objective.C++
|
||||
- changed the extensions protocol to use the new one, which is also
|
||||
implemented by uTorrent.
|
||||
- factorized the peer_connection and added web_peer_connection which is
|
||||
able to download from http-sources.
|
||||
- converted the network code to use asio (resulted in slight api changes
|
||||
dealing with network addresses).
|
||||
- made libtorrent build in vc7 (patches from Allen Zhao)
|
||||
- fixed bug caused when binding outgoing connections to a non-local interface.
|
||||
- add_torrent() will now throw if called while the session object is
|
||||
being closed.
|
||||
- added the ability to limit the number of simultaneous half-open
|
||||
TCP connections. Flags in peer_info has been added.
|
||||
|
||||
|
||||
* Thu Jun 1 2006 %{packager} %{version}-%{release}
|
||||
- Initial Build for Mandriva Linux
|
||||
134
packaging/ubuntu-dapper/debian/changelog
Normal file
@@ -0,0 +1,134 @@
|
||||
qbittorrent (0.6.1-0ubuntu2) dapper; urgency=low
|
||||
|
||||
* Disabled debug mode
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Mon, 28 Aug 2006 19:29:17 +0000
|
||||
|
||||
qbittorrent (0.6.1-0ubuntu1) dapper; urgency=low
|
||||
* BUGFIX: Fixed possible segfaults when using context menus
|
||||
* BUGFIX: Cleanup up context menus code
|
||||
* BUGFIX: Used best gzip compressing for manpage
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Thu, 24 Aug 2006 19:53:32 +0200
|
||||
|
||||
qbittorrent (0.6.0) dapper; urgency=low
|
||||
* FEATURE: Rewritten the download list from scratch (more flexible)
|
||||
* FEATURE: Rewritten the search results list from scratch (more flexible)
|
||||
* FEATURE: Rewritten the torrent properties list from scratch (more flexible)
|
||||
* FEATURE: Improved and cleaned up search engine code
|
||||
* FEATURE: Search results are now displayed in real time (not sequentially)
|
||||
* FEATURE: Added two command lines parameters (--version, --help)
|
||||
* FEATURE: Added a popup menu for download list
|
||||
* FEATURE: Double-click on an item now toggles the paused state of a download
|
||||
* FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
|
||||
* FEATURE: Allow to toggle selected state of a file within a torrent using double-click
|
||||
* FEATURE: Remember columns width in download and search results lists
|
||||
* BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
|
||||
* BUGFIX: Fixed ETA calculation when downloading while connecting
|
||||
* BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
|
||||
* BUGFIX: Code cleanup & optimization
|
||||
* BUGFIX: Fixed sorting in download list
|
||||
* BUGFIX: Fixed sorting in search results list
|
||||
* BUGFIX: Fixed Parameters passing between instances
|
||||
* BUGFIX: Fixed missing icon for clear action in infoBar popup menu
|
||||
* BUGFIX: Fixed truncated lines in search results
|
||||
* BUGFIX: Don't refresh download list when user is in search tab (save CPU)
|
||||
* BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
|
||||
* BUGFIX: Save selected search engines only when they have changed (faster program exit)
|
||||
* COSMETIC: Increased icon size in toolbar from 24px to 32px
|
||||
* COSMETIC: Display a progress bar to visualize each download progress
|
||||
* COSMETIC: Size of each result in search are displayed in user friendly units
|
||||
* COSMETIC: Display a progress bar to visualize each file progress within a torrent
|
||||
* COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
|
||||
* COSMETIC: Improved layout of torrent properties window when maximized
|
||||
* COSMETIC: Now number of search results is updated in real time
|
||||
* COSMETIC: Remember last window size
|
||||
* COSMETIC: Improved splash screen look
|
||||
* COSMETIC: Improved default width of columns in download and search results lists
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 22 Aug 2006 10:42:37 +0200
|
||||
|
||||
qbittorrent (0.5.0) dapper; urgency=low
|
||||
* Improved "Download from url" feature (now supports https, ftp & redirections)
|
||||
* Added a torrent creation tool
|
||||
* Display progress for each file within a torrent
|
||||
* Based on new libtorrent v0.10 (lot of improvements)
|
||||
* Now possible to clear log textbox (popup menu)
|
||||
* Added two search engines (isohunt, torrentreactor)
|
||||
* Now Display share ratio on main window
|
||||
* Use OSD (On Screen Display) when a download or a search is finished
|
||||
* Allow only one instance of qBittorrent (and add new parameters to download list)
|
||||
* Remember last selected search engines in search tab
|
||||
* Improved search engines status output (Aborted, timed out, finished, no results)
|
||||
* qBittorrent can now update search plugin from qbittorrent.org
|
||||
* Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
|
||||
* Fixed ThePirateBay parser for search engine (website had changed)
|
||||
* Fixed filenames for results from ThePirateBay search engine
|
||||
* Fixed unicode support for ThePirateBay search engine
|
||||
* Now search results are sorted by seeds
|
||||
* Overwrite nova.py search plugin only if it is outdated
|
||||
* Fixed possible division by 0 in ETA calculation
|
||||
* Improved ETA calculation precision
|
||||
* Fixed default tab in options
|
||||
* When saving options, reconnect only when listening ports changed
|
||||
* qBittorrent has now its own new logo
|
||||
* Display status "downloading" if DL Speed > 0 (even when tracker is down)
|
||||
* Added a splashscreen
|
||||
* qBittorrent has new cute icons
|
||||
* Display number of results in search tab
|
||||
* Added icons for each item in download list according to its state
|
||||
* Redesigned Locale settings
|
||||
* Fixed search engines names width (were cut on the right)
|
||||
* Moved search engines to the left of the window (better ui)
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 2 Aug 2006 19:46:32 +0200
|
||||
|
||||
qbittorrent (0.4.1) dapper; urgency=low
|
||||
* Not counting "protocol chatter" in UP/DL speed anymore
|
||||
* Download speed is now 0 when download is finished
|
||||
* Paused torrents remain paused when qbittorrent is re-started
|
||||
* Added option "go to systray when minimizing"
|
||||
* Added option "Clear finished downloads on exit"
|
||||
* Added option "Ask user for confirmation on exit"
|
||||
* Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
|
||||
* Fixed Search window layout on maximizing
|
||||
* Fixed a bug that caused upload limit not to be always applied
|
||||
* Added Bulgarian translation
|
||||
* Updated Translations
|
||||
* Code optimization
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Thu, 22 Jun 2006 20:14:27 +0200
|
||||
|
||||
qbittorrent (0.4.0) dapper; urgency=low
|
||||
|
||||
* Added a search engine (supports Mininova & thepiratebay websites)
|
||||
* Fixed critical bug: some options were not applied correctly to BT session
|
||||
* Possibility to download a torrent file from an URL
|
||||
* Added confirmation dialog on qbittorrent exit
|
||||
* Enabled sorting in Download list
|
||||
* Added Ukrainian translation
|
||||
* Support urls as program parameters
|
||||
* Added more actions to trayicon menu
|
||||
* Fixed exception catching when retrieving fastresume data
|
||||
* use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
|
||||
* Iconification to systray when minimizing
|
||||
* Code Cleanup & optimization
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 14 Jun 2006 14:47:27 +0200
|
||||
|
||||
qbittorrent (0.3.1) dapper; urgency=low
|
||||
|
||||
* Fixed toolbar layout (spacing).
|
||||
* Added Russian translation.
|
||||
* Resume also finished files on startup (for seeding).
|
||||
* Added colors corresponding to download state.
|
||||
* Fixed a segfault when deleting a download (if no scan dir is set).
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Sat, 6 Jun 2006 21:36:27 +0200
|
||||
|
||||
|
||||
qbittorrent (0.3) dapper; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Sat, 3 Jun 2006 21:57:27 +0200
|
||||
1
packaging/ubuntu-dapper/debian/compat
Normal file
@@ -0,0 +1 @@
|
||||
4
|
||||
15
packaging/ubuntu-dapper/debian/control
Normal file
@@ -0,0 +1,15 @@
|
||||
Source: qbittorrent
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Christophe Dumez <chris@qbittorrent.org>
|
||||
Build-Depends: debhelper (>= 4.0.0), autotools-dev, libqt4-core (>= 4.1.0), libqt4-dev (>= 4.1.0), libqt4-gui (>= 4.1.0), rb-libtorrent (>= 0.10), libcurl3-dev
|
||||
Standards-Version: 3.6.2
|
||||
|
||||
Package: qbittorrent
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, rb-libtorrent (>= 0.10), python (>= 2.3)
|
||||
Description: Bittorrent client in Qt4.1 / C++
|
||||
qBittorrent is a bittorrent client programmed in C++ / Qt4.1
|
||||
using rb_libtorrent by Arvid Norberg. It aims to be a good
|
||||
alternative to other bittorrent client out there. It is fast,
|
||||
stable and provides unicode support.
|
||||
26
packaging/ubuntu-dapper/debian/copyright
Normal file
@@ -0,0 +1,26 @@
|
||||
This is qbittorrent, written and maintained by Christophe Dumez <chris@qbittorrent.org>
|
||||
on Sat, 3 Jun 2006 21:57:27 +0200.
|
||||
|
||||
The original source can always be found at:
|
||||
ftp://ftp.debian.org/dists/unstable/main/source/
|
||||
|
||||
Copyright (C) 2006 Christophe Dumez
|
||||
|
||||
License:
|
||||
|
||||
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 package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License can be found in `/usr/share/common-licenses/GPL'.
|
||||
2
packaging/ubuntu-dapper/debian/dirs
Normal file
@@ -0,0 +1,2 @@
|
||||
usr/bin
|
||||
usr/sbin
|
||||
3
packaging/ubuntu-dapper/debian/docs
Normal file
@@ -0,0 +1,3 @@
|
||||
NEWS
|
||||
README
|
||||
TODO
|
||||
1
packaging/ubuntu-dapper/debian/files
Normal file
@@ -0,0 +1 @@
|
||||
qbittorrent_0.6.1-0ubuntu2_i386.deb net optional
|
||||
1
packaging/ubuntu-dapper/debian/qbittorrent.substvars
Normal file
@@ -0,0 +1 @@
|
||||
shlibs:Depends=libboost-date-time1.33.1, libboost-filesystem1.33.1, libboost-thread1.33.1, libc6 (>= 2.3.4-1), libcurl3 (>= 7.15.0-1), libgcc1 (>= 1:4.0.2), libqt4-core (>= 4.1.2), libqt4-gui (>= 4.1.2), libstdc++6 (>= 4.0.2-4), libx11-6, libxext6, zlib1g (>= 1:1.2.1)
|
||||
107
packaging/ubuntu-dapper/debian/rules
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
|
||||
# These are used for cross-compiling and for saving the configure script
|
||||
# from having to guess our platform (since we know it already)
|
||||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
|
||||
CFLAGS = -Wall
|
||||
|
||||
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
|
||||
CFLAGS += -O0
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
|
||||
config.status: configure
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
CFLAGS="$(CFLAGS) -Wl,-z,defs" ./configure --prefix=/usr
|
||||
|
||||
|
||||
build: build-stamp
|
||||
|
||||
build-stamp: config.status
|
||||
dh_testdir
|
||||
|
||||
# Add here commands to compile the package.
|
||||
$(MAKE)
|
||||
#docbook-to-man debian/qbittorrent.sgml > qbittorrent.1
|
||||
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
-$(MAKE) distclean
|
||||
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
|
||||
cp -f /usr/share/misc/config.sub config.sub
|
||||
endif
|
||||
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
|
||||
cp -f /usr/share/misc/config.guess config.guess
|
||||
endif
|
||||
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/qbittorrent.
|
||||
$(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/qbittorrent
|
||||
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installchangelogs Changelog
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
# dh_install
|
||||
# dh_installmenu
|
||||
# dh_installdebconf
|
||||
# dh_installlogrotate
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installmime
|
||||
# dh_installinit
|
||||
# dh_installcron
|
||||
# dh_installinfo
|
||||
dh_installman
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# dh_perl
|
||||
# dh_python
|
||||
# dh_makeshlibs
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
134
packaging/ubuntu-edgy/debian/changelog
Normal file
@@ -0,0 +1,134 @@
|
||||
qbittorrent (0.6.1-0ubuntu2) edgy; urgency=low
|
||||
|
||||
* Disabled debug mode
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Mon, 28 Aug 2006 21:22:48 +0200
|
||||
|
||||
qbittorrent (0.6.1-0ubuntu1) edgy; urgency=low
|
||||
* BUGFIX: Fixed possible segfaults when using context menus
|
||||
* BUGFIX: Cleanup up context menus code
|
||||
* BUGFIX: Used best gzip compressing for manpage
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Thu, 24 Aug 2006 19:53:32 +0200
|
||||
|
||||
qbittorrent (0.6.0) edgy; urgency=low
|
||||
* FEATURE: Rewritten the download list from scratch (more flexible)
|
||||
* FEATURE: Rewritten the search results list from scratch (more flexible)
|
||||
* FEATURE: Rewritten the torrent properties list from scratch (more flexible)
|
||||
* FEATURE: Improved and cleaned up search engine code
|
||||
* FEATURE: Search results are now displayed in real time (not sequentially)
|
||||
* FEATURE: Added two command lines parameters (--version, --help)
|
||||
* FEATURE: Added a popup menu for download list
|
||||
* FEATURE: Double-click on an item now toggles the paused state of a download
|
||||
* FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
|
||||
* FEATURE: Allow to toggle selected state of a file within a torrent using double-click
|
||||
* FEATURE: Remember columns width in download and search results lists
|
||||
* BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
|
||||
* BUGFIX: Fixed ETA calculation when downloading while connecting
|
||||
* BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
|
||||
* BUGFIX: Code cleanup & optimization
|
||||
* BUGFIX: Fixed sorting in download list
|
||||
* BUGFIX: Fixed sorting in search results list
|
||||
* BUGFIX: Fixed Parameters passing between instances
|
||||
* BUGFIX: Fixed missing icon for clear action in infoBar popup menu
|
||||
* BUGFIX: Fixed truncated lines in search results
|
||||
* BUGFIX: Don't refresh download list when user is in search tab (save CPU)
|
||||
* BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
|
||||
* BUGFIX: Save selected search engines only when they have changed (faster program exit)
|
||||
* COSMETIC: Increased icon size in toolbar from 24px to 32px
|
||||
* COSMETIC: Display a progress bar to visualize each download progress
|
||||
* COSMETIC: Size of each result in search are displayed in user friendly units
|
||||
* COSMETIC: Display a progress bar to visualize each file progress within a torrent
|
||||
* COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
|
||||
* COSMETIC: Improved layout of torrent properties window when maximized
|
||||
* COSMETIC: Now number of search results is updated in real time
|
||||
* COSMETIC: Remember last window size
|
||||
* COSMETIC: Improved splash screen look
|
||||
* COSMETIC: Improved default width of columns in download and search results lists
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 22 Aug 2006 10:42:37 +0200
|
||||
|
||||
qbittorrent (0.5.0) edgy; urgency=low
|
||||
* Improved "Download from url" feature (now supports https, ftp & redirections)
|
||||
* Added a torrent creation tool
|
||||
* Display progress for each file within a torrent
|
||||
* Based on new libtorrent v0.10 (lot of improvements)
|
||||
* Now possible to clear log textbox (popup menu)
|
||||
* Added two search engines (isohunt, torrentreactor)
|
||||
* Now Display share ratio on main window
|
||||
* Use OSD (On Screen Display) when a download or a search is finished
|
||||
* Allow only one instance of qBittorrent (and add new parameters to download list)
|
||||
* Remember last selected search engines in search tab
|
||||
* Improved search engines status output (Aborted, timed out, finished, no results)
|
||||
* qBittorrent can now update search plugin from qbittorrent.org
|
||||
* Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
|
||||
* Fixed ThePirateBay parser for search engine (website had changed)
|
||||
* Fixed filenames for results from ThePirateBay search engine
|
||||
* Fixed unicode support for ThePirateBay search engine
|
||||
* Now search results are sorted by seeds
|
||||
* Overwrite nova.py search plugin only if it is outdated
|
||||
* Fixed possible division by 0 in ETA calculation
|
||||
* Improved ETA calculation precision
|
||||
* Fixed default tab in options
|
||||
* When saving options, reconnect only when listening ports changed
|
||||
* qBittorrent has now its own new logo
|
||||
* Display status "downloading" if DL Speed > 0 (even when tracker is down)
|
||||
* Added a splashscreen
|
||||
* qBittorrent has new cute icons
|
||||
* Display number of results in search tab
|
||||
* Added icons for each item in download list according to its state
|
||||
* Redesigned Locale settings
|
||||
* Fixed search engines names width (were cut on the right)
|
||||
* Moved search engines to the left of the window (better ui)
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 2 Aug 2006 19:46:32 +0200
|
||||
|
||||
qbittorrent (0.4.1) edgy; urgency=low
|
||||
* Not counting "protocol chatter" in UP/DL speed anymore
|
||||
* Download speed is now 0 when download is finished
|
||||
* Paused torrents remain paused when qbittorrent is re-started
|
||||
* Added option "go to systray when minimizing"
|
||||
* Added option "Clear finished downloads on exit"
|
||||
* Added option "Ask user for confirmation on exit"
|
||||
* Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
|
||||
* Fixed Search window layout on maximizing
|
||||
* Fixed a bug that caused upload limit not to be always applied
|
||||
* Added Bulgarian translation
|
||||
* Updated Translations
|
||||
* Code optimization
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Thu, 22 Jun 2006 20:14:27 +0200
|
||||
|
||||
qbittorrent (0.4.0) edgy; urgency=low
|
||||
|
||||
* Added a search engine (supports Mininova & thepiratebay websites)
|
||||
* Fixed critical bug: some options were not applied correctly to BT session
|
||||
* Possibility to download a torrent file from an URL
|
||||
* Added confirmation dialog on qbittorrent exit
|
||||
* Enabled sorting in Download list
|
||||
* Added Ukrainian translation
|
||||
* Support urls as program parameters
|
||||
* Added more actions to trayicon menu
|
||||
* Fixed exception catching when retrieving fastresume data
|
||||
* use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
|
||||
* Iconification to systray when minimizing
|
||||
* Code Cleanup & optimization
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Wed, 14 Jun 2006 14:47:27 +0200
|
||||
|
||||
qbittorrent (0.3.1) edgy; urgency=low
|
||||
|
||||
* Fixed toolbar layout (spacing).
|
||||
* Added Russian translation.
|
||||
* Resume also finished files on startup (for seeding).
|
||||
* Added colors corresponding to download state.
|
||||
* Fixed a segfault when deleting a download (if no scan dir is set).
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Sat, 6 Jun 2006 21:36:27 +0200
|
||||
|
||||
|
||||
qbittorrent (0.3) edgy; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Christophe Dumez <chris@qbittorrent.org> Sat, 3 Jun 2006 21:57:27 +0200
|
||||
1
packaging/ubuntu-edgy/debian/compat
Normal file
@@ -0,0 +1 @@
|
||||
4
|
||||
15
packaging/ubuntu-edgy/debian/control
Normal file
@@ -0,0 +1,15 @@
|
||||
Source: qbittorrent
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Christophe Dumez <chris@qbittorrent.org>
|
||||
Build-Depends: debhelper (>= 4.0.0), autotools-dev, libqt4-core (>= 4.1.0), libqt4-dev (>= 4.1.0), libqt4-gui (>= 4.1.0), rb-libtorrent (>= 0.10), libcurl3-dev
|
||||
Standards-Version: 3.6.2
|
||||
|
||||
Package: qbittorrent
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, rb-libtorrent (>= 0.10), python (>= 2.3)
|
||||
Description: Bittorrent client in Qt4.1 / C++
|
||||
qBittorrent is a bittorrent client programmed in C++ / Qt4.1
|
||||
using rb_libtorrent by Arvid Norberg. It aims to be a good
|
||||
alternative to other bittorrent client out there. It is fast,
|
||||
stable and provides unicode support.
|
||||
26
packaging/ubuntu-edgy/debian/copyright
Normal file
@@ -0,0 +1,26 @@
|
||||
This is qbittorrent, written and maintained by Christophe Dumez <chris@qbittorrent.org>
|
||||
on Sat, 3 Jun 2006 21:57:27 +0200.
|
||||
|
||||
The original source can always be found at:
|
||||
ftp://ftp.debian.org/dists/unstable/main/source/
|
||||
|
||||
Copyright (C) 2006 Christophe Dumez
|
||||
|
||||
License:
|
||||
|
||||
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 package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License can be found in `/usr/share/common-licenses/GPL'.
|
||||
2
packaging/ubuntu-edgy/debian/dirs
Normal file
@@ -0,0 +1,2 @@
|
||||
usr/bin
|
||||
usr/sbin
|
||||
3
packaging/ubuntu-edgy/debian/docs
Normal file
@@ -0,0 +1,3 @@
|
||||
NEWS
|
||||
README
|
||||
TODO
|
||||
1
packaging/ubuntu-edgy/debian/files
Normal file
@@ -0,0 +1 @@
|
||||
qbittorrent_0.6.1-0ubuntu2_i386.deb net optional
|
||||
1
packaging/ubuntu-edgy/debian/qbittorrent.substvars
Normal file
@@ -0,0 +1 @@
|
||||
shlibs:Depends=libboost-date-time1.33.1, libboost-filesystem1.33.1, libboost-thread1.33.1, libc6 (>= 2.4-1), libcurl3 (>= 7.15.4-1), libgcc1 (>= 1:4.1.1-11ubuntu1), libqt4-core (>= 4.1.4), libqt4-gui (>= 4.1.4), libstdc++6 (>= 4.1.1-11ubuntu1), libx11-6, libxext6, zlib1g (>= 1:1.2.1)
|
||||
107
packaging/ubuntu-edgy/debian/rules
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
|
||||
# These are used for cross-compiling and for saving the configure script
|
||||
# from having to guess our platform (since we know it already)
|
||||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
|
||||
CFLAGS = -Wall
|
||||
|
||||
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
|
||||
CFLAGS += -O0
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
|
||||
config.status: configure
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
CFLAGS="$(CFLAGS) -Wl,-z,defs" ./configure --prefix=/usr
|
||||
|
||||
|
||||
build: build-stamp
|
||||
|
||||
build-stamp: config.status
|
||||
dh_testdir
|
||||
|
||||
# Add here commands to compile the package.
|
||||
$(MAKE)
|
||||
#docbook-to-man debian/qbittorrent.sgml > qbittorrent.1
|
||||
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
-$(MAKE) distclean
|
||||
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
|
||||
cp -f /usr/share/misc/config.sub config.sub
|
||||
endif
|
||||
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
|
||||
cp -f /usr/share/misc/config.guess config.guess
|
||||
endif
|
||||
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/qbittorrent.
|
||||
$(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/qbittorrent
|
||||
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installchangelogs Changelog
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
# dh_install
|
||||
# dh_installmenu
|
||||
# dh_installdebconf
|
||||
# dh_installlogrotate
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installmime
|
||||
# dh_installinit
|
||||
# dh_installcron
|
||||
# dh_installinfo
|
||||
dh_installman
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# dh_perl
|
||||
# dh_python
|
||||
# dh_makeshlibs
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
@@ -94,12 +94,13 @@
|
||||
<includestyle>4</includestyle>
|
||||
<designerintegration>ExternalDesigner</designerintegration>
|
||||
<root>/usr/lib/qt4</root>
|
||||
<qmake>/usr/bin/qmake</qmake>
|
||||
<designer>/usr/bin/designer</designer>
|
||||
<qmake>/usr/bin/qmake-qt4</qmake>
|
||||
<designer>/usr/bin/designer-qt4</designer>
|
||||
<designerpluginpaths/>
|
||||
</qt>
|
||||
<references>
|
||||
<pcs>automatic_%2Fhome%2Fishanarora%2Fprojects%2Fqbittorrent</pcs>
|
||||
<pcs>automatic_%2Fhome%2Fchris%2Fqbittorrent_svn%2Ftrunk</pcs>
|
||||
<pcs>Qt4</pcs>
|
||||
</references>
|
||||
<codecompletion>
|
||||
<automaticCodeCompletion>true</automaticCodeCompletion>
|
||||
@@ -148,14 +149,14 @@
|
||||
</kdevfilecreate>
|
||||
<kdevtrollproject>
|
||||
<general>
|
||||
<activedir>src</activedir>
|
||||
<activedir></activedir>
|
||||
</general>
|
||||
<run>
|
||||
<directoryradio>executable</directoryradio>
|
||||
<mainprogram>/home/ishanarora/projects/qbittorrent/src/qbittorrent</mainprogram>
|
||||
<mainprogram>/home/chris/qbittorrent_svn/trunk/src/qbittorrent</mainprogram>
|
||||
<programargs/>
|
||||
<globaldebugarguments/>
|
||||
<globalcwd>/home/ishanarora/projects/qbittorrent</globalcwd>
|
||||
<globalcwd>/home/chris/qbittorrent_svn/trunk</globalcwd>
|
||||
<useglobalprogram>true</useglobalprogram>
|
||||
<terminal>false</terminal>
|
||||
<autocompile>true</autocompile>
|
||||
@@ -186,7 +187,7 @@
|
||||
</cppsupportpart>
|
||||
<ctagspart>
|
||||
<customArguments/>
|
||||
<customTagfilePath>/home/ishanarora/projects/qbittorrent/tags</customTagfilePath>
|
||||
<customTagfilePath>/home/chris/qbittorrent_svn/trunk/tags</customTagfilePath>
|
||||
<activeTagsFiles/>
|
||||
</ctagspart>
|
||||
<kdevdocumentation>
|
||||
|
||||
@@ -6,14 +6,18 @@
|
||||
<dep type='qt4'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libtorrent-rasterbar'>
|
||||
<dep type='libtorrent'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libboost'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libcurl'>
|
||||
<dep type='libcommoncpp2'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libmagick'/>
|
||||
<dep type='libzzip'/>
|
||||
<dep type='python'>
|
||||
<required/>
|
||||
</dep>
|
||||
</qconf>
|
||||
|
||||
@@ -37,17 +37,15 @@ public:
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!QFile::exists(s+QString("/libccext2.so")))
|
||||
if(!QFile::exists(s+QString("libccext2.so")))
|
||||
return false;
|
||||
if(!QFile::exists(s+QString("/libccgnu2.so")))
|
||||
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"))){
|
||||
@@ -60,6 +58,16 @@ public:
|
||||
if(!found) return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}
|
||||
// BUGFIX for Fedora (doesn't support pkg-config?)
|
||||
QFile issue_file("/etc/issue");
|
||||
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||
QString content = issue_file.readAll();
|
||||
issue_file.close();
|
||||
if(content.indexOf("Fedora") != -1){
|
||||
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
|
||||
conf->addLib("-pthread -lccext2 -lz -lccgnu2 -ldl -lrt");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libcommoncpp2
|
||||
arg: with-libcurl-inc=[path], Path to libcurl include files
|
||||
arg: with-libcurl-lib=[path], Path to libcurl library files
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_libcurl : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libcurl(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libcurl"; }
|
||||
QString shortname() const { return "libcurl"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "curl/curl.h")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/include";
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "curl/curl.h")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
conf->addIncludePath(s);
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!QFile::exists(s+QString("/libcurl.so")))
|
||||
return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
sl << "/usr/lib64/";
|
||||
sl << "/usr/local/lib/";
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(QFile::exists(s+QString("libcurl.so"))){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -44,20 +44,18 @@ public:
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkLibrary(s, "Magick++")) {
|
||||
return false;
|
||||
}
|
||||
if(!QFile::exists(s+QString("libMagick++.so"))){
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
sl << "/usr/lib64/";
|
||||
sl << "/usr/local/lib/";
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkLibrary(s, "Magick++")) {
|
||||
if(QFile::exists(s+QString("libMagick++.so"))){
|
||||
found = true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
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-----
|
||||
*/
|
||||
class qc_libtorrent_rasterbar : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
|
||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/include";
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "libtorrent/magnet_uri.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;
|
||||
}
|
||||
};
|
||||
78
qcm/libtorrent.qcm
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libtorrent
|
||||
arg: with-libtorrent-inc=[path], Path to libtorrent include files
|
||||
arg: with-libtorrent-lib=[path], Path to libtorrent library files
|
||||
arg: with-libtorrent-static-lib=[path], Path to libtorrent .a file
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_libtorrent : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libtorrent(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "libtorrent >= 0.13"; }
|
||||
QString shortname() const { return "libtorrent"; }
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/include";
|
||||
sl << "/usr/local/include";
|
||||
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")) {
|
||||
return false;
|
||||
}
|
||||
conf->addLib(QString("-L") + s);
|
||||
}else{
|
||||
QStringList sl;
|
||||
sl << "/usr/lib/";
|
||||
sl << "/usr/local/lib/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkLibrary(s, "torrent")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}
|
||||
// BUGFIX for Fedora (doesn't support pkg-config?)
|
||||
QFile issue_file("/etc/issue");
|
||||
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||
QString content = issue_file.readAll();
|
||||
issue_file.close();
|
||||
if(content.indexOf("Fedora") != -1){
|
||||
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
|
||||
conf->addLib("-lssl -lcrypto -lboost_date_time -lboost_filesystem -lboost_thread -lz -ltorrent");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -44,15 +44,13 @@ public:
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!QFile::exists(s+QString("/libzzip.so"))){
|
||||
if(!QFile::exists(s+QString("libzzip.so"))){
|
||||
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(QFile::exists(s+QString("libzzip.so"))){
|
||||
|
||||
19
qcm/python.qcm
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: python
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_python : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_python(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "python >= 2.3"; }
|
||||
QString shortname() const { return "python"; }
|
||||
bool exec(){
|
||||
int r = conf->doCommand("python testpython.py");
|
||||
if(r == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -11,10 +11,6 @@ public:
|
||||
QString shortname() const { return "Qt 4.3"; }
|
||||
bool exec()
|
||||
{
|
||||
if(QT_VERSION >= 0x040400) {
|
||||
conf->addDefine("QT_4_4");
|
||||
}
|
||||
return(QT_VERSION >= 0x040300);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,8 +40,7 @@
|
||||
#define SEEDSLEECH 5
|
||||
#define RATIO 6
|
||||
#define ETA 7
|
||||
#define PRIORITY 8
|
||||
#define HASH 9
|
||||
#define HASH 8
|
||||
|
||||
class DLListDelegate: public QItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -34,10 +34,11 @@
|
||||
// Defines for download list list columns
|
||||
#define F_NAME 0
|
||||
#define F_SIZE 1
|
||||
#define F_UPSPEED 2
|
||||
#define F_LEECH 3
|
||||
#define F_RATIO 4
|
||||
#define F_HASH 5
|
||||
#define F_PROGRESS 2
|
||||
#define F_UPSPEED 3
|
||||
#define F_SEEDSLEECH 4
|
||||
#define F_RATIO 5
|
||||
#define F_HASH 6
|
||||
|
||||
class FinishedListDelegate: public QItemDelegate {
|
||||
Q_OBJECT
|
||||
@@ -66,6 +67,20 @@ class FinishedListDelegate: public QItemDelegate {
|
||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||
break;
|
||||
}
|
||||
case F_PROGRESS:{
|
||||
QStyleOptionProgressBarV2 newopt;
|
||||
double progress = index.data().toDouble()*100.;
|
||||
newopt.rect = opt.rect;
|
||||
newopt.text = QString(QByteArray::number(progress, 'f', 1))+QString::fromUtf8("%");
|
||||
newopt.progress = (int)progress;
|
||||
newopt.maximum = 100;
|
||||
newopt.minimum = 0;
|
||||
newopt.state |= QStyle::State_Enabled;
|
||||
newopt.textVisible = true;
|
||||
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt,
|
||||
painter);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
QItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
@@ -31,21 +31,21 @@
|
||||
#include <QStandardItemModel>
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
|
||||
FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbFinished(0){
|
||||
setupUi(this);
|
||||
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
|
||||
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
|
||||
finishedListModel = new QStandardItemModel(0,6);
|
||||
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_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
|
||||
finishedListModel->setHeaderData(F_PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded"));
|
||||
finishedListModel->setHeaderData(F_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed"));
|
||||
finishedListModel->setHeaderData(F_LEECH, Qt::Horizontal, tr("Leechers", "i.e: full/partial sources"));
|
||||
finishedListModel->setHeaderData(F_SEEDSLEECH, Qt::Horizontal, tr("Seeds/Leechs", "i.e: full/partial sources"));
|
||||
finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio"));
|
||||
finishedList->setModel(finishedListModel);
|
||||
loadHiddenColumns();
|
||||
// Hide hash column
|
||||
// Hide ETA & hash column
|
||||
finishedList->hideColumn(F_HASH);
|
||||
// Load last columns width for download list
|
||||
if(!loadColWidthFinishedList()){
|
||||
@@ -54,12 +54,10 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
|
||||
// Make download list header clickable for sorting
|
||||
finishedList->header()->setClickable(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);
|
||||
finishedList->setItemDelegate(finishedListDelegate);
|
||||
connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&)));
|
||||
finishedList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(finishedList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedHoSMenu(const QPoint&)));
|
||||
connect(finishedList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
|
||||
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
|
||||
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
|
||||
@@ -71,21 +69,11 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
|
||||
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_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(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
|
||||
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
|
||||
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
|
||||
connect(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
|
||||
|
||||
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
|
||||
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
|
||||
connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed()));
|
||||
connect(actionHOSColLeechers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnLeechers()));
|
||||
connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio()));
|
||||
}
|
||||
|
||||
FinishedTorrents::~FinishedTorrents(){
|
||||
saveColWidthFinishedList();
|
||||
saveHiddenColumns();
|
||||
delete finishedListDelegate;
|
||||
delete finishedListModel;
|
||||
}
|
||||
@@ -93,10 +81,13 @@ FinishedTorrents::~FinishedTorrents(){
|
||||
void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
|
||||
unsigned int row = index.row();
|
||||
QString hash = getHashFromRow(row);
|
||||
emit torrentDoubleClicked(hash, true);
|
||||
emit torrentDoubleClicked(hash);
|
||||
}
|
||||
|
||||
void FinishedTorrents::addTorrent(QString hash){
|
||||
if(!BTSession->isFinished(hash)){
|
||||
BTSession->setFinishedTorrent(hash);
|
||||
}
|
||||
int row = getRowFromHash(hash);
|
||||
if(row != -1) return;
|
||||
row = finishedListModel->rowCount();
|
||||
@@ -106,9 +97,10 @@ void FinishedTorrents::addTorrent(QString hash){
|
||||
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_UPSPEED), QVariant((double)0.));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant("0"));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant("0/0"));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString::fromUtf8(misc::toString(BTSession->getRealRatio(hash)).c_str())));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.));
|
||||
if(h.is_paused()) {
|
||||
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
|
||||
setRowColor(row, "red");
|
||||
@@ -119,8 +111,13 @@ void FinishedTorrents::addTorrent(QString hash){
|
||||
// Update the number of finished torrents
|
||||
++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
|
||||
@@ -159,60 +156,27 @@ bool FinishedTorrents::loadColWidthFinishedList(){
|
||||
if(line.isEmpty())
|
||||
return false;
|
||||
QStringList width_list = line.split(' ');
|
||||
if(width_list.size() < finishedListModel->columnCount()-1)
|
||||
if(width_list.size() != finishedListModel->columnCount()-1)
|
||||
return false;
|
||||
unsigned int listSize = width_list.size();
|
||||
for(unsigned int i=0; i<listSize; ++i){
|
||||
finishedList->header()->resizeSection(i, width_list.at(i).toInt());
|
||||
}
|
||||
loadLastSortedColumn();
|
||||
qDebug("Finished list columns width loaded");
|
||||
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
|
||||
// (finished list)
|
||||
void FinishedTorrents::saveColWidthFinishedList() const{
|
||||
qDebug("Saving columns width in finished list");
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
QStringList width_list;
|
||||
QStringList new_width_list;
|
||||
short nbColumns = finishedListModel->columnCount()-1;
|
||||
|
||||
QString line = settings.value("FinishedListColsWidth", QString()).toString();
|
||||
if(!line.isEmpty()) {
|
||||
width_list = line.split(' ');
|
||||
unsigned int nbColumns = finishedListModel->columnCount()-1;
|
||||
for(unsigned int i=0; i<nbColumns; ++i){
|
||||
width_list << QString::fromUtf8(misc::toString(finishedList->columnWidth(i)).c_str());
|
||||
}
|
||||
for(short i=0; i<nbColumns; ++i){
|
||||
if(finishedList->columnWidth(i)<1 && width_list.size() == finishedListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
|
||||
// load the former width
|
||||
new_width_list << width_list.at(i);
|
||||
} else if(finishedList->columnWidth(i)>=1) {
|
||||
// usual case, save the current width
|
||||
new_width_list << QString::fromUtf8(misc::toString(finishedList->columnWidth(i)).c_str());
|
||||
} else {
|
||||
// default width
|
||||
finishedList->resizeColumnToContents(i);
|
||||
new_width_list << QString::fromUtf8(misc::toString(finishedList->columnWidth(i)).c_str());
|
||||
}
|
||||
}
|
||||
settings.setValue("FinishedListColsWidth", new_width_list.join(" "));
|
||||
settings.setValue("FinishedListColsWidth", width_list.join(" "));
|
||||
qDebug("Finished list columns width saved");
|
||||
}
|
||||
|
||||
@@ -229,8 +193,15 @@ void FinishedTorrents::on_actionSet_upload_limit_triggered(){
|
||||
new BandwidthAllocationDialog(this, true, BTSession, hashes);
|
||||
}
|
||||
|
||||
void FinishedTorrents::updateTorrent(QTorrentHandle h) {
|
||||
QString hash = h.hash();
|
||||
void FinishedTorrents::updateFinishedList(){
|
||||
QString 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);
|
||||
if(row == -1){
|
||||
qDebug("Cannot find torrent in finished list, adding it");
|
||||
@@ -238,36 +209,32 @@ void FinishedTorrents::updateTorrent(QTorrentHandle h) {
|
||||
row = getRowFromHash(hash);
|
||||
}
|
||||
Q_ASSERT(row != -1);
|
||||
if(h.is_paused()) return;
|
||||
// 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/time.png"))), Qt::DecorationRole);
|
||||
} else {
|
||||
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_LEECH), "0");
|
||||
setRowColor(row, QString::fromUtf8("grey"));
|
||||
return;
|
||||
if(h.is_paused()) continue;
|
||||
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
|
||||
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)h.progress()));
|
||||
continue;
|
||||
}
|
||||
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
|
||||
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!
|
||||
qDebug("Info: a torrent was moved from finished to download tab");
|
||||
deleteTorrent(hash);
|
||||
BTSession->setFinishedTorrent(hash);
|
||||
emit torrentMovedFromFinishedList(hash);
|
||||
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"));
|
||||
return;
|
||||
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)h.progress()));
|
||||
continue;
|
||||
}
|
||||
setRowColor(row, QString::fromUtf8("orange"));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
|
||||
if(!finishedList->isColumnHidden(F_UPSPEED)) {
|
||||
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
|
||||
}
|
||||
if(!finishedList->isColumnHidden(F_LEECH)) {
|
||||
finishedListModel->setData(finishedListModel->index(row, F_LEECH), misc::toQString(h.num_peers() - h.num_seeds(), true));
|
||||
}
|
||||
if(!finishedList->isColumnHidden(F_RATIO)) {
|
||||
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
|
||||
}
|
||||
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+"/"+misc::toQString(h.num_peers() - h.num_seeds(), true)));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.));
|
||||
}
|
||||
}
|
||||
|
||||
int FinishedTorrents::getRowFromHash(QString hash) const{
|
||||
@@ -283,14 +250,20 @@ int FinishedTorrents::getRowFromHash(QString hash) const{
|
||||
// Note: does not actually pause the torrent in BT Session
|
||||
void FinishedTorrents::pauseTorrent(QString hash) {
|
||||
int row = getRowFromHash(hash);
|
||||
if(row == -1)
|
||||
return;
|
||||
Q_ASSERT(row != -1);
|
||||
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_LEECH), QVariant(QString::fromUtf8("0")));
|
||||
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
|
||||
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 {
|
||||
Q_ASSERT(row < (unsigned int)finishedListModel->rowCount());
|
||||
return finishedListModel->data(finishedListModel->index(row, F_HASH)).toString();
|
||||
@@ -310,14 +283,11 @@ void FinishedTorrents::deleteTorrent(QString hash){
|
||||
|
||||
// Show torrent properties dialog
|
||||
void FinishedTorrents::showProperties(const QModelIndex &index){
|
||||
showPropertiesFromHash(finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString());
|
||||
}
|
||||
|
||||
void FinishedTorrents::showPropertiesFromHash(QString hash){
|
||||
int row = index.row();
|
||||
QString hash = finishedListModel->data(finishedListModel->index(row, F_HASH)).toString();
|
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||
properties *prop = new properties(this, BTSession, h);
|
||||
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSize(QString)));
|
||||
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
|
||||
prop->show();
|
||||
}
|
||||
|
||||
@@ -338,23 +308,13 @@ void FinishedTorrents::propertiesSelection(){
|
||||
}
|
||||
}
|
||||
|
||||
void FinishedTorrents::forceRecheck(){
|
||||
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||
QModelIndex index;
|
||||
foreach(index, selectedIndexes){
|
||||
if(index.column() == F_NAME){
|
||||
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
|
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||
h.force_recheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
|
||||
QMenu myFinishedListMenu(this);
|
||||
QModelIndex index;
|
||||
// Enable/disable pause/start action given the DL state
|
||||
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
QString previewProgram = settings.value("Preferences/general/MediaPlayer", QString()).toString();
|
||||
bool has_pause = false, has_start = false, has_preview = false;
|
||||
foreach(index, selectedIndexes) {
|
||||
if(index.column() == F_NAME) {
|
||||
@@ -374,7 +334,7 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
|
||||
has_pause = true;
|
||||
}
|
||||
}
|
||||
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
myFinishedListMenu.addAction(actionPreview_file);
|
||||
has_preview = true;
|
||||
}
|
||||
@@ -387,190 +347,30 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
|
||||
myFinishedListMenu.addSeparator();
|
||||
myFinishedListMenu.addAction(actionSet_upload_limit);
|
||||
myFinishedListMenu.addSeparator();
|
||||
myFinishedListMenu.addAction(actionForce_recheck);
|
||||
myFinishedListMenu.addSeparator();
|
||||
myFinishedListMenu.addAction(actionOpen_destination_folder);
|
||||
myFinishedListMenu.addAction(actionTorrent_Properties);
|
||||
myFinishedListMenu.addSeparator();
|
||||
myFinishedListMenu.addAction(actionBuy_it);
|
||||
|
||||
// Call menu
|
||||
// XXX: why mapToGlobal() is not enough?
|
||||
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,58));
|
||||
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,55));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hiding Columns functions
|
||||
*/
|
||||
|
||||
// hide/show columns menu
|
||||
void FinishedTorrents::displayFinishedHoSMenu(const QPoint& pos){
|
||||
QMenu hideshowColumn(this);
|
||||
hideshowColumn.setTitle(tr("Hide or Show Column"));
|
||||
int lastCol = F_RATIO;
|
||||
for(int i=0; i<=lastCol; i++) {
|
||||
hideshowColumn.addAction(getActionHoSCol(i));
|
||||
}
|
||||
// Call menu
|
||||
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,34));
|
||||
}
|
||||
|
||||
// toggle hide/show a column
|
||||
void FinishedTorrents::hideOrShowColumn(int index) {
|
||||
unsigned int nbVisibleColumns = 0;
|
||||
unsigned int nbCols = finishedListModel->columnCount();
|
||||
// Count visible columns
|
||||
for(unsigned int i=0; i<nbCols; ++i) {
|
||||
if(!finishedList->isColumnHidden(i))
|
||||
++nbVisibleColumns;
|
||||
}
|
||||
if(!finishedList->isColumnHidden(index)) {
|
||||
// User wants to hide the column
|
||||
// Is there at least one other visible column?
|
||||
if(nbVisibleColumns <= 1) return;
|
||||
// User can hide the column, do it.
|
||||
finishedList->setColumnHidden(index, true);
|
||||
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
|
||||
--nbVisibleColumns;
|
||||
} else {
|
||||
// User want to display the column
|
||||
finishedList->setColumnHidden(index, false);
|
||||
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
|
||||
++nbVisibleColumns;
|
||||
}
|
||||
//resize all others non-hidden columns
|
||||
for(unsigned int i=0; i<nbCols; ++i) {
|
||||
if(!finishedList->isColumnHidden(i)) {
|
||||
finishedList->setColumnWidth(i, (int)ceil(finishedList->columnWidth(i)+(finishedList->columnWidth(index)/nbVisibleColumns)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FinishedTorrents::hideOrShowColumnName() {
|
||||
hideOrShowColumn(F_NAME);
|
||||
}
|
||||
|
||||
void FinishedTorrents::hideOrShowColumnSize() {
|
||||
hideOrShowColumn(F_SIZE);
|
||||
}
|
||||
|
||||
void FinishedTorrents::hideOrShowColumnUpSpeed() {
|
||||
hideOrShowColumn(F_UPSPEED);
|
||||
}
|
||||
|
||||
void FinishedTorrents::hideOrShowColumnLeechers() {
|
||||
hideOrShowColumn(F_LEECH);
|
||||
}
|
||||
|
||||
void FinishedTorrents::hideOrShowColumnRatio() {
|
||||
hideOrShowColumn(F_RATIO);
|
||||
}
|
||||
|
||||
// load the previous settings, and hide the columns
|
||||
bool FinishedTorrents::loadHiddenColumns() {
|
||||
bool loaded = false;
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
QString line = settings.value("FinishedListColsHoS", QString()).toString();
|
||||
QStringList ishidden_list;
|
||||
if(!line.isEmpty()) {
|
||||
ishidden_list = line.split(' ');
|
||||
if(ishidden_list.size() == finishedListModel->columnCount()-1) {
|
||||
unsigned int listSize = ishidden_list.size();
|
||||
for(unsigned int i=0; i<listSize; ++i){
|
||||
finishedList->header()->resizeSection(i, ishidden_list.at(i).toInt());
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
for(int i=0; i<finishedListModel->columnCount()-1; i++) {
|
||||
if(loaded && ishidden_list.at(i) == "0") {
|
||||
finishedList->setColumnHidden(i, true);
|
||||
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
|
||||
} else {
|
||||
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
|
||||
}
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
// save the hidden columns in settings
|
||||
void FinishedTorrents::saveHiddenColumns() {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
QStringList ishidden_list;
|
||||
short nbColumns = finishedListModel->columnCount()-1;
|
||||
|
||||
for(short i=0; i<nbColumns; ++i){
|
||||
if(finishedList->isColumnHidden(i)) {
|
||||
ishidden_list << QString::fromUtf8(misc::toString(0).c_str());
|
||||
} else {
|
||||
ishidden_list << QString::fromUtf8(misc::toString(1).c_str());
|
||||
}
|
||||
}
|
||||
settings.setValue("FinishedListColsHoS", ishidden_list.join(" "));
|
||||
}
|
||||
|
||||
// getter, return the action hide or show whose id is index
|
||||
QAction* FinishedTorrents::getActionHoSCol(int index) {
|
||||
switch(index) {
|
||||
case F_NAME :
|
||||
return actionHOSColName;
|
||||
break;
|
||||
case F_SIZE :
|
||||
return actionHOSColSize;
|
||||
break;
|
||||
case F_UPSPEED :
|
||||
return actionHOSColUpSpeed;
|
||||
break;
|
||||
case F_LEECH :
|
||||
return actionHOSColLeechers;
|
||||
break;
|
||||
case F_RATIO :
|
||||
return actionHOSColRatio;
|
||||
break;
|
||||
default :
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sorting functions
|
||||
*/
|
||||
|
||||
void FinishedTorrents::toggleFinishedListSortOrder(int index) {
|
||||
Qt::SortOrder sortOrder = Qt::AscendingOrder;
|
||||
void FinishedTorrents::sortFinishedList(int index){
|
||||
static Qt::SortOrder sortOrder = Qt::AscendingOrder;
|
||||
if(finishedList->header()->sortIndicatorSection() == index){
|
||||
sortOrder = (Qt::SortOrder)!(bool)finishedList->header()->sortIndicatorOrder();
|
||||
if(sortOrder == Qt::AscendingOrder){
|
||||
sortOrder = Qt::DescendingOrder;
|
||||
}else{
|
||||
sortOrder = Qt::AscendingOrder;
|
||||
}
|
||||
}
|
||||
switch(index) {
|
||||
case F_SIZE:
|
||||
case F_UPSPEED:
|
||||
case F_RATIO:
|
||||
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 {
|
||||
finishedList->header()->setSortIndicator(index, sortOrder);
|
||||
}
|
||||
switch(index) {
|
||||
finishedList->header()->setSortIndicator(index, sortOrder);
|
||||
switch(index){
|
||||
case F_SIZE:
|
||||
case F_UPSPEED:
|
||||
case F_PROGRESS:
|
||||
sortFinishedListFloat(index, sortOrder);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -39,10 +39,6 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
||||
FinishedListDelegate *finishedListDelegate;
|
||||
QStandardItemModel *finishedListModel;
|
||||
unsigned int nbFinished;
|
||||
void hideOrShowColumn(int index);
|
||||
bool loadHiddenColumns();
|
||||
void saveHiddenColumns();
|
||||
QAction* getActionHoSCol(int index);
|
||||
|
||||
public:
|
||||
FinishedTorrents(QObject *parent, bittorrent *BTSession);
|
||||
@@ -57,35 +53,27 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
||||
protected slots:
|
||||
void showProperties(const QModelIndex &index);
|
||||
void displayFinishedListMenu(const QPoint&);
|
||||
void displayFinishedHoSMenu(const QPoint&);
|
||||
void setRowColor(int row, QString color);
|
||||
void saveColWidthFinishedList() const;
|
||||
void toggleFinishedListSortOrder(int index);
|
||||
void sortFinishedList(int index=-1, Qt::SortOrder sortOrder=Qt::AscendingOrder);
|
||||
void sortFinishedList(int index);
|
||||
void sortFinishedListFloat(int index, Qt::SortOrder sortOrder);
|
||||
void sortFinishedListString(int index, Qt::SortOrder sortOrder);
|
||||
void updateFileSize(QString hash);
|
||||
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume);
|
||||
void on_actionSet_upload_limit_triggered();
|
||||
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
||||
void hideOrShowColumnName();
|
||||
void hideOrShowColumnSize();
|
||||
void hideOrShowColumnUpSpeed();
|
||||
void hideOrShowColumnLeechers();
|
||||
void hideOrShowColumnRatio();
|
||||
void forceRecheck();
|
||||
|
||||
public slots:
|
||||
void addTorrent(QString hash);
|
||||
void updateTorrent(QTorrentHandle h);
|
||||
void updateFinishedList();
|
||||
void pauseTorrent(QString hash);
|
||||
void resumeTorrent(QString hash);
|
||||
void propertiesSelection();
|
||||
void deleteTorrent(QString hash);
|
||||
void showPropertiesFromHash(QString hash);
|
||||
void loadLastSortedColumn();
|
||||
|
||||
signals:
|
||||
void torrentMovedFromFinishedList(QString);
|
||||
void torrentDoubleClicked(QString hash, bool finished);
|
||||
void torrentDoubleClicked(QString hash);
|
||||
void finishedTorrentsNumberChanged(unsigned int);
|
||||
|
||||
};
|
||||
|
||||
998
src/GUI.cpp
65
src/GUI.h
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <QProcess>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QPointer>
|
||||
|
||||
#include "ui_MainWindow.h"
|
||||
#include "qtorrenthandle.h"
|
||||
|
||||
@@ -35,13 +35,8 @@ class DownloadingTorrents;
|
||||
class FinishedTorrents;
|
||||
class downloadFromURL;
|
||||
class SearchEngine;
|
||||
#ifdef QT_4_4
|
||||
class QLocalServer;
|
||||
class QLocalSocket;
|
||||
#else
|
||||
class QTcpServer;
|
||||
class QTcpSocket;
|
||||
#endif
|
||||
class QTcpServer;
|
||||
class QTcpSocket;
|
||||
class QCloseEvent;
|
||||
class RSSImp;
|
||||
class QShortcut;
|
||||
@@ -51,8 +46,6 @@ class options_imp;
|
||||
class QTabWidget;
|
||||
class QLabel;
|
||||
class QModelIndex;
|
||||
class HttpServer;
|
||||
class QFrame;
|
||||
|
||||
class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
Q_OBJECT
|
||||
@@ -64,9 +57,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers;
|
||||
// GUI related
|
||||
QTabWidget *tabs;
|
||||
QPointer<options_imp> options;
|
||||
options_imp *options;
|
||||
QSystemTrayIcon *myTrayIcon;
|
||||
QPointer<QTimer> systrayCreator;
|
||||
QMenu *myTrayIconMenu;
|
||||
DownloadingTorrents *downloadingTorrentTab;
|
||||
FinishedTorrents *finishedTorrentTab;
|
||||
@@ -76,36 +68,21 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
bool force_exit;
|
||||
unsigned int refreshInterval;
|
||||
QTimer *refresher;
|
||||
QLabel *dlSpeedLbl;
|
||||
QLabel *upSpeedLbl;
|
||||
QLabel *ratioLbl;
|
||||
QLabel *DHTLbl;
|
||||
QFrame *statusSep1;
|
||||
QFrame *statusSep2;
|
||||
QFrame *statusSep3;
|
||||
QFrame *statusSep4;
|
||||
// Keyboard shortcuts
|
||||
QShortcut *switchSearchShortcut;
|
||||
QShortcut *switchSearchShortcut2;
|
||||
QShortcut *switchDownShortcut;
|
||||
QShortcut *switchUpShortcut;
|
||||
QShortcut *switchRSSShortcut;
|
||||
QAction *prioSeparator;
|
||||
QAction *prioSeparator2;
|
||||
// Preview
|
||||
QProcess *previewProcess;
|
||||
// Search
|
||||
SearchEngine *searchEngine;
|
||||
// RSS
|
||||
RSSImp *rssWidget;
|
||||
// Web UI
|
||||
QPointer<HttpServer> httpServer;
|
||||
// Misc
|
||||
#ifdef QT_4_4
|
||||
QLocalServer *localServer;
|
||||
QLocalSocket *clientConnection;
|
||||
#else
|
||||
QTcpServer *localServer;
|
||||
QTcpServer *tcpServer;
|
||||
QTcpSocket *clientConnection;
|
||||
#endif
|
||||
|
||||
protected slots:
|
||||
// GUI related slots
|
||||
@@ -116,13 +93,12 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
void on_actionCreate_torrent_triggered();
|
||||
void on_actionWebsite_triggered() const;
|
||||
void on_actionBugReport_triggered() const;
|
||||
void on_actionShow_console_triggered();
|
||||
void readParamsOnSocket();
|
||||
void acceptConnection();
|
||||
void togglePausedState(QString hash);
|
||||
void torrentDoubleClicked(QString hash, bool finished);
|
||||
void on_actionPreview_file_triggered();
|
||||
void previewFile(QString filePath);
|
||||
void cleanTempPreviewFile(int, QProcess::ExitStatus) const;
|
||||
void balloonClicked();
|
||||
void writeSettings();
|
||||
void readSettings();
|
||||
@@ -132,7 +108,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
void updateFinishedTorrentNumber(unsigned int nb);
|
||||
void fullDiskError(QTorrentHandle& h) const;
|
||||
void handleDownloadFromUrlFailure(QString, QString) const;
|
||||
void createSystrayDelayed();
|
||||
// Keyboard shortcuts
|
||||
void createKeyboardShortcuts();
|
||||
void displayDownTab() const;
|
||||
@@ -156,21 +131,16 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
void processParams(const QStringList& params);
|
||||
void addTorrent(QString path);
|
||||
void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker);
|
||||
void processScannedFiles(const QStringList& params);
|
||||
void processDownloadedFiles(QString path, QString url);
|
||||
void downloadFromURLList(const QStringList& urls);
|
||||
void deleteTorrent(QString hash);
|
||||
void deleteTorrent(QString hash, QString fileName, bool finished);
|
||||
void finishedTorrent(QTorrentHandle& h) const;
|
||||
void addedTorrent(QTorrentHandle& h) const;
|
||||
void checkedTorrent(QTorrentHandle& h) const;
|
||||
void pausedTorrent(QTorrentHandle& h) const;
|
||||
void resumedTorrent(QTorrentHandle& h) const;
|
||||
void updateLists(bool force=false);
|
||||
bool initWebUi(QString username, QString password, int port);
|
||||
void on_actionIncreasePriority_triggered();
|
||||
void on_actionDecreasePriority_triggered();
|
||||
void torrentChecked(QString hash) const;
|
||||
void updateLists();
|
||||
// Options slots
|
||||
void on_actionOptions_triggered();
|
||||
void OptionsSaved(bool deleteOptions);
|
||||
void OptionsSaved(QString info, bool deleteOptions);
|
||||
// HTTP slots
|
||||
void on_actionDownload_from_URL_triggered();
|
||||
|
||||
@@ -178,22 +148,17 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
public slots:
|
||||
void trackerAuthenticationRequired(QTorrentHandle& h);
|
||||
void setTabText(int index, QString text) const;
|
||||
void openDestinationFolder() const;
|
||||
void goBuyPage() const;
|
||||
void updateRatio();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
void showEvent(QShowEvent *);
|
||||
bool event(QEvent * event);
|
||||
void displayRSSTab(bool enable);
|
||||
void hideEvent(QHideEvent *);
|
||||
|
||||
public:
|
||||
// Construct / Destruct
|
||||
GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList());
|
||||
~GUI();
|
||||
// Methods
|
||||
int getCurrentTabIndex() const;
|
||||
unsigned int getCurrentTabIndex() const;
|
||||
QPoint screenCenter() const;
|
||||
};
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 575 B |
|
Before Width: | Height: | Size: 455 B |
|
Before Width: | Height: | Size: 333 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 813 B |
@@ -1,14 +1,14 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P
|
||||
Comment=V1.3.0
|
||||
Exec=qbittorrent %f
|
||||
Categories=Qt;Application;Network;P2P
|
||||
Comment=V1.0.0
|
||||
Encoding=UTF-8
|
||||
Exec=qbittorrent
|
||||
GenericName=Bittorrent client
|
||||
GenericName[bg]=Торент клиент
|
||||
GenericName[de]=Bittorren Client
|
||||
GenericName[el]=Τορεντ πελάτης
|
||||
GenericName[es]=Cliente Bittorrent
|
||||
GenericName[fr]=Client Bittorrent
|
||||
GenericName[it]=Client Bittorrent
|
||||
GenericName[ja]=Bittorrent クライアント
|
||||
GenericName[ko]=비토렌트 클라이언트
|
||||
GenericName[nl]=Bittorrent client
|
||||
@@ -19,7 +19,7 @@ GenericName[tr]=Bittorrent istemcisi
|
||||
GenericName[uk]=Bittorrent-клієнт
|
||||
GenericName[zh]=Bittorrent之用户
|
||||
Icon=qbittorrent
|
||||
MimeType=application/x-bittorrent;
|
||||
MimeType=application/x-bittorrent
|
||||
Name=qBittorrent
|
||||
Name[ko]=큐비토런트
|
||||
Terminal=false
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.3 KiB |
BIN
src/Icons/skin/connecting.png
Normal file
|
After Width: | Height: | Size: 576 B |
|
Before Width: | Height: | Size: 5.1 KiB |
BIN
src/Icons/skin/disconnected.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 493 B |
|
Before Width: | Height: | Size: 2.0 KiB |
BIN
src/Icons/smile.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 68 KiB |
BIN
src/Icons/stare.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/Icons/unhappy.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
@@ -5,7 +5,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>914</width>
|
||||
<width>849</width>
|
||||
<height>563</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -16,15 +16,22 @@
|
||||
<string/>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget" >
|
||||
<layout class="QVBoxLayout" />
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>914</width>
|
||||
<height>26</height>
|
||||
<width>849</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_Edit" >
|
||||
@@ -41,8 +48,6 @@
|
||||
<addaction name="separator" />
|
||||
<addaction name="actionDelete" />
|
||||
<addaction name="actionDelete_Permanently" />
|
||||
<addaction name="actionDecreasePriority" />
|
||||
<addaction name="actionIncreasePriority" />
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Help" >
|
||||
<property name="title" >
|
||||
@@ -58,7 +63,6 @@
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<addaction name="actionOptions" />
|
||||
<addaction name="actionShow_console" />
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_File" >
|
||||
<property name="title" >
|
||||
@@ -93,11 +97,8 @@
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="floatable" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="toolBarArea" >
|
||||
<enum>TopToolBarArea</enum>
|
||||
<number>4</number>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak" >
|
||||
<bool>false</bool>
|
||||
@@ -117,13 +118,9 @@
|
||||
<addaction name="actionPause_All" />
|
||||
<addaction name="separator" />
|
||||
<addaction name="actionOptions" />
|
||||
<addaction name="actionDecreasePriority" />
|
||||
<addaction name="actionIncreasePriority" />
|
||||
<addaction name="separator" />
|
||||
<addaction name="actionExit" />
|
||||
<addaction name="separator" />
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar" />
|
||||
<action name="actionOpen" >
|
||||
<property name="text" >
|
||||
<string>Open</string>
|
||||
@@ -234,39 +231,7 @@
|
||||
<string>Set global upload limit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDecreasePriority" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >:/Icons/skin/decrease.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Decrease priority</string>
|
||||
</property>
|
||||
<property name="visible" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionIncreasePriority" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >:/Icons/skin/increase.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Increase priority</string>
|
||||
</property>
|
||||
<property name="visible" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShow_console" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >:/Icons/log.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Console</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="icons.qrc" />
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -174,16 +174,14 @@ class PropListDelegate: public QItemDelegate {
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// if(old_val != NORMAL){
|
||||
// model->setData(index, QVariant(NORMAL));
|
||||
// if(filteredFilesChanged != 0)
|
||||
// *filteredFilesChanged = true;
|
||||
// } else {
|
||||
model->setData(index, QVariant(HIGH));
|
||||
if(old_val != NORMAL){
|
||||
model->setData(index, QVariant(NORMAL));
|
||||
if(filteredFilesChanged != 0)
|
||||
*filteredFilesChanged = true;
|
||||
// }
|
||||
} else {
|
||||
model->setData(index, QVariant(HIGH));
|
||||
model->setData(index, QVariant(NORMAL));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(old_val != HIGH){
|
||||
|
||||
@@ -1,189 +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.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#include <QDir>
|
||||
#include <QTreeView>
|
||||
#include <QStandardItemModel>
|
||||
#include <QHeaderView>
|
||||
#include <QSettings>
|
||||
|
||||
#include "SearchTab.h"
|
||||
#include "SearchListDelegate.h"
|
||||
#include "misc.h"
|
||||
#include "searchEngine.h"
|
||||
|
||||
#define SEARCH_NAME 0
|
||||
#define SEARCH_SIZE 1
|
||||
#define SEARCH_SEEDERS 2
|
||||
#define SEARCH_LEECHERS 3
|
||||
#define SEARCH_ENGINE 4
|
||||
|
||||
SearchTab::SearchTab(SearchEngine *parent) : QWidget()
|
||||
{
|
||||
box=new QVBoxLayout();
|
||||
results_lbl=new QLabel();
|
||||
resultsBrowser = new QTreeView();
|
||||
resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
box->addWidget(results_lbl);
|
||||
box->addWidget(resultsBrowser);
|
||||
|
||||
setLayout(box);
|
||||
// Set Search results list model
|
||||
SearchListModel = new QStandardItemModel(0,5);
|
||||
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_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_ENGINE, Qt::Horizontal, tr("Search engine"));
|
||||
resultsBrowser->setModel(SearchListModel);
|
||||
SearchDelegate = new SearchListDelegate();
|
||||
resultsBrowser->setItemDelegate(SearchDelegate);
|
||||
// Make search list header clickable for sorting
|
||||
resultsBrowser->header()->setClickable(true);
|
||||
resultsBrowser->header()->setSortIndicatorShown(true);
|
||||
|
||||
// Connect signals to slots (search part)
|
||||
connect(resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), parent, SLOT(downloadSelectedItem(const QModelIndex&)));
|
||||
connect(resultsBrowser->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortSearchList(int)));
|
||||
|
||||
// Load last columns width for search results list
|
||||
if(!loadColWidthSearchList()){
|
||||
resultsBrowser->header()->resizeSection(0, 275);
|
||||
}
|
||||
}
|
||||
|
||||
SearchTab::~SearchTab()
|
||||
{
|
||||
saveColWidthSearchList();
|
||||
delete resultsBrowser;
|
||||
delete SearchListModel;
|
||||
delete SearchDelegate;
|
||||
}
|
||||
|
||||
QLabel* SearchTab::getCurrentLabel()
|
||||
{
|
||||
return results_lbl;
|
||||
}
|
||||
|
||||
QTreeView* SearchTab::getCurrentTreeView()
|
||||
{
|
||||
return resultsBrowser;
|
||||
}
|
||||
|
||||
QStandardItemModel* SearchTab::getCurrentSearchListModel()
|
||||
{
|
||||
return SearchListModel;
|
||||
}
|
||||
|
||||
// Set the color of a row in data model
|
||||
void SearchTab::setRowColor(int row, QString color){
|
||||
for(int i=0; i<SearchListModel->columnCount(); ++i){
|
||||
SearchListModel->setData(SearchListModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchTab::sortSearchList(int index){
|
||||
static Qt::SortOrder sortOrder = Qt::AscendingOrder;
|
||||
if(resultsBrowser->header()->sortIndicatorSection() == index){
|
||||
sortOrder = (sortOrder == Qt::DescendingOrder) ? Qt::AscendingOrder : Qt::DescendingOrder; ;
|
||||
}
|
||||
resultsBrowser->header()->setSortIndicator(index, sortOrder);
|
||||
switch(index){
|
||||
case SEEDERS:
|
||||
case LEECHERS:
|
||||
case SIZE:
|
||||
sortSearchListInt(index, sortOrder);
|
||||
break;
|
||||
default:
|
||||
sortSearchListString(index, sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchTab::sortSearchListInt(int index, Qt::SortOrder sortOrder){
|
||||
QList<QPair<int, qlonglong> > lines;
|
||||
// Insertion sorting
|
||||
for(int i=0; i<SearchListModel->rowCount(); ++i){
|
||||
misc::insertSort(lines, QPair<int,qlonglong>(i, SearchListModel->data(SearchListModel->index(i, index)).toLongLong()), sortOrder);
|
||||
}
|
||||
// Insert items in new model, in correct order
|
||||
int nbRows_old = lines.size();
|
||||
for(int row=0; row<lines.size(); ++row){
|
||||
SearchListModel->insertRow(SearchListModel->rowCount());
|
||||
int sourceRow = lines[row].first;
|
||||
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), Qt::ForegroundRole), Qt::ForegroundRole);
|
||||
}
|
||||
}
|
||||
// Remove old rows
|
||||
SearchListModel->removeRows(0, nbRows_old);
|
||||
}
|
||||
|
||||
void SearchTab::sortSearchListString(int index, Qt::SortOrder sortOrder){
|
||||
QList<QPair<int, QString> > lines;
|
||||
// Insetion sorting
|
||||
for(int i=0; i<SearchListModel->rowCount(); ++i){
|
||||
misc::insertSortString(lines, QPair<int, QString>(i, SearchListModel->data(SearchListModel->index(i, index)).toString()), sortOrder);
|
||||
}
|
||||
// Insert items in new model, in correct order
|
||||
int nbRows_old = lines.size();
|
||||
for(int row=0; row<nbRows_old; ++row){
|
||||
SearchListModel->insertRow(SearchListModel->rowCount());
|
||||
int sourceRow = lines[row].first;
|
||||
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), Qt::ForegroundRole), Qt::ForegroundRole);
|
||||
}
|
||||
}
|
||||
// Remove old rows
|
||||
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;
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#ifndef SEARCH_TAB_H
|
||||
#define SEARCH_TAB_H
|
||||
|
||||
#include "ui_search.h"
|
||||
|
||||
class SearchListDelegate;
|
||||
class SearchEngine;
|
||||
class QTreeView;
|
||||
class QStandardItemModel;
|
||||
|
||||
class SearchTab : public QWidget, public Ui::search_engine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QVBoxLayout *box;
|
||||
QLabel *results_lbl;
|
||||
QTreeView *resultsBrowser;
|
||||
QStandardItemModel *SearchListModel;
|
||||
SearchListDelegate *SearchDelegate;
|
||||
public:
|
||||
SearchTab(SearchEngine *parent);
|
||||
~SearchTab();
|
||||
bool loadColWidthSearchList();
|
||||
QLabel * getCurrentLabel();
|
||||
QStandardItemModel * getCurrentSearchListModel();
|
||||
QTreeView * getCurrentTreeView();
|
||||
void setRowColor(int row, QString color);
|
||||
protected slots:
|
||||
void sortSearchList(int index);
|
||||
void sortSearchListInt(int index, Qt::SortOrder sortOrder);
|
||||
void sortSearchListString(int index, Qt::SortOrder sortOrder);
|
||||
void saveColWidthSearchList() const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,53 +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.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#ifndef TRACKERSADDITION_H
|
||||
#define TRACKERSADDITION_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QStringList>
|
||||
#include "ui_trackersAdd.h"
|
||||
|
||||
class TrackersAddDlg : public QDialog, private Ui::TrackersAdditionDlg{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TrackersAddDlg(QWidget *parent): QDialog(parent){
|
||||
setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
show();
|
||||
}
|
||||
|
||||
~TrackersAddDlg(){}
|
||||
|
||||
signals:
|
||||
void TrackersToAdd(QStringList trackers);
|
||||
|
||||
public slots:
|
||||
void on_buttonBox_accepted() {
|
||||
QStringList trackers = trackers_list->toPlainText().trimmed().split("\n");
|
||||
if(trackers.size()) {
|
||||
emit TrackersToAdd(trackers);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -44,7 +44,7 @@ class about : public QDialog, private Ui::AboutDlg{
|
||||
// Thanks
|
||||
te_thanks->append(QString::fromUtf8("<a name='top'></a>"));
|
||||
te_thanks->append(QString::fromUtf8("<ul><li>I would like to thank sourceforge.net for hosting qBittorrent project.</li>"));
|
||||
te_thanks->append(QString::fromUtf8("<li>I am happy that Ishan Arora and Arnaud Demaizière are contributing to the project as developers. Their help is greatly appreciated</li>"));
|
||||
te_thanks->append(QString::fromUtf8("<li>I am happy that Arnaud Demaizière is contributing to the project as a developer. His help is greatly appreciated</li>"));
|
||||
te_thanks->append(QString::fromUtf8("<li>I also want to thank Jeffery Fernandez (jeffery@qbittorrent.org), project consultant, RPM packager, for his help and support.</li>"));
|
||||
te_thanks->append(QString::fromUtf8("<li>I am grateful to Peter Koeleman (peter@qbittorrent.org) who is helping port qBittorrent to Windows.</li>"));
|
||||
te_thanks->append(QString::fromUtf8("<li>Thanks a lot to our graphist Mateusz Toboła (tobejodok@qbittorrent.org) for his great work.</li></ul><br><br>"));
|
||||
@@ -56,15 +56,13 @@ class about : public QDialog, private Ui::AboutDlg{
|
||||
"<i>- <u>Brazilian:</u> Nick Marinho (nickmarinho@gmail.com)<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>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>Chinese (Simplified):</u> Guo Yue (guoyue0418@hotmail.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)<br>\
|
||||
- <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net)<br>\
|
||||
- <u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\
|
||||
- <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\
|
||||
- <u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)<br>\
|
||||
- <u>Hungarian:</u> Majoros Péter (majoros.j.p@t-online.hu)<br>\
|
||||
- <u>Italian:</u> Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)<br>\
|
||||
- <u>Japanese:</u> Nardog (nardog@e2umail.com)<br>\
|
||||
- <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\
|
||||
@@ -72,11 +70,11 @@ class about : public QDialog, private Ui::AboutDlg{
|
||||
- <u>Polish:</u> Jarek Smieja (ajep9691@wp.pl)<br>\
|
||||
- <u>Portuguese:</u> Nick Marinho (nickmarinho@gmail.com)<br>\
|
||||
- <u>Romanian:</u> Obada Denis (obadadenis@users.sourceforge.net)<br>\
|
||||
- <u>Russian:</u> Nick Khazov (m2k3d0n@users.sourceforge.net) and Alexey Morsov (samurai@ricom.ru)<br>\
|
||||
- <u>Russian:</u> Nick Khazov (m2k3d0n at users.sourceforge.net)<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)<br>\
|
||||
- <u>Swedish:</u> Daniel Nylander (po@danielnylander.se)<br>\
|
||||
- <u>Turkish:</u> Hasan YILMAZ (iletisim@hedefturkce.com) and Erdem Bingöl (erdem84@gmail.com)<br>\
|
||||
- <u>Turkish:</u> Erdem Bingöl (erdem84@gmail.com)<br>\
|
||||
- <u>Ukrainian:</u> Andrey Shpachenko (masterfix@users.sourceforge.net)<br><br>"));
|
||||
te_translation->append(tr("Please contact me if you would like to translate qBittorrent into your own language."));
|
||||
te_translation->scrollToAnchor(QString::fromUtf8("top"));
|
||||
|
||||
@@ -13,6 +13,21 @@
|
||||
<string>Torrent addition dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="fileNameLbl" >
|
||||
<property name="text" >
|
||||
@@ -95,50 +110,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="collapseAllButton" >
|
||||
<property name="text" >
|
||||
<string>Collapse all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="expandAllButton" >
|
||||
<property name="text" >
|
||||
<string>Expand all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkIncrementalDL" >
|
||||
<property name="text" >
|
||||
|
||||
@@ -27,19 +27,19 @@
|
||||
#include <QDir>
|
||||
#include "misc.h"
|
||||
|
||||
class torrent_file {
|
||||
class file {
|
||||
private:
|
||||
torrent_file *parent;
|
||||
file *parent;
|
||||
bool is_dir;
|
||||
QString rel_path;
|
||||
QList<torrent_file*> children;
|
||||
QList<file*> children;
|
||||
size_type size;
|
||||
float progress;
|
||||
int priority;
|
||||
int index; // Index in torrent_info
|
||||
|
||||
public:
|
||||
torrent_file(torrent_file *parent, QString path, bool dir, size_type size=0, int index=-1, float progress=0., int priority=1): parent(parent), is_dir(dir), size(size), progress(progress), priority(priority), index(index){
|
||||
file(file *parent, QString path, bool dir, size_type size=0, int index=-1, float progress=0., int priority=1): parent(parent), is_dir(dir), size(size), progress(progress), priority(priority), index(index){
|
||||
qDebug("created a file with index %d", index);
|
||||
rel_path = QDir::cleanPath(path);
|
||||
if(parent) {
|
||||
@@ -48,7 +48,7 @@ class torrent_file {
|
||||
}
|
||||
}
|
||||
|
||||
~torrent_file() {
|
||||
~file() {
|
||||
qDeleteAll(children);
|
||||
}
|
||||
|
||||
@@ -62,25 +62,17 @@ class torrent_file {
|
||||
|
||||
void updateProgress() {
|
||||
Q_ASSERT(is_dir);
|
||||
if(children.isEmpty()) {
|
||||
progress = 0.;
|
||||
return;
|
||||
}
|
||||
float wanted = 0.;
|
||||
float done = 0.;
|
||||
torrent_file *child;
|
||||
float sum = 0;
|
||||
file *child;
|
||||
foreach(child, children) {
|
||||
wanted += child->getSize();
|
||||
done += child->getSize()*child->getProgress();
|
||||
sum += child->getProgress();
|
||||
}
|
||||
progress = done / wanted;
|
||||
Q_ASSERT(progress >= 0.);
|
||||
Q_ASSERT(progress <= 1.);
|
||||
progress = sum / (float)children.size();
|
||||
}
|
||||
|
||||
void updatePriority(int prio) {
|
||||
Q_ASSERT(is_dir);
|
||||
torrent_file *child;
|
||||
file *child;
|
||||
foreach(child, children) {
|
||||
if(child->getPriority() != prio) return;
|
||||
}
|
||||
@@ -111,13 +103,13 @@ class torrent_file {
|
||||
return (!children.isEmpty());
|
||||
}
|
||||
|
||||
QList<torrent_file*> getChildren() const {
|
||||
QList<file*> getChildren() const {
|
||||
return children;
|
||||
}
|
||||
|
||||
torrent_file* getChild(QString fileName) const {
|
||||
file* getChild(QString fileName) const {
|
||||
Q_ASSERT(is_dir);
|
||||
torrent_file* f;
|
||||
file* f;
|
||||
foreach(f, children) {
|
||||
if(f->name() == fileName) return f;
|
||||
}
|
||||
@@ -130,10 +122,10 @@ class torrent_file {
|
||||
parent->addBytes(b);
|
||||
}
|
||||
|
||||
torrent_file* addChild(QString fileName, bool dir, size_type size=0, int index = -1, float progress=0., int priority=1) {
|
||||
file* addChild(QString fileName, bool dir, size_type size=0, int index = -1, float progress=0., int priority=1) {
|
||||
Q_ASSERT(is_dir);
|
||||
qDebug("Adding a new child of size: %ld", (long)size);
|
||||
torrent_file *f = new torrent_file(this, QDir::cleanPath(rel_path+QDir::separator()+fileName), dir, size, index, progress, priority);
|
||||
file *f = new file(this, QDir::cleanPath(rel_path+QDir::separator()+fileName), dir, size, index, progress, priority);
|
||||
children << f;
|
||||
if(size) {
|
||||
addBytes(size);
|
||||
@@ -148,7 +140,7 @@ class torrent_file {
|
||||
return true;
|
||||
}
|
||||
bool success = true;
|
||||
torrent_file *f;
|
||||
file *f;
|
||||
qDebug("We have %d children", children.size());
|
||||
foreach(f, children) {
|
||||
bool s = f->removeFromFS(saveDir);
|
||||
@@ -169,44 +161,44 @@ class torrent_file {
|
||||
|
||||
class arborescence {
|
||||
private:
|
||||
torrent_file *root;
|
||||
file *root;
|
||||
|
||||
public:
|
||||
arborescence(boost::intrusive_ptr<torrent_info> t) {
|
||||
torrent_info::file_iterator fi = t->begin_files();
|
||||
if(t->num_files() > 1) {
|
||||
root = new torrent_file(0, misc::toQString(t->name()), true);
|
||||
} else {
|
||||
// XXX: Will crash if there is no file in torrent
|
||||
root = new torrent_file(0, misc::toQString(t->name()), false, fi->size, 0);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
while(fi != t->end_files()) {
|
||||
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
||||
addFile(path, fi->size, i);
|
||||
fi++;
|
||||
++i;
|
||||
}
|
||||
qDebug("real size: %ld, tree size: %ld", (long)t->total_size(), (long)root->getSize());
|
||||
Q_ASSERT(root->getSize() == t->total_size());
|
||||
}
|
||||
|
||||
arborescence(torrent_info const& t, std::vector<size_type> fp, int *prioritiesTab) {
|
||||
arborescence(torrent_info t) {
|
||||
torrent_info::file_iterator fi = t.begin_files();
|
||||
if(t.num_files() > 1) {
|
||||
qDebug("More than one file in the torrent, setting a folder as root");
|
||||
root = new torrent_file(0, misc::toQString(t.name()), true);
|
||||
root = new file(0, misc::toQString(t.name()), true);
|
||||
} else {
|
||||
// XXX: Will crash if there is no file in torrent
|
||||
qDebug("one file in the torrent, setting it as root with index 0");
|
||||
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0]/t.file_at(0).size, prioritiesTab[0]);
|
||||
root = new file(0, misc::toQString(t.name()), false, fi->size, 0);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
while(fi != t.end_files()) {
|
||||
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
||||
addFile(path, fi->size, i, fp[i]/t.file_at(i).size, prioritiesTab[i]);
|
||||
addFile(path, fi->size, i);
|
||||
fi++;
|
||||
++i;
|
||||
}
|
||||
qDebug("real size: %ld, tree size: %ld", (long)t.total_size(), (long)root->getSize());
|
||||
Q_ASSERT(root->getSize() == t.total_size());
|
||||
}
|
||||
|
||||
arborescence(torrent_info t, std::vector<float> fp, int *prioritiesTab) {
|
||||
torrent_info::file_iterator fi = t.begin_files();
|
||||
if(t.num_files() > 1) {
|
||||
qDebug("More than one file in the torrent, setting a folder as root");
|
||||
root = new file(0, misc::toQString(t.name()), true);
|
||||
} else {
|
||||
// XXX: Will crash if there is no file in torrent
|
||||
qDebug("one file in the torrent, setting it as root with index 0");
|
||||
root = new file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
while(fi != t.end_files()) {
|
||||
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
||||
addFile(path, fi->size, i, fp[i], prioritiesTab[i]);
|
||||
fi++;
|
||||
++i;
|
||||
}
|
||||
@@ -218,7 +210,7 @@ class arborescence {
|
||||
delete root;
|
||||
}
|
||||
|
||||
torrent_file* getRoot() const {
|
||||
file* getRoot() const {
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -234,19 +226,19 @@ class arborescence {
|
||||
void addFile(QString path, size_type file_size, int index, float progress=0., int priority=1) {
|
||||
Q_ASSERT(root->isDir());
|
||||
path = QDir::cleanPath(path);
|
||||
//Q_ASSERT(path.startsWith(root->path()));
|
||||
Q_ASSERT(path.startsWith(root->path()));
|
||||
QString relative_path = path.remove(0, root->path().size());
|
||||
if(relative_path.at(0) ==QDir::separator())
|
||||
relative_path.remove(0, 1);
|
||||
QStringList fileNames = relative_path.split(QDir::separator());
|
||||
QString fileName;
|
||||
torrent_file *dad = root;
|
||||
file *dad = root;
|
||||
unsigned int nb_i = 0;
|
||||
unsigned int size = fileNames.size();
|
||||
foreach(fileName, fileNames) {
|
||||
++nb_i;
|
||||
if(fileName == ".") continue;
|
||||
torrent_file* child = dad->getChild(fileName);
|
||||
file* child = dad->getChild(fileName);
|
||||
if(!child) {
|
||||
if(nb_i != size) {
|
||||
// Folder
|
||||
|
||||
1305
src/bittorrent.cpp
110
src/bittorrent.h
@@ -22,10 +22,9 @@
|
||||
#define __BITTORRENT_H__
|
||||
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QStringList>
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QPointer>
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/ip_filter.hpp>
|
||||
@@ -35,37 +34,33 @@ using namespace libtorrent;
|
||||
|
||||
class downloadThread;
|
||||
class QTimer;
|
||||
class QFileSystemWatcher;
|
||||
class QMutex;
|
||||
class FilterParserThread;
|
||||
|
||||
class bittorrent : public QObject {
|
||||
class bittorrent : public QObject{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
session *s;
|
||||
QPointer<QFileSystemWatcher> FSWatcher;
|
||||
QMutex* FSMutex;
|
||||
QPointer<QTimer> timerAlerts;
|
||||
QPointer<QTimer> BigRatioTimer;
|
||||
QString scan_dir;
|
||||
QTimer *timerScan;
|
||||
QTimer *timerAlerts;
|
||||
bool DHTEnabled;
|
||||
QPointer<downloadThread> downloader;
|
||||
downloadThread *downloader;
|
||||
QString defaultSavePath;
|
||||
QHash<QString, QHash<QString, QString> > trackersErrors;
|
||||
QStringList consoleMessages;
|
||||
QStringList peerBanMessages;
|
||||
QStringList torrentsToPauseAfterChecking;
|
||||
QHash<QString, bool> reloadingTorrents;
|
||||
QHash<QString, QList<qlonglong> > ETAstats;
|
||||
QHash<QString, qlonglong> ETAs;
|
||||
QHash<QString, QPair<size_type,size_type> > ratioData;
|
||||
QTimer *ETARefresher;
|
||||
QHash<QString, QList<QPair<QString, QString> > > trackersErrors;
|
||||
QStringList waitingForPause;
|
||||
QStringList finishedTorrents;
|
||||
QStringList unfinishedTorrents;
|
||||
bool preAllocateAll;
|
||||
bool addInPause;
|
||||
int maxConnecsPerTorrent;
|
||||
int maxUploadsPerTorrent;
|
||||
float max_ratio;
|
||||
bool UPnPEnabled;
|
||||
bool NATPMPEnabled;
|
||||
bool LSDEnabled;
|
||||
QPointer<FilterParserThread> filterParser;
|
||||
QString filterPath;
|
||||
bool queueingEnabled;
|
||||
QStringList url_skippingDlg;
|
||||
|
||||
protected:
|
||||
QString getSavePath(QString hash);
|
||||
@@ -75,59 +70,46 @@ class bittorrent : public QObject {
|
||||
bittorrent();
|
||||
~bittorrent();
|
||||
QTorrentHandle getTorrentHandle(QString hash) const;
|
||||
std::vector<torrent_handle> getTorrents() const;
|
||||
bool isPaused(QString hash) const;
|
||||
bool isFilePreviewPossible(QString fileHash) const;
|
||||
bool isDHTEnabled() const;
|
||||
float getPayloadDownloadRate() const;
|
||||
float getPayloadUploadRate() const;
|
||||
session_status getSessionStatus() const;
|
||||
int getListenPort() const;
|
||||
QStringList getTorrentsToPauseAfterChecking() const;
|
||||
long getETA(QString hash) const;
|
||||
float getRealRatio(QString hash) const;
|
||||
session* getSession() const;
|
||||
QHash<QString, QString> getTrackersErrors(QString hash) const;
|
||||
QList<QPair<QString, QString> > getTrackersErrors(QString hash) const;
|
||||
QStringList getFinishedTorrents() const;
|
||||
QStringList getUnfinishedTorrents() const;
|
||||
bool isFinished(QString hash) const;
|
||||
bool has_filtered_files(QString hash) const;
|
||||
unsigned int getFinishedPausedTorrentsNb() const;
|
||||
unsigned int getUnfinishedPausedTorrentsNb() const;
|
||||
bool isQueueingEnabled() const;
|
||||
int getDlTorrentPriority(QString hash) const;
|
||||
int getUpTorrentPriority(QString hash) const;
|
||||
int getMaximumActiveDownloads() const;
|
||||
int getMaximumActiveTorrents() const;
|
||||
int loadTorrentPriority(QString hash);
|
||||
QStringList getConsoleMessages() const;
|
||||
QStringList getPeerBanMessages() const;
|
||||
qlonglong getETA(QString hash) const;
|
||||
|
||||
public slots:
|
||||
QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
||||
void loadSessionState();
|
||||
void saveSessionState();
|
||||
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
||||
void downloadFromUrl(QString url);
|
||||
void downloadFromURLList(const QStringList& url_list);
|
||||
void deleteTorrent(QString hash, bool permanent = false);
|
||||
/* Needed by Web UI */
|
||||
void pauseAllTorrents();
|
||||
void resumeAllTorrents();
|
||||
void pauseTorrent(QString hash);
|
||||
void resumeTorrent(QString hash);
|
||||
/* End Web UI */
|
||||
bool pauseTorrent(QString hash);
|
||||
bool resumeTorrent(QString hash);
|
||||
void saveDHTEntry();
|
||||
void preAllocateAllFiles(bool b);
|
||||
void saveFastResumeData();
|
||||
void saveFastResumeAndRatioData();
|
||||
void enableDirectoryScanning(QString scan_dir);
|
||||
void disableDirectoryScanning();
|
||||
void enableIPFilter(QString filter);
|
||||
void enablePeerExchange();
|
||||
void enableIPFilter(ip_filter filter);
|
||||
void disableIPFilter();
|
||||
void setQueueingEnabled(bool enable);
|
||||
void resumeUnfinishedTorrents();
|
||||
void saveTorrentPriority(QString hash, int prio);
|
||||
void updateETAs();
|
||||
void saveTorrentSpeedLimits(QString hash);
|
||||
void loadTorrentSpeedLimits(QString hash);
|
||||
void saveDownloadUploadForTorrent(QString hash);
|
||||
void loadDownloadUploadForTorrent(QString hash);
|
||||
void handleDownloadFailure(QString url, QString reason);
|
||||
void loadWebSeeds(QString fileHash);
|
||||
void increaseDlTorrentPriority(QString hash);
|
||||
void decreaseDlTorrentPriority(QString hash);
|
||||
void downloadUrlAndSkipDialog(QString);
|
||||
// Session configuration - Setters
|
||||
void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports);
|
||||
void setMaxConnections(int maxConnec);
|
||||
@@ -146,34 +128,42 @@ class bittorrent : public QObject {
|
||||
void loadFilesPriorities(QTorrentHandle& h);
|
||||
void setDownloadLimit(QString hash, long val);
|
||||
void setUploadLimit(QString hash, long val);
|
||||
void setUnfinishedTorrent(QString hash);
|
||||
void setFinishedTorrent(QString hash);
|
||||
void enableUPnP(bool b);
|
||||
void enableNATPMP(bool b);
|
||||
void enableLSD(bool b);
|
||||
bool enableDHT(bool b);
|
||||
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
||||
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
||||
void enableDHT(bool b);
|
||||
|
||||
protected slots:
|
||||
void scanDirectory(QString);
|
||||
void scanDirectory();
|
||||
void readAlerts();
|
||||
void processDownloadedFile(QString, QString);
|
||||
bool loadTrackerFile(QString hash);
|
||||
void saveTrackerFile(QString hash);
|
||||
void pauseAndReloadTorrent(QTorrentHandle h, bool full_alloc);
|
||||
void reloadTorrent(const QTorrentHandle &h, bool full_alloc); // This is protected now, call pauseAndReloadTorrent() instead
|
||||
void deleteBigRatios();
|
||||
|
||||
signals:
|
||||
void addedTorrent(QTorrentHandle& h);
|
||||
void deletedTorrent(QString hash);
|
||||
void pausedTorrent(QTorrentHandle& h);
|
||||
void resumedTorrent(QTorrentHandle& h);
|
||||
void invalidTorrent(QString path);
|
||||
void duplicateTorrent(QString path);
|
||||
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume);
|
||||
void finishedTorrent(QTorrentHandle& h);
|
||||
void fullDiskError(QTorrentHandle& h);
|
||||
void trackerError(QString hash, QString time, QString msg);
|
||||
void portListeningFailure();
|
||||
void trackerAuthenticationRequired(QTorrentHandle& h);
|
||||
void scanDirFoundTorrents(const QStringList& pathList);
|
||||
void newDownloadedTorrent(QString path, QString url);
|
||||
void aboutToDownloadFromUrl(QString url);
|
||||
void updateFileSize(QString hash);
|
||||
void peerBlocked(QString);
|
||||
void downloadFromUrlFailure(QString url, QString reason);
|
||||
void torrentFinishedChecking(QTorrentHandle& h);
|
||||
void fastResumeDataRejected(QString name);
|
||||
void urlSeedProblem(QString url, QString msg);
|
||||
void torrentFinishedChecking(QString hash);
|
||||
void torrent_deleted(QString hash, QString fileName, bool finished);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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/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/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>
|
||||
@@ -1,50 +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.
|
||||
*
|
||||
* 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
|
||||
19
src/convertPOtoTS.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
|
||||
LANG_FOLDER = "lang/"
|
||||
PO_FOLDER = 'po_files'
|
||||
|
||||
if __name__ == '__main__':
|
||||
po_files = os.listdir(os.path.join(LANG_FOLDER, PO_FOLDER))
|
||||
po_files = [x for x in po_files if os.path.splitext(x)[-1] == ".po"]
|
||||
for file in po_files:
|
||||
# First clean up the ts file
|
||||
ts_file = os.path.join(LANG_FOLDER, os.path.splitext(file)[0]+'.ts')
|
||||
po_file = os.path.join(LANG_FOLDER, PO_FOLDER, file)
|
||||
if os.path.exists(ts_file):
|
||||
os.remove(ts_file)
|
||||
# Convert to PO
|
||||
print "Converting %s..." % (po_file,)
|
||||
os.system("po2ts %s -o %s" % (po_file, ts_file))
|
||||
24
src/convertTStoPO.py
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
|
||||
LANG_FOLDER = 'lang/'
|
||||
PO_FOLDER = 'po_files'
|
||||
|
||||
if __name__ == '__main__':
|
||||
ts_files = os.listdir(LANG_FOLDER)
|
||||
ts_files = [x for x in ts_files if os.path.splitext(x)[-1] == ".ts"]
|
||||
for file in ts_files:
|
||||
# First clean up the po file
|
||||
po_file = os.path.join(LANG_FOLDER, PO_FOLDER, os.path.splitext(file)[0]+'.po')
|
||||
ts_file = os.path.join(LANG_FOLDER, file)
|
||||
if os.path.exists(po_file):
|
||||
os.remove(po_file)
|
||||
# create po folder if it doesn't exist
|
||||
if not os.path.exists(os.path.join(LANG_FOLDER, PO_FOLDER)):
|
||||
os.mkdir(os.path.join(LANG_FOLDER, PO_FOLDER))
|
||||
# Convert to PO
|
||||
print "Converting %s..." % (ts_file,)
|
||||
os.system("ts2po %s -o %s" % (ts_file, po_file))
|
||||
# Making an archive
|
||||
os.system("tar czf %s %s" % (os.path.join(LANG_FOLDER, PO_FOLDER)+'.tar.gz', os.path.join(LANG_FOLDER, PO_FOLDER)))
|
||||
@@ -6,7 +6,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>592</width>
|
||||
<height>655</height>
|
||||
<height>590</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
@@ -477,20 +477,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="progressLbl" >
|
||||
<property name="text" >
|
||||
<string>Progress:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar" >
|
||||
<property name="value" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <libtorrent/entry.hpp>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
@@ -35,38 +34,18 @@
|
||||
#include <libtorrent/storage.hpp>
|
||||
#include <libtorrent/hasher.hpp>
|
||||
#include <libtorrent/file_pool.hpp>
|
||||
#include <libtorrent/create_torrent.hpp>
|
||||
|
||||
#include "createtorrent_imp.h"
|
||||
#include "misc.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
// do not include files and folders whose
|
||||
// name starts with a .
|
||||
bool file_filter(boost::filesystem::path const& filename)
|
||||
{
|
||||
if (filename.leaf()[0] == '.') return false;
|
||||
std::cerr << filename << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
createtorrent::createtorrent(QWidget *parent): QDialog(parent){
|
||||
setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
creatorThread = new torrentCreatorThread(this);
|
||||
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*)), this, SLOT(handleCreationSuccess(QString, const char*)));
|
||||
connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString)));
|
||||
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
|
||||
path::default_name_check(no_check);
|
||||
show();
|
||||
}
|
||||
|
||||
createtorrent::~createtorrent() {
|
||||
delete creatorThread;
|
||||
}
|
||||
|
||||
void createtorrent::on_addFolder_button_clicked(){
|
||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly);
|
||||
if(!dir.isEmpty())
|
||||
@@ -138,6 +117,18 @@ 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){
|
||||
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{
|
||||
t.add_file(l, file_size(f));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList createtorrent::allItems(QListWidget *list){
|
||||
QStringList res;
|
||||
unsigned int nbItems = list->count();
|
||||
@@ -150,8 +141,6 @@ QStringList createtorrent::allItems(QListWidget *list){
|
||||
// Main function that create a .torrent file
|
||||
void createtorrent::on_createButton_clicked(){
|
||||
QString input = textInputPath->text().trimmed();
|
||||
if (input.endsWith(QDir::separator()))
|
||||
input.chop(1);
|
||||
if(input.isEmpty()){
|
||||
QMessageBox::critical(0, tr("No input path set"), tr("Please type an input path first"));
|
||||
return;
|
||||
@@ -168,100 +157,58 @@ void createtorrent::on_createButton_clicked(){
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
QStringList url_seeds = allItems(URLSeeds_list);
|
||||
QString comment = txt_comment->toPlainText();
|
||||
creatorThread->create(input, destination, trackers, url_seeds, comment, check_private->isChecked(), getPieceSize());
|
||||
}
|
||||
|
||||
void createtorrent::handleCreationFailure(QString 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) {
|
||||
if(checkStartSeeding->isChecked()) {
|
||||
// Create save path file
|
||||
boost::intrusive_ptr<torrent_info> t;
|
||||
try {
|
||||
t = new torrent_info(path.toUtf8().data());
|
||||
} catch(std::exception&) {
|
||||
QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list."));
|
||||
return;
|
||||
}
|
||||
QString hash = misc::toQString(t->info_hash());
|
||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
savepath_file.write(branch_path);
|
||||
savepath_file.close();
|
||||
emit torrent_to_seed(path);
|
||||
}
|
||||
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
|
||||
hide();
|
||||
}
|
||||
|
||||
void createtorrent::updateProgressBar(int progress) {
|
||||
progressBar->setValue(progress);
|
||||
}
|
||||
|
||||
//
|
||||
// Torrent Creator Thread
|
||||
//
|
||||
|
||||
void torrentCreatorThread::create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size) {
|
||||
input_path = _input_path;
|
||||
save_path = _save_path;
|
||||
trackers = _trackers;
|
||||
url_seeds = _url_seeds;
|
||||
comment = _comment;
|
||||
is_private = _is_private;
|
||||
piece_size = _piece_size;
|
||||
abort = false;
|
||||
start();
|
||||
}
|
||||
|
||||
void sendProgressUpdateSignal(int i, int num, QDialog *parent){
|
||||
((createtorrent*)parent)->updateProgressBar((int)(i*100./(float)num));
|
||||
}
|
||||
|
||||
void torrentCreatorThread::run() {
|
||||
emit updateProgress(0);
|
||||
char const* creator_str = "qBittorrent "VERSION;
|
||||
try {
|
||||
file_storage fs;
|
||||
file_pool fp;
|
||||
path full_path = complete(path(input_path.toUtf8().data()));
|
||||
boost::intrusive_ptr<torrent_info> t(new torrent_info);
|
||||
ofstream out(complete(path((const char*)destination.toUtf8())), std::ios_base::binary);
|
||||
path full_path;
|
||||
// Adding files to the torrent
|
||||
add_files(fs, full_path, file_filter);
|
||||
if(abort) return;
|
||||
create_torrent t(fs, piece_size);
|
||||
|
||||
full_path = complete(path(input.toUtf8().data()));
|
||||
add_files(*t, full_path.branch_path(), full_path.leaf());
|
||||
// Set piece size
|
||||
int piece_size = getPieceSize();
|
||||
t->set_piece_size(piece_size);
|
||||
// Add url seeds
|
||||
QStringList urlSeeds = allItems(URLSeeds_list);
|
||||
QString seed;
|
||||
foreach(seed, url_seeds){
|
||||
t.add_url_seed(seed.toUtf8().data());
|
||||
foreach(seed, urlSeeds){
|
||||
t->add_url_seed(seed.toUtf8().data());
|
||||
}
|
||||
for(int i=0; i<trackers.size(); ++i){
|
||||
t.add_tracker(trackers.at(i).toUtf8().data());
|
||||
t->add_tracker(trackers.at(i).toUtf8().data());
|
||||
}
|
||||
if(abort) return;
|
||||
|
||||
// calculate the hash for all pieces
|
||||
set_piece_hashes(t, full_path.branch_path(), boost::bind<void>(&sendProgressUpdateSignal, _1, t.num_pieces(), parent));
|
||||
file_pool fp;
|
||||
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp));
|
||||
int num = t->num_pieces();
|
||||
std::vector<char> buf(piece_size);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
st->read(&buf[0], i, 0, t->piece_size(i));
|
||||
hasher h(&buf[0], t->piece_size(i));
|
||||
t->set_hash(i, h.final());
|
||||
}
|
||||
// Set qBittorrent as creator and add user comment to
|
||||
// torrent_info structure
|
||||
t.set_creator(creator_str);
|
||||
t.set_comment((const char*)comment.toUtf8());
|
||||
t->set_creator(creator_str);
|
||||
t->set_comment((const char*)txt_comment->toPlainText().toUtf8());
|
||||
// Is private ?
|
||||
if(is_private){
|
||||
t.set_priv(true);
|
||||
if(check_private->isChecked()){
|
||||
t->set_priv(true);
|
||||
}
|
||||
if(abort) return;
|
||||
// create the torrent and print it to out
|
||||
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
|
||||
bencode(std::ostream_iterator<char>(out), t.generate());
|
||||
emit updateProgress(100);
|
||||
emit creationSuccess(save_path, full_path.branch_path().string().c_str());
|
||||
entry e = t->create_torrent();
|
||||
libtorrent::bencode(std::ostream_iterator<char>(out), e);
|
||||
out.flush();
|
||||
if(checkStartSeeding->isChecked())
|
||||
emit torrent_to_seed(destination);
|
||||
}
|
||||
catch (std::exception& e){
|
||||
emit creationFailure(QString::fromUtf8(e.what()));
|
||||
std::cerr << e.what() << "\n";
|
||||
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(QString::fromUtf8(e.what())));
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
hide();
|
||||
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+destination);
|
||||
}
|
||||
|
||||
@@ -22,60 +22,19 @@
|
||||
#ifndef CREATE_TORRENT_IMP_H
|
||||
#define CREATE_TORRENT_IMP_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include "ui_createtorrent.h"
|
||||
|
||||
class torrentCreatorThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
QString input_path;
|
||||
QString save_path;
|
||||
QStringList trackers;
|
||||
QStringList url_seeds;
|
||||
QString comment;
|
||||
bool is_private;
|
||||
int piece_size;
|
||||
bool abort;
|
||||
QDialog *parent;
|
||||
|
||||
public:
|
||||
torrentCreatorThread(QDialog *_parent) {
|
||||
parent = _parent;
|
||||
}
|
||||
~torrentCreatorThread() {
|
||||
abort = true;
|
||||
wait();
|
||||
}
|
||||
void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
signals:
|
||||
void creationFailure(QString msg);
|
||||
void creationSuccess(QString path, const char* branch_path);
|
||||
void updateProgress(int progress);
|
||||
};
|
||||
|
||||
class createtorrent : public QDialog, private Ui::createTorrentDialog{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
torrentCreatorThread *creatorThread;
|
||||
|
||||
public:
|
||||
createtorrent(QWidget *parent = 0);
|
||||
~createtorrent();
|
||||
QStringList allItems(QListWidget *list);
|
||||
int getPieceSize() const;
|
||||
|
||||
signals:
|
||||
void torrent_to_seed(QString path);
|
||||
|
||||
public slots:
|
||||
void updateProgressBar(int progress);
|
||||
|
||||
protected slots:
|
||||
void on_createButton_clicked();
|
||||
void on_addFile_button_clicked();
|
||||
@@ -84,8 +43,6 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
|
||||
void on_removeTracker_button_clicked();
|
||||
void on_addURLSeed_button_clicked();
|
||||
void on_removeURLSeed_button_clicked();
|
||||
void handleCreationFailure(QString msg);
|
||||
void handleCreationSuccess(QString path, const char* branch_path);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
125
src/deleteThread.h
Normal 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
|
||||
351
src/download.ui
@@ -21,6 +21,185 @@
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<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="QLabel" name="lbl_DLSpeed" >
|
||||
<property name="text" >
|
||||
<string>Total DL Speed:</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="LCD_DownSpeed" >
|
||||
<property name="autoFillBackground" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="smallDecimalPoint" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="numDigits" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="segmentStyle" >
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
<property name="value" stdset="0" >
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="intValue" stdset="0" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="unitDL" >
|
||||
<property name="text" >
|
||||
<string>KiB/s</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</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>
|
||||
<item>
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Session ratio: </string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="LCD_Ratio" >
|
||||
<property name="autoFillBackground" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="numDigits" >
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="segmentStyle" >
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
<property name="value" stdset="0" >
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbl_ratio_icon" >
|
||||
<property name="text" >
|
||||
<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>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbl_UPSpeed" >
|
||||
<property name="text" >
|
||||
<string>Total UP Speed:</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="LCD_UpSpeed" >
|
||||
<property name="autoFillBackground" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="smallDecimalPoint" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="numDigits" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="segmentStyle" >
|
||||
<enum>QLCDNumber::Flat</enum>
|
||||
</property>
|
||||
<property name="value" stdset="0" >
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="unitUP" >
|
||||
<property name="text" >
|
||||
<string>KiB/s</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="downloadList" >
|
||||
<property name="minimumSize" >
|
||||
@@ -48,6 +227,79 @@
|
||||
</item>
|
||||
</layout>
|
||||
</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="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="infoBar" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>7</hsizetype>
|
||||
<vsizetype>7</vsizetype>
|
||||
<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="margin" >
|
||||
<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>
|
||||
<action name="actionStart" >
|
||||
<property name="text" >
|
||||
@@ -64,6 +316,11 @@
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClearLog" >
|
||||
<property name="text" >
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreview_file" >
|
||||
<property name="text" >
|
||||
<string>Preview file</string>
|
||||
@@ -89,99 +346,7 @@
|
||||
<string>Torrent Properties</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpen_destination_folder" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/folder.png</normaloff>:/Icons/folder.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Open destination folder</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColName" >
|
||||
<property name="text" >
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColSize" >
|
||||
<property name="text" >
|
||||
<string>Size</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColProgress" >
|
||||
<property name="text" >
|
||||
<string>Progress</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColDownSpeed" >
|
||||
<property name="text" >
|
||||
<string>DLSpeed</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColUpSpeed" >
|
||||
<property name="text" >
|
||||
<string>UpSpeed</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColSeedersLeechers" >
|
||||
<property name="text" >
|
||||
<string>Seeds/Leechs</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColRatio" >
|
||||
<property name="text" >
|
||||
<string>Ratio</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColEta" >
|
||||
<property name="text" >
|
||||
<string>ETA</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBuy_it" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/money.png</normaloff>:/Icons/money.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Buy it</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHOSColPriority" >
|
||||
<property name="text" >
|
||||
<string>Priority</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionIncreasePriority" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/skin/increase.png</normaloff>:/Icons/skin/increase.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Increase priority</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDecreasePriority" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/skin/decrease.png</normaloff>:/Icons/skin/decrease.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Decrease priority</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionForce_recheck" >
|
||||
<property name="icon" >
|
||||
<iconset resource="icons.qrc" >
|
||||
<normaloff>:/Icons/gear.png</normaloff>:/Icons/gear.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Force recheck</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="icons.qrc" />
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -21,50 +21,43 @@
|
||||
|
||||
#include "downloadThread.h"
|
||||
#include <iostream>
|
||||
#include <QSettings>
|
||||
#include <stdio.h>
|
||||
#include <cc++/common.h>
|
||||
|
||||
#define MAX_THREADS 3
|
||||
|
||||
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
|
||||
QString subDownloadThread::errorCodeToString(CURLcode status) {
|
||||
QString subDownloadThread::errorCodeToString(int status) {
|
||||
switch(status){
|
||||
case CURLE_FTP_CANT_GET_HOST:
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
case 1://ost::URLStream::errUnreachable:
|
||||
return tr("Host is unreachable");
|
||||
case CURLE_READ_ERROR:
|
||||
case CURLE_FILE_COULDNT_READ_FILE:
|
||||
case 2://ost::URLStream::errMissing:
|
||||
return tr("File was not found (404)");
|
||||
case CURLE_FTP_ACCESS_DENIED:
|
||||
case CURLE_LOGIN_DENIED:
|
||||
case CURLE_FTP_USER_PASSWORD_INCORRECT:
|
||||
case 3://ost::URLStream::errDenied:
|
||||
return tr("Connection was denied");
|
||||
case CURLE_URL_MALFORMAT:
|
||||
case 4://ost::URLStream::errInvalid:
|
||||
return tr("Url is invalid");
|
||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
||||
return tr("Could not resolve proxy");
|
||||
//case 5:
|
||||
// return tr("Connection forbidden (403)");
|
||||
//case 6:
|
||||
// return tr("Connection was not authorized (401)");
|
||||
//case 7:
|
||||
// return tr("Content has moved (301)");
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
case 5://ost::URLStream::errForbidden:
|
||||
return tr("Connection forbidden (403)");
|
||||
case 6://ost::URLStream::errUnauthorized:
|
||||
return tr("Connection was not authorized (401)");
|
||||
case 7://ost::URLStream::errRelocated:
|
||||
return tr("Content has moved (301)");
|
||||
case 8://ost::URLStream::errFailure:
|
||||
return tr("Connection failure");
|
||||
case CURLE_OPERATION_TIMEOUTED:
|
||||
case 9://ost::URLStream::errTimeout:
|
||||
return tr("Connection was timed out");
|
||||
case CURLE_INTERFACE_FAILED:
|
||||
case 10://ost::URLStream::errInterface:
|
||||
return tr("Incorrect network interface");
|
||||
default:
|
||||
return tr("Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){}
|
||||
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){
|
||||
url_stream = new ost::URLStream();
|
||||
}
|
||||
|
||||
subDownloadThread::~subDownloadThread(){
|
||||
abort = true;
|
||||
wait();
|
||||
delete url_stream;
|
||||
}
|
||||
|
||||
void subDownloadThread::run(){
|
||||
@@ -75,69 +68,38 @@ void subDownloadThread::run(){
|
||||
filePath = tmpfile->fileName();
|
||||
}
|
||||
delete tmpfile;
|
||||
FILE *f = fopen(filePath.toUtf8().data(), "wb");
|
||||
if(!f) {
|
||||
std::cerr << "couldn't open destination file" << "\n";
|
||||
QFile dest_file(filePath);
|
||||
if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){
|
||||
std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n';
|
||||
return;
|
||||
}
|
||||
CURL *curl;
|
||||
CURLcode res = (CURLcode)-1;
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
std::string c_url = url.toUtf8().data();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, c_url.c_str());
|
||||
// SSL support
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
// PROXY SUPPORT
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
int intValue = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxyType"), 0).toInt();
|
||||
if(intValue > 0) {
|
||||
// Proxy enabled
|
||||
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString();
|
||||
QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString();
|
||||
qDebug("Using proxy: %s", (IP+QString(":")+port).toUtf8().data());
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toUtf8().data());
|
||||
// Default proxy type is HTTP, we must change if it is SOCKS5
|
||||
if(intValue%2==0) {
|
||||
qDebug("Proxy is SOCKS5, not HTTP");
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
}
|
||||
// Authentication?
|
||||
if(intValue > 2) {
|
||||
qDebug("Proxy requires authentication, authenticating");
|
||||
QString username = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Username"), QString()).toString();
|
||||
QString password = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Password"), QString()).toString();
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toUtf8().data());
|
||||
}
|
||||
}
|
||||
// We have to define CURLOPT_WRITEFUNCTION or it will crash on windows
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
|
||||
// Verbose
|
||||
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
// No progress info (we don't use it)
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
||||
// Redirections
|
||||
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1);
|
||||
qDebug("Downloading %s", url.toUtf8().data());
|
||||
if(!abort)
|
||||
res = curl_easy_perform(curl);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(f);
|
||||
if(abort)
|
||||
return;
|
||||
if(res) {
|
||||
emit downloadFailureST(this, url, errorCodeToString(res));
|
||||
} else {
|
||||
emit downloadFinishedST(this, url, filePath);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Could not initialize CURL" << "\n";
|
||||
ost::URLStream::Error status = url_stream->get((const char*)url.toUtf8());
|
||||
if(status){
|
||||
// Failure
|
||||
QString error_msg = errorCodeToString((int)status);
|
||||
qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8());
|
||||
url_stream->close();
|
||||
emit downloadFailureST(this, url, error_msg);
|
||||
return;
|
||||
}
|
||||
qDebug("Downloading %s...", (const char*)url.toUtf8());
|
||||
char cbuf[1024];
|
||||
int len;
|
||||
while(!url_stream->eof()) {
|
||||
url_stream->read(cbuf, sizeof(cbuf));
|
||||
len = url_stream->gcount();
|
||||
if(len > 0)
|
||||
dest_file.write(cbuf, len);
|
||||
if(abort){
|
||||
dest_file.close();
|
||||
url_stream->close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
dest_file.close();
|
||||
url_stream->close();
|
||||
emit downloadFinishedST(this, url, filePath);
|
||||
qDebug("download completed here: %s", (const char*)filePath.toUtf8());
|
||||
}
|
||||
|
||||
/** Download Thread **/
|
||||
@@ -155,7 +117,9 @@ downloadThread::~downloadThread(){
|
||||
|
||||
void downloadThread::downloadUrl(QString url){
|
||||
QMutexLocker locker(&mutex);
|
||||
urls_queue.enqueue(url);
|
||||
if(downloading_list.contains(url)) return;
|
||||
url_list << url;
|
||||
downloading_list << url;
|
||||
if(!isRunning()){
|
||||
start();
|
||||
}else{
|
||||
@@ -168,8 +132,8 @@ void downloadThread::run(){
|
||||
if(abort)
|
||||
return;
|
||||
mutex.lock();
|
||||
if(!urls_queue.empty() && subThreads.size() < MAX_THREADS){
|
||||
QString url = urls_queue.dequeue();
|
||||
if(url_list.size() != 0){
|
||||
QString url = url_list.takeFirst();
|
||||
mutex.unlock();
|
||||
subDownloadThread *st = new subDownloadThread(0, url);
|
||||
subThreads << st;
|
||||
@@ -190,9 +154,9 @@ void downloadThread::propagateDownloadedFile(subDownloadThread* st, QString url,
|
||||
delete st;
|
||||
emit downloadFinished(url, path);
|
||||
mutex.lock();
|
||||
if(!urls_queue.empty()) {
|
||||
condition.wakeOne();
|
||||
}
|
||||
index = downloading_list.indexOf(url);
|
||||
Q_ASSERT(index != -1);
|
||||
downloading_list.removeAt(index);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -203,8 +167,8 @@ void downloadThread::propagateDownloadFailure(subDownloadThread* st, QString url
|
||||
delete st;
|
||||
emit downloadFailure(url, reason);
|
||||
mutex.lock();
|
||||
if(!urls_queue.empty()) {
|
||||
condition.wakeOne();
|
||||
}
|
||||
index = downloading_list.indexOf(url);
|
||||
Q_ASSERT(index != -1);
|
||||
downloading_list.removeAt(index);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -29,19 +29,22 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QWaitCondition>
|
||||
#include <QStringList>
|
||||
#include <curl/curl.h>
|
||||
#include <QQueue>
|
||||
|
||||
namespace ost {
|
||||
class URLStream;
|
||||
}
|
||||
|
||||
class subDownloadThread : public QThread {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QString url;
|
||||
ost::URLStream *url_stream;
|
||||
bool abort;
|
||||
|
||||
public:
|
||||
subDownloadThread(QObject *parent, QString url);
|
||||
~subDownloadThread();
|
||||
QString errorCodeToString(CURLcode status);
|
||||
QString errorCodeToString(int status);
|
||||
|
||||
signals:
|
||||
// For subthreads
|
||||
@@ -56,7 +59,8 @@ class downloadThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QQueue<QString> urls_queue;
|
||||
QStringList url_list;
|
||||
QStringList downloading_list;
|
||||
QMutex mutex;
|
||||
QWaitCondition condition;
|
||||
bool abort;
|
||||
@@ -72,13 +76,13 @@ class downloadThread : public QThread {
|
||||
~downloadThread();
|
||||
|
||||
void downloadUrl(QString url);
|
||||
void setProxy(QString IP, int port, QString username, QString password);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
protected slots:
|
||||
void propagateDownloadedFile(subDownloadThread* st, QString url, QString path);
|
||||
|
||||
void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason);
|
||||
};
|
||||
|
||||
|
||||
@@ -33,12 +33,13 @@
|
||||
#include <QTime>
|
||||
#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);
|
||||
// Setting icons
|
||||
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
|
||||
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.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")));
|
||||
actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
|
||||
actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
|
||||
@@ -46,9 +47,11 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
||||
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
|
||||
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
|
||||
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.png")));
|
||||
// Set default ratio
|
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png")));
|
||||
|
||||
// Set Download list model
|
||||
DLListModel = new QStandardItemModel(0,10);
|
||||
DLListModel = new QStandardItemModel(0,9);
|
||||
DLListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
|
||||
DLListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
|
||||
DLListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded"));
|
||||
@@ -57,17 +60,20 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
||||
DLListModel->setHeaderData(SEEDSLEECH, Qt::Horizontal, tr("Seeds/Leechs", "i.e: full/partial sources"));
|
||||
DLListModel->setHeaderData(RATIO, Qt::Horizontal, tr("Ratio"));
|
||||
DLListModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left"));
|
||||
DLListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority"));
|
||||
downloadList->setModel(DLListModel);
|
||||
DLDelegate = new DLListDelegate(downloadList);
|
||||
downloadList->setItemDelegate(DLDelegate);
|
||||
// Hide priority column
|
||||
downloadList->hideColumn(PRIORITY);
|
||||
// Hide hash column
|
||||
downloadList->hideColumn(HASH);
|
||||
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)));
|
||||
|
||||
// Load last columns width for download list
|
||||
if(!loadColWidthDLList()) {
|
||||
@@ -78,57 +84,43 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
||||
downloadList->header()->setSortIndicatorShown(true);
|
||||
// Connecting Actions to slots
|
||||
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&)));
|
||||
downloadList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(downloadList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLHoSMenu(const QPoint&)));
|
||||
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&)));
|
||||
// Actions
|
||||
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
|
||||
connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_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(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
|
||||
connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
|
||||
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(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
|
||||
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
|
||||
connect(actionHOSColProgress, SIGNAL(triggered()), this, SLOT(hideOrShowColumnProgress()));
|
||||
connect(actionHOSColDownSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnDownSpeed()));
|
||||
connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed()));
|
||||
connect(actionHOSColSeedersLeechers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSeedersLeechers()));
|
||||
connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio()));
|
||||
connect(actionHOSColEta, SIGNAL(triggered()), this, SLOT(hideOrShowColumnEta()));
|
||||
connect(actionHOSColPriority, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPriority()));
|
||||
|
||||
// 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)));
|
||||
setInfoBar(tr("Be careful, sharing copyrighted material without permission is against the law."), QString::fromUtf8("red"));
|
||||
qDebug("Download tab built");
|
||||
}
|
||||
|
||||
DownloadingTorrents::~DownloadingTorrents() {
|
||||
saveColWidthDLList();
|
||||
saveHiddenColumns();
|
||||
delete DLDelegate;
|
||||
delete DLListModel;
|
||||
}
|
||||
|
||||
void DownloadingTorrents::enablePriorityColumn(bool enable) {
|
||||
if(enable) {
|
||||
downloadList->showColumn(PRIORITY);
|
||||
} else {
|
||||
downloadList->hideColumn(PRIORITY);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadingTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
|
||||
unsigned int row = index.row();
|
||||
QString hash = getHashFromRow(row);
|
||||
emit torrentDoubleClicked(hash, false);
|
||||
emit torrentDoubleClicked(hash);
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -138,15 +130,14 @@ unsigned int DownloadingTorrents::getNbTorrentsInList() const {
|
||||
// Note: do not actually pause the torrent in BT session
|
||||
void DownloadingTorrents::pauseTorrent(QString hash) {
|
||||
int row = getRowFromHash(hash);
|
||||
if(row == -1)
|
||||
return;
|
||||
Q_ASSERT(row != -1);
|
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0));
|
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0));
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||
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")));
|
||||
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"));
|
||||
}
|
||||
|
||||
@@ -155,19 +146,29 @@ QString DownloadingTorrents::getHashFromRow(unsigned int row) const {
|
||||
return DLListModel->data(DLListModel->index(row, HASH)).toString();
|
||||
}
|
||||
|
||||
// Show torrent properties dialog
|
||||
void DownloadingTorrents::showProperties(const QModelIndex &index) {
|
||||
showPropertiesFromHash(DLListModel->data(DLListModel->index(index.row(), HASH)).toString());
|
||||
void DownloadingTorrents::setBottomTabEnabled(unsigned int index, bool b){
|
||||
if(index and !b)
|
||||
tabBottom->setCurrentIndex(0);
|
||||
tabBottom->setTabEnabled(index, b);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::showPropertiesFromHash(QString hash) {
|
||||
// Show torrent properties dialog
|
||||
void DownloadingTorrents::showProperties(const QModelIndex &index) {
|
||||
int row = index.row();
|
||||
QString hash = DLListModel->data(DLListModel->index(row, HASH)).toString();
|
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||
properties *prop = new properties(this, BTSession, h);
|
||||
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSizeAndProgress(QString)));
|
||||
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
|
||||
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
|
||||
void DownloadingTorrents::deleteTorrent(QString hash) {
|
||||
int row = getRowFromHash(hash);
|
||||
@@ -180,6 +181,27 @@ void DownloadingTorrents::deleteTorrent(QString hash) {
|
||||
emit unfinishedTorrentsNumberChanged(nbTorrents);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
qDebug("Color is %s", color.name().toUtf8().data());
|
||||
infoBar->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + info + QString::fromUtf8("</i></font>"));
|
||||
}
|
||||
|
||||
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() {
|
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
|
||||
QModelIndex index;
|
||||
@@ -219,23 +241,13 @@ void DownloadingTorrents::propertiesSelection(){
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadingTorrents::forceRecheck() {
|
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
|
||||
QModelIndex index;
|
||||
foreach(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& pos) {
|
||||
QMenu myDLLlistMenu(this);
|
||||
QModelIndex index;
|
||||
// Enable/disable pause/start action given the DL state
|
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
|
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||
QString previewProgram = settings.value(QString::fromUtf8("Preferences/general/MediaPlayer"), QString()).toString();
|
||||
bool has_pause = false, has_start = false, has_preview = false;
|
||||
foreach(index, selectedIndexes) {
|
||||
if(index.column() == NAME) {
|
||||
@@ -255,7 +267,7 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
|
||||
has_pause = true;
|
||||
}
|
||||
}
|
||||
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||
myDLLlistMenu.addAction(actionPreview_file);
|
||||
has_preview = true;
|
||||
}
|
||||
@@ -269,195 +281,14 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
|
||||
myDLLlistMenu.addAction(actionSet_download_limit);
|
||||
myDLLlistMenu.addAction(actionSet_upload_limit);
|
||||
myDLLlistMenu.addSeparator();
|
||||
myDLLlistMenu.addAction(actionForce_recheck);
|
||||
myDLLlistMenu.addSeparator();
|
||||
myDLLlistMenu.addAction(actionOpen_destination_folder);
|
||||
myDLLlistMenu.addAction(actionTorrent_Properties);
|
||||
if(BTSession->isQueueingEnabled()) {
|
||||
myDLLlistMenu.addSeparator();
|
||||
myDLLlistMenu.addAction(actionIncreasePriority);
|
||||
myDLLlistMenu.addAction(actionDecreasePriority);
|
||||
}
|
||||
myDLLlistMenu.addSeparator();
|
||||
myDLLlistMenu.addAction(actionBuy_it);
|
||||
// Call menu
|
||||
// XXX: why mapToGlobal() is not enough?
|
||||
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,35));
|
||||
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,60));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hiding Columns functions
|
||||
*/
|
||||
|
||||
// hide/show columns menu
|
||||
void DownloadingTorrents::displayDLHoSMenu(const QPoint& pos){
|
||||
QMenu hideshowColumn(this);
|
||||
hideshowColumn.setTitle(tr("Hide or Show Column"));
|
||||
int lastCol;
|
||||
if(BTSession->isQueueingEnabled()) {
|
||||
lastCol = PRIORITY;
|
||||
} else {
|
||||
lastCol = ETA;
|
||||
}
|
||||
for(int i=0; i <= lastCol; ++i) {
|
||||
hideshowColumn.addAction(getActionHoSCol(i));
|
||||
}
|
||||
// Call menu
|
||||
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,10));
|
||||
}
|
||||
|
||||
// toggle hide/show a column
|
||||
void DownloadingTorrents::hideOrShowColumn(int index) {
|
||||
unsigned int nbVisibleColumns = 0;
|
||||
unsigned int nbCols = DLListModel->columnCount();
|
||||
// Count visible columns
|
||||
for(unsigned int i=0; i<nbCols; ++i) {
|
||||
if(!downloadList->isColumnHidden(i))
|
||||
++nbVisibleColumns;
|
||||
}
|
||||
if(!downloadList->isColumnHidden(index)) {
|
||||
// User wants to hide the column
|
||||
// Is there at least one other visible column?
|
||||
if(nbVisibleColumns <= 1) return;
|
||||
// User can hide the column, do it.
|
||||
downloadList->setColumnHidden(index, true);
|
||||
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
|
||||
--nbVisibleColumns;
|
||||
} else {
|
||||
// User want to display the column
|
||||
downloadList->setColumnHidden(index, false);
|
||||
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
|
||||
++nbVisibleColumns;
|
||||
}
|
||||
//resize all others non-hidden columns
|
||||
for(unsigned int i=0; i<nbCols; ++i) {
|
||||
if(!downloadList->isColumnHidden(i)) {
|
||||
downloadList->setColumnWidth(i, (int)ceil(downloadList->columnWidth(i)+(downloadList->columnWidth(index)/nbVisibleColumns)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hidePriorityColumn(bool hide) {
|
||||
downloadList->setColumnHidden(PRIORITY, hide);
|
||||
if(hide)
|
||||
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
|
||||
else
|
||||
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
|
||||
}
|
||||
|
||||
// save the hidden columns in settings
|
||||
void DownloadingTorrents::saveHiddenColumns() {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
QStringList ishidden_list;
|
||||
short nbColumns = DLListModel->columnCount()-1;
|
||||
|
||||
for(short i=0; i<nbColumns; ++i){
|
||||
if(downloadList->isColumnHidden(i)) {
|
||||
ishidden_list << QString::fromUtf8(misc::toString(0).c_str());
|
||||
} else {
|
||||
ishidden_list << QString::fromUtf8(misc::toString(1).c_str());
|
||||
}
|
||||
}
|
||||
settings.setValue("DownloadListColsHoS", ishidden_list.join(" "));
|
||||
}
|
||||
|
||||
// load the previous settings, and hide the columns
|
||||
bool DownloadingTorrents::loadHiddenColumns() {
|
||||
bool loaded = false;
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
QString line = settings.value("DownloadListColsHoS", QString()).toString();
|
||||
QStringList ishidden_list;
|
||||
if(!line.isEmpty()) {
|
||||
ishidden_list = line.split(' ');
|
||||
if(ishidden_list.size() == DLListModel->columnCount()-1) {
|
||||
unsigned int listSize = ishidden_list.size();
|
||||
for(unsigned int i=0; i<listSize; ++i){
|
||||
downloadList->header()->resizeSection(i, ishidden_list.at(i).toInt());
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
for(int i=0; i<DLListModel->columnCount()-1; i++) {
|
||||
if(loaded && ishidden_list.at(i) == "0") {
|
||||
downloadList->setColumnHidden(i, true);
|
||||
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
|
||||
} else {
|
||||
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
|
||||
}
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnName() {
|
||||
hideOrShowColumn(NAME);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnSize() {
|
||||
hideOrShowColumn(SIZE);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnProgress() {
|
||||
hideOrShowColumn(PROGRESS);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnDownSpeed() {
|
||||
hideOrShowColumn(DLSPEED);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnUpSpeed() {
|
||||
hideOrShowColumn(UPSPEED);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnSeedersLeechers() {
|
||||
hideOrShowColumn(SEEDSLEECH);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnRatio() {
|
||||
hideOrShowColumn(RATIO);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnEta() {
|
||||
hideOrShowColumn(ETA);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::hideOrShowColumnPriority() {
|
||||
hideOrShowColumn(PRIORITY);
|
||||
}
|
||||
|
||||
// getter, return the action hide or show whose id is index
|
||||
QAction* DownloadingTorrents::getActionHoSCol(int index) {
|
||||
switch(index) {
|
||||
case NAME :
|
||||
return actionHOSColName;
|
||||
break;
|
||||
case SIZE :
|
||||
return actionHOSColSize;
|
||||
break;
|
||||
case PROGRESS :
|
||||
return actionHOSColProgress;
|
||||
break;
|
||||
case DLSPEED :
|
||||
return actionHOSColDownSpeed;
|
||||
break;
|
||||
case UPSPEED :
|
||||
return actionHOSColUpSpeed;
|
||||
break;
|
||||
case SEEDSLEECH :
|
||||
return actionHOSColSeedersLeechers;
|
||||
break;
|
||||
case RATIO :
|
||||
return actionHOSColRatio;
|
||||
break;
|
||||
case ETA :
|
||||
return actionHOSColEta;
|
||||
break;
|
||||
case PRIORITY :
|
||||
return actionHOSColPriority;
|
||||
break;
|
||||
default :
|
||||
return NULL;
|
||||
}
|
||||
void DownloadingTorrents::on_actionClearLog_triggered() {
|
||||
infoBar->clear();
|
||||
}
|
||||
|
||||
QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
|
||||
@@ -475,10 +306,62 @@ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
|
||||
return res;
|
||||
}
|
||||
|
||||
void DownloadingTorrents::updateRatio() {
|
||||
// Update ratio info
|
||||
float ratio = 1.;
|
||||
session_status sessionStatus = BTSession->getSessionStatus();
|
||||
if(sessionStatus.total_payload_download == 0) {
|
||||
if(sessionStatus.total_payload_upload == 0)
|
||||
ratio = 1.;
|
||||
else
|
||||
ratio = 10.;
|
||||
}else{
|
||||
ratio = (double)sessionStatus.total_payload_upload / (double)sessionStatus.total_payload_download;
|
||||
if(ratio > 10.)
|
||||
ratio = 10.;
|
||||
}
|
||||
LCD_Ratio->display(QString(QByteArray::number(ratio, 'f', 1)));
|
||||
if(ratio < 0.5) {
|
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/unhappy.png")));
|
||||
}else{
|
||||
if(ratio > 1.0) {
|
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/smile.png")));
|
||||
}else{
|
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// update download list accordingly
|
||||
bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
|
||||
bool added = false;
|
||||
void DownloadingTorrents::updateDlList() {
|
||||
// update global informations
|
||||
LCD_UpSpeed->display(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))); // UP LCD
|
||||
LCD_DownSpeed->display(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))); // DL LCD
|
||||
// browse handles
|
||||
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{
|
||||
QString hash = h.hash();
|
||||
int row = getRowFromHash(hash);
|
||||
@@ -486,85 +369,77 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
|
||||
qDebug("Info: Could not find filename in download list, adding it...");
|
||||
addTorrent(hash);
|
||||
row = getRowFromHash(hash);
|
||||
added = true;
|
||||
}
|
||||
Q_ASSERT(row != -1);
|
||||
// Update Priority
|
||||
if(BTSession->isQueueingEnabled()) {
|
||||
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
|
||||
if(h.is_queued()) {
|
||||
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/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);
|
||||
if(!downloadList->isColumnHidden(ETA)) {
|
||||
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"));
|
||||
return added;
|
||||
}
|
||||
}
|
||||
if(!downloadList->isColumnHidden(PROGRESS))
|
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||
// No need to update a paused torrent
|
||||
if(h.is_paused()) return added;
|
||||
if(h.is_paused()) continue;
|
||||
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
|
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||
continue;
|
||||
}
|
||||
// Parse download state
|
||||
// Setting download 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::queued_for_checking:
|
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
|
||||
setRowColor(row, QString::fromUtf8("grey"));
|
||||
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
|
||||
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{
|
||||
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"));
|
||||
}
|
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
|
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate()));
|
||||
break;
|
||||
case torrent_status::downloading:
|
||||
case torrent_status::downloading_metadata:
|
||||
if(h.download_payload_rate() > 0) {
|
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
|
||||
if(!downloadList->isColumnHidden(ETA)) {
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
|
||||
}
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
|
||||
setRowColor(row, QString::fromUtf8("green"));
|
||||
}else{
|
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole);
|
||||
if(!downloadList->isColumnHidden(ETA)) {
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||
}
|
||||
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
|
||||
}
|
||||
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()));
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||
setRowColor(row, QPalette::WindowText);
|
||||
}
|
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
|
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate()));
|
||||
break;
|
||||
default:
|
||||
if(!downloadList->isColumnHidden(ETA)) {
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||
}
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||
}
|
||||
if(!downloadList->isColumnHidden(SEEDSLEECH)) {
|
||||
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(!downloadList->isColumnHidden(RATIO)) {
|
||||
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
|
||||
}
|
||||
}catch(invalid_handle e) {}
|
||||
return added;
|
||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+QString::fromUtf8("/")+misc::toQString(h.num_peers() - h.num_seeds(), true)));
|
||||
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
|
||||
}catch(invalid_handle e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadingTorrents::addTorrent(QString hash) {
|
||||
if(BTSession->isFinished(hash)){
|
||||
BTSession->setUnfinishedTorrent(hash);
|
||||
}
|
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||
int row = getRowFromHash(hash);
|
||||
qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toUtf8(), row);
|
||||
if(row != -1) return;
|
||||
row = DLListModel->rowCount();
|
||||
// Adding torrent to download list
|
||||
@@ -574,23 +449,18 @@ void DownloadingTorrents::addTorrent(QString hash) {
|
||||
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, PROGRESS), QVariant((double)h.progress()));
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||
if(BTSession->isQueueingEnabled())
|
||||
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
|
||||
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash));
|
||||
// Pause torrent if it is
|
||||
if(h.is_paused()) {
|
||||
// Pause torrent if it was paused last time
|
||||
if(BTSession->isPaused(hash)) {
|
||||
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/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"));
|
||||
}
|
||||
++nbTorrents;
|
||||
emit unfinishedTorrentsNumberChanged(nbTorrents);
|
||||
// sort List
|
||||
sortDownloadList();
|
||||
}
|
||||
|
||||
void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) {
|
||||
@@ -639,51 +509,27 @@ void DownloadingTorrents::sortDownloadListString(int index, Qt::SortOrder sortOr
|
||||
DLListModel->removeRows(0, nbRows_old);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::toggleDownloadListSortOrder(int index) {
|
||||
Qt::SortOrder sortOrder = Qt::AscendingOrder;
|
||||
qDebug("Toggling column sort order");
|
||||
if(downloadList->header()->sortIndicatorSection() == index) {
|
||||
sortOrder = (Qt::SortOrder)!(bool)downloadList->header()->sortIndicatorOrder();
|
||||
void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder startSortOrder, bool fromLoadColWidth) {
|
||||
qDebug("Called sort download list");
|
||||
static Qt::SortOrder sortOrder = startSortOrder;
|
||||
if(!fromLoadColWidth && downloadList->header()->sortIndicatorSection() == index) {
|
||||
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;
|
||||
if(sortOrder == Qt::AscendingOrder)
|
||||
sortOrderLetter = QString::fromUtf8("a");
|
||||
else
|
||||
sortOrderLetter = QString::fromUtf8("d");
|
||||
settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter);
|
||||
}
|
||||
|
||||
void DownloadingTorrents::sortProgressColumn(QTorrentHandle& h) {
|
||||
QString hash = h.hash();
|
||||
int index = downloadList->header()->sortIndicatorSection();
|
||||
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();
|
||||
if(fromLoadColWidth) {
|
||||
// XXX: Why is this needed?
|
||||
if(sortOrder == Qt::DescendingOrder)
|
||||
downloadList->header()->setSortIndicator(index, Qt::AscendingOrder);
|
||||
else
|
||||
downloadList->header()->setSortIndicator(index, Qt::DescendingOrder);
|
||||
} else {
|
||||
downloadList->header()->setSortIndicator(index, sortOrder);
|
||||
}
|
||||
@@ -692,13 +538,23 @@ void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder sortOrder) {
|
||||
case ETA:
|
||||
case UPSPEED:
|
||||
case DLSPEED:
|
||||
case PRIORITY:
|
||||
case PROGRESS:
|
||||
sortDownloadListFloat(index, sortOrder);
|
||||
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:
|
||||
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
|
||||
@@ -707,26 +563,11 @@ void DownloadingTorrents::saveColWidthDLList() const{
|
||||
qDebug("Saving columns width in download list");
|
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||
QStringList width_list;
|
||||
QStringList new_width_list;
|
||||
short nbColumns = DLListModel->columnCount()-1;
|
||||
QString line = settings.value("DownloadListColsWidth", QString()).toString();
|
||||
if(!line.isEmpty()) {
|
||||
width_list = line.split(' ');
|
||||
unsigned int nbColumns = DLListModel->columnCount()-1;
|
||||
for(unsigned int i=0; i<nbColumns; ++i) {
|
||||
width_list << misc::toQString(downloadList->columnWidth(i));
|
||||
}
|
||||
for(short i=0; i<nbColumns; ++i){
|
||||
if(downloadList->columnWidth(i)<1 && width_list.size() == DLListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
|
||||
// load the former width
|
||||
new_width_list << width_list.at(i);
|
||||
} else if(downloadList->columnWidth(i)>=1) {
|
||||
// usual case, save the current width
|
||||
new_width_list << QString::fromUtf8(misc::toString(downloadList->columnWidth(i)).c_str());
|
||||
} else {
|
||||
// default width
|
||||
downloadList->resizeColumnToContents(i);
|
||||
new_width_list << QString::fromUtf8(misc::toString(downloadList->columnWidth(i)).c_str());
|
||||
}
|
||||
}
|
||||
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), new_width_list.join(QString::fromUtf8(" ")));
|
||||
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), width_list.join(QString::fromUtf8(" ")));
|
||||
qDebug("Download list columns width saved");
|
||||
}
|
||||
|
||||
@@ -747,13 +588,7 @@ bool DownloadingTorrents::loadColWidthDLList() {
|
||||
for(unsigned int i=0; i<listSize; ++i) {
|
||||
downloadList->header()->resizeSection(i, width_list.at(i).toInt());
|
||||
}
|
||||
qDebug("Download list columns width loaded");
|
||||
return true;
|
||||
}
|
||||
|
||||
void DownloadingTorrents::loadLastSortedColumn() {
|
||||
// Loading last sorted column
|
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||
QString sortedCol = settings.value(QString::fromUtf8("DownloadListSortedCol"), QString()).toString();
|
||||
if(!sortedCol.isEmpty()) {
|
||||
Qt::SortOrder sortOrder;
|
||||
@@ -763,8 +598,55 @@ void DownloadingTorrents::loadLastSortedColumn() {
|
||||
sortOrder = Qt::AscendingOrder;
|
||||
sortedCol = sortedCol.left(sortedCol.size()-1);
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
@@ -772,7 +654,13 @@ void DownloadingTorrents::updateFileSizeAndProgress(QString hash) {
|
||||
Q_ASSERT(row != -1);
|
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||
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
|
||||
@@ -794,3 +682,7 @@ int DownloadingTorrents::getRowFromHash(QString hash) const{
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void DownloadingTorrents::displayDownloadingUrlInfos(QString url) {
|
||||
setInfoBar(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url), QPalette::WindowText);
|
||||
}
|
||||
|
||||
@@ -38,11 +38,9 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
||||
bittorrent *BTSession;
|
||||
DLListDelegate *DLDelegate;
|
||||
QStandardItemModel *DLListModel;
|
||||
bool delayedSorting;
|
||||
unsigned int nbTorrents;
|
||||
void hideOrShowColumn(int index);
|
||||
bool loadHiddenColumns();
|
||||
void saveHiddenColumns();
|
||||
QAction* getActionHoSCol(int index);
|
||||
Qt::SortOrder delayedSortingOrder;
|
||||
|
||||
public:
|
||||
DownloadingTorrents(QObject *parent, bittorrent *BTSession);
|
||||
@@ -53,47 +51,46 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
||||
QString getHashFromRow(unsigned int row) const;
|
||||
QStringList getSelectedTorrents(bool only_one=false) const;
|
||||
unsigned int getNbTorrentsInList() const;
|
||||
void enablePriorityColumn(bool enable);
|
||||
|
||||
signals:
|
||||
void unfinishedTorrentsNumberChanged(unsigned int);
|
||||
void torrentDoubleClicked(QString hash, bool finished);
|
||||
void torrentDoubleClicked(QString hash);
|
||||
void torrentFinished(QString hash);
|
||||
|
||||
protected slots:
|
||||
void addLogPeerBlocked(QString);
|
||||
void addFastResumeRejectedAlert(QString);
|
||||
void addUrlSeedError(QString url, QString msg);
|
||||
void on_actionSet_download_limit_triggered();
|
||||
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
||||
void on_actionSet_upload_limit_triggered();
|
||||
void displayDLListMenu(const QPoint& pos);
|
||||
void displayDLHoSMenu(const QPoint&);
|
||||
void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder);
|
||||
void toggleDownloadListSortOrder(int index);
|
||||
void on_actionClearLog_triggered();
|
||||
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 sortDownloadListString(int index, Qt::SortOrder sortOrder);
|
||||
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 displayDownloadingUrlInfos(QString url);
|
||||
void showProperties(const QModelIndex &index);
|
||||
void hideOrShowColumnName();
|
||||
void hideOrShowColumnSize();
|
||||
void hideOrShowColumnProgress();
|
||||
void hideOrShowColumnDownSpeed();
|
||||
void hideOrShowColumnUpSpeed();
|
||||
void hideOrShowColumnSeedersLeechers();
|
||||
void hideOrShowColumnRatio();
|
||||
void hideOrShowColumnEta();
|
||||
void hideOrShowColumnPriority();
|
||||
void forceRecheck();
|
||||
|
||||
public slots:
|
||||
bool updateTorrent(QTorrentHandle h);
|
||||
void updateDlList();
|
||||
void setInfoBar(QString info, QColor color=QPalette::WindowText);
|
||||
void pauseTorrent(QString hash);
|
||||
void resumeTorrent(QString hash);
|
||||
void updateRatio();
|
||||
void deleteTorrent(QString hash);
|
||||
void setBottomTabEnabled(unsigned int index, bool b);
|
||||
void propertiesSelection();
|
||||
void sortProgressColumnDelayed();
|
||||
void updateFileSizeAndProgress(QString hash);
|
||||
void showPropertiesFromHash(QString hash);
|
||||
void hidePriorityColumn(bool hide);
|
||||
void sortProgressColumn(QTorrentHandle& h);
|
||||
void loadLastSortedColumn();
|
||||
void addTorrent(QString hash);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
#include <QDropEvent>
|
||||
#include <QInputDialog>
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
#include <Magick++.h>
|
||||
using namespace Magick;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZZIP
|
||||
#include <zzip/zzip.h>
|
||||
#endif
|
||||
@@ -245,13 +250,11 @@ void engineSelectDlg::setRowColor(int row, QString color){
|
||||
bool engineSelectDlg::checkInstalled(QString plugin_name) const {
|
||||
QProcess nova;
|
||||
QStringList params;
|
||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
||||
params << "--supported_engines";
|
||||
nova.start("python", params, QIODevice::ReadOnly);
|
||||
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly);
|
||||
nova.waitForStarted();
|
||||
nova.waitForFinished();
|
||||
QByteArray result = nova.readAll();
|
||||
result = result.replace("\r", "");
|
||||
result = result.replace("\n", "");
|
||||
QList<QByteArray> plugins_list = result.split(',');
|
||||
return plugins_list.contains(plugin_name.toUtf8());
|
||||
@@ -277,13 +280,11 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
|
||||
QStringList params;
|
||||
// Ask nova core for the supported search engines
|
||||
QProcess nova;
|
||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
||||
params << "--supported_engines";
|
||||
nova.start("python", params, QIODevice::ReadOnly);
|
||||
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly);
|
||||
nova.waitForStarted();
|
||||
nova.waitForFinished();
|
||||
QByteArray result = nova.readAll();
|
||||
result = result.replace("\r", "");
|
||||
result = result.replace("\n", "");
|
||||
qDebug("read: %s", result.data());
|
||||
QByteArray e;
|
||||
@@ -294,13 +295,11 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
|
||||
installed_engines[en] = old_engines.value(en, true);
|
||||
}
|
||||
params.clear();
|
||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
||||
params << "--supported_engines_infos";
|
||||
nova.start("python", params, QIODevice::ReadOnly);
|
||||
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly);
|
||||
nova.waitForStarted();
|
||||
nova.waitForFinished();
|
||||
result = nova.readAll();
|
||||
result = result.replace("\r", "");
|
||||
result = result.replace("\n", "");
|
||||
qDebug("read: %s", result.data());
|
||||
unsigned int i = 0;
|
||||
@@ -606,6 +605,20 @@ void engineSelectDlg::processDownloadedFile(QString url, QString filePath) {
|
||||
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
|
||||
// Icon downloaded
|
||||
QImage fileIcon;
|
||||
#ifdef HAVE_MAGICK
|
||||
try{
|
||||
QFile::copy(filePath, filePath+".ico");
|
||||
Image image(QDir::cleanPath(filePath+".ico").toUtf8().data());
|
||||
// Convert to PNG since we can't read ICO format
|
||||
image.magick("PNG");
|
||||
// Resize to 16x16px
|
||||
image.sample(Geometry(16, 16));
|
||||
image.write(filePath.toUtf8().data());
|
||||
QFile::remove(filePath+".ico");
|
||||
}catch(Magick::Exception &error_){
|
||||
qDebug("favicon conversion to PNG failure: %s", error_.what());
|
||||
}
|
||||
#endif
|
||||
if(fileIcon.load(filePath)) {
|
||||
QList<QTreeWidgetItem*> items = findItemsWithUrl(url);
|
||||
QTreeWidgetItem *item;
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora & Christophe Dumez
|
||||
* <ishan@qbittorrent.org>, <chris@qbittorrent.org>
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "eventmanager.h"
|
||||
#include "bittorrent.h"
|
||||
#include <QDebug>
|
||||
|
||||
EventManager::EventManager(QObject *parent, bittorrent *BTSession)
|
||||
: QObject(parent), BTSession(BTSession)
|
||||
{
|
||||
}
|
||||
|
||||
QList<QVariantMap> EventManager::getEventList() const {
|
||||
return event_list.values();
|
||||
}
|
||||
|
||||
void EventManager::addedTorrent(QTorrentHandle& h)
|
||||
{
|
||||
modifiedTorrent(h);
|
||||
}
|
||||
|
||||
void EventManager::deletedTorrent(QString hash)
|
||||
{
|
||||
event_list.remove(hash);
|
||||
}
|
||||
|
||||
void EventManager::modifiedTorrent(QTorrentHandle h)
|
||||
{
|
||||
QString hash = h.hash();
|
||||
QVariantMap event;
|
||||
|
||||
if(h.is_paused()) {
|
||||
event["state"] = QVariant("paused");
|
||||
} else {
|
||||
if(BTSession->isQueueingEnabled() && h.is_queued()) {
|
||||
event["state"] = QVariant("queued");
|
||||
} else {
|
||||
switch(h.state())
|
||||
{
|
||||
case torrent_status::finished:
|
||||
case torrent_status::seeding:
|
||||
event["state"] = QVariant("seeding");
|
||||
break;
|
||||
case torrent_status::checking_files:
|
||||
case torrent_status::queued_for_checking:
|
||||
event["state"] = QVariant("checking");
|
||||
break;
|
||||
case torrent_status::allocating:
|
||||
case torrent_status::downloading:
|
||||
case torrent_status::downloading_metadata:
|
||||
if(h.download_payload_rate() > 0)
|
||||
event["state"] = QVariant("downloading");
|
||||
else
|
||||
event["state"] = QVariant("stalled");
|
||||
break;
|
||||
default:
|
||||
qDebug("No status, should not happen!!! status is %d", h.state());
|
||||
event["state"] = QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
event["name"] = QVariant(h.name());
|
||||
event["size"] = QVariant((qlonglong)h.actual_size());
|
||||
if(!h.is_seed()) {
|
||||
event["progress"] = QVariant(h.progress());
|
||||
event["dlspeed"] = QVariant(h.download_payload_rate());
|
||||
if(BTSession->isQueueingEnabled()) {
|
||||
event["priority"] = QVariant(h.queue_position());
|
||||
} else {
|
||||
event["priority"] = -1;
|
||||
}
|
||||
}
|
||||
event["upspeed"] = QVariant(h.upload_payload_rate());
|
||||
event["seed"] = QVariant(h.is_seed());
|
||||
event["hash"] = QVariant(hash);
|
||||
event_list[hash] = event;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora & Christophe Dumez
|
||||
* <ishan@qbittorrent.org>, <chris@qbittorrent.org>
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EVENTMANAGER_H
|
||||
#define EVENTMANAGER_H
|
||||
|
||||
#include "qtorrenthandle.h"
|
||||
#include <QHash>
|
||||
#include <QVariant>
|
||||
|
||||
struct bittorrent;
|
||||
|
||||
class EventManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QHash<QString, QVariantMap> event_list;
|
||||
bittorrent* BTSession;
|
||||
|
||||
protected:
|
||||
void update(QVariantMap event);
|
||||
|
||||
public:
|
||||
EventManager(QObject *parent, bittorrent* BTSession);
|
||||
QList<QVariantMap> getEventList() const;
|
||||
|
||||
public slots:
|
||||
void addedTorrent(QTorrentHandle& h);
|
||||
void deletedTorrent(QString hash);
|
||||
void modifiedTorrent(QTorrentHandle h);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,388 +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.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#ifndef FILTERPARSERTHREAD_H
|
||||
#define FILTERPARSERTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QFile>
|
||||
#include <QDataStream>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/ip_filter.hpp>
|
||||
|
||||
using namespace libtorrent;
|
||||
using namespace std;
|
||||
|
||||
// P2B Stuff
|
||||
#include <string.h>
|
||||
#ifdef Q_WS_WIN
|
||||
#include <Winsock2.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
// End of P2B stuff
|
||||
|
||||
class FilterParserThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
session *s;
|
||||
ip_filter filter;
|
||||
bool abort;
|
||||
QString filePath;
|
||||
|
||||
protected:
|
||||
void run(){
|
||||
qDebug("Processing filter file");
|
||||
if(filePath.endsWith(".dat", Qt::CaseInsensitive)) {
|
||||
// eMule DAT file
|
||||
parseDATFilterFile(filePath);
|
||||
} else {
|
||||
if(filePath.endsWith(".p2p", Qt::CaseInsensitive)) {
|
||||
// PeerGuardian p2p file
|
||||
parseP2PFilterFile(filePath);
|
||||
} else {
|
||||
if(filePath.endsWith(".p2p", Qt::CaseInsensitive)) {
|
||||
// PeerGuardian p2p file
|
||||
parseP2BFilterFile(filePath);
|
||||
} else {
|
||||
// Default: eMule DAT format
|
||||
parseDATFilterFile(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
s->set_ip_filter(filter);
|
||||
qDebug("IP Filter thread: finished parsing, filter applied");
|
||||
}
|
||||
|
||||
public:
|
||||
FilterParserThread(QObject* parent, session *s) : QThread(parent), s(s), abort(false) {
|
||||
|
||||
}
|
||||
|
||||
~FilterParserThread(){
|
||||
abort = true;
|
||||
wait();
|
||||
}
|
||||
|
||||
// Parser for eMule ip filter in DAT format
|
||||
void parseDATFilterFile(QString filePath) {
|
||||
const QRegExp is_ipv6(QString::fromUtf8("^[0-9a-f]{4}(:[0-9a-f]{4}){7}$"), Qt::CaseInsensitive, QRegExp::RegExp);
|
||||
const QRegExp is_ipv4(QString::fromUtf8("^(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))(\\.(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))){3}$"), Qt::CaseInsensitive, QRegExp::RegExp);
|
||||
QString strStartIP, strEndIP;
|
||||
bool IPv4 = true;
|
||||
QFile file(filePath);
|
||||
if (file.exists()){
|
||||
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
unsigned int nbLine = 0;
|
||||
while (!file.atEnd() && !abort) {
|
||||
++nbLine;
|
||||
QByteArray line = file.readLine();
|
||||
// Ignoring empty lines
|
||||
line = line.trimmed();
|
||||
if(line.isEmpty()) continue;
|
||||
// Ignoring commented lines
|
||||
if(line.startsWith('#') || line.startsWith("//")) continue;
|
||||
// Line is not commented
|
||||
QList<QByteArray> partsList = line.split(',');
|
||||
unsigned int nbElem = partsList.size();
|
||||
// IP Range can be splitted by a dash or a comma...
|
||||
// Check if there is a dash in first part
|
||||
QByteArray firstPart = partsList.at(0);
|
||||
int nbAccess = 0;
|
||||
if(firstPart.contains('-')) {
|
||||
// Range is splitted by a dash
|
||||
QList<QByteArray> IPs = firstPart.split('-');
|
||||
if(IPs.size() != 2) {
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
continue;
|
||||
}
|
||||
strStartIP = IPs.at(0).trimmed();
|
||||
strEndIP = IPs.at(1).trimmed();
|
||||
// Check if IPs are correct
|
||||
if(strStartIP.contains(is_ipv4) && strEndIP.contains(is_ipv4)) {
|
||||
IPv4 = true;
|
||||
} else {
|
||||
if(strStartIP.contains(is_ipv6) && strEndIP.contains(is_ipv6)) {
|
||||
IPv4 = false;
|
||||
} else {
|
||||
// Could not determine IP format
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Check if there is an access value (apparently not mandatory)
|
||||
if(nbElem > 1) {
|
||||
// There is possibly one
|
||||
bool ok;
|
||||
nbAccess = partsList.at(1).trimmed().toInt(&ok);
|
||||
if(!ok){
|
||||
nbAccess = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Range is probably splitted by a comma
|
||||
unsigned int nbElem = partsList.size();
|
||||
if(nbElem > 1) {
|
||||
strStartIP = firstPart.trimmed();
|
||||
strEndIP = partsList.at(1).trimmed();
|
||||
// Check if IPs are correct
|
||||
if(strStartIP.contains(is_ipv4) && strEndIP.contains(is_ipv4)) {
|
||||
IPv4 = true;
|
||||
} else {
|
||||
if(strStartIP.contains(is_ipv6) && strEndIP.contains(is_ipv6)) {
|
||||
IPv4 = false;
|
||||
} else {
|
||||
// Could not determine IP format
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Check if there is an access value (apparently not mandatory)
|
||||
if(nbElem > 2) {
|
||||
// There is possibly one
|
||||
bool ok;
|
||||
nbAccess = partsList.at(2).trimmed().toInt(&ok);
|
||||
if(!ok){
|
||||
nbAccess = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(nbAccess > 127) {
|
||||
// Ignoring this rule because access value is too high
|
||||
continue;
|
||||
}
|
||||
// Now Add to the filter
|
||||
QStringList IP;
|
||||
if(IPv4) {
|
||||
//IPv4 addresses
|
||||
IP = strStartIP.split('.');
|
||||
address_v4 start((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
|
||||
IP = strEndIP.split('.');
|
||||
address_v4 last((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
|
||||
// Apply to bittorrent session
|
||||
filter.add_rule(start, last, ip_filter::blocked);
|
||||
} else {
|
||||
// IPv6, ex : 1fff:0000:0a88:85a3:0000:0000:ac1f:8001
|
||||
IP = strStartIP.split(':');
|
||||
address_v6 start = address_v6::from_string(strStartIP.remove(':', 0).toUtf8().data());
|
||||
IP = strEndIP.split(':');
|
||||
address_v6 last = address_v6::from_string(strEndIP.remove(':', 0).toUtf8().data());
|
||||
// Apply to bittorrent session
|
||||
filter.add_rule(start, last, ip_filter::blocked);
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Parser for PeerGuardian ip filter in p2p format
|
||||
void parseP2PFilterFile(QString filePath) {
|
||||
const QRegExp is_ipv4(QString::fromUtf8("^(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))(\\.(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))){3}$"), Qt::CaseInsensitive, QRegExp::RegExp);
|
||||
QFile file(filePath);
|
||||
QStringList IP;
|
||||
if (file.exists()){
|
||||
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
unsigned int nbLine = 0;
|
||||
while (!file.atEnd() && !abort) {
|
||||
++nbLine;
|
||||
QByteArray line = file.readLine();
|
||||
// Ignoring empty lines
|
||||
line = line.trimmed();
|
||||
if(line.isEmpty()) continue;
|
||||
// Ignoring commented lines
|
||||
if(line.startsWith('#') || line.startsWith("//")) continue;
|
||||
// Line is not commented
|
||||
QList<QByteArray> partsList = line.split(':');
|
||||
if(partsList.size() < 2){
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
continue;
|
||||
}
|
||||
// Get IP range
|
||||
QList<QByteArray> IPs = partsList.last().split('-');
|
||||
if(IPs.size() != 2) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
continue;
|
||||
}
|
||||
QString strStartIP = IPs.at(0).trimmed();
|
||||
QString strEndIP = IPs.at(1).trimmed();
|
||||
// Check IPs format (IPv4 only)
|
||||
if(strStartIP.contains(is_ipv4) && strEndIP.contains(is_ipv4)) {
|
||||
// IPv4
|
||||
IP = strStartIP.split('.');
|
||||
address_v4 start((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
|
||||
IP = strEndIP.split('.');
|
||||
address_v4 last((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
|
||||
// Apply to bittorrent session
|
||||
filter.add_rule(start, last, ip_filter::blocked);
|
||||
} else {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
int getlineInStream(QDataStream& stream, string& name, char delim) {
|
||||
char c;
|
||||
int total_read = 0;
|
||||
int read;
|
||||
do {
|
||||
read = stream.readRawData(&c, 1);
|
||||
total_read += read;
|
||||
if(read > 0) {
|
||||
if(c != delim) {
|
||||
name += c;
|
||||
} else {
|
||||
// Delim found
|
||||
return total_read;
|
||||
}
|
||||
}
|
||||
} while(read > 0);
|
||||
return total_read;
|
||||
}
|
||||
|
||||
// Parser for PeerGuardian ip filter in p2p format
|
||||
void parseP2BFilterFile(QString filePath) {
|
||||
QFile file(filePath);
|
||||
if (file.exists()){
|
||||
if(!file.open(QIODevice::ReadOnly)){
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
QDataStream stream(&file);
|
||||
// Read header
|
||||
char buf[7];
|
||||
unsigned char version;
|
||||
if(
|
||||
!stream.readRawData(buf, sizeof(buf)) ||
|
||||
memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7) ||
|
||||
!stream.readRawData((char*)&version, sizeof(version))
|
||||
) {
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
|
||||
if(version==1 || version==2) {
|
||||
qDebug ("p2b version 1 or 2");
|
||||
unsigned int start, end;
|
||||
|
||||
string name;
|
||||
while(getlineInStream(stream, name, '\0') && !abort) {
|
||||
if(
|
||||
!stream.readRawData((char*)&start, sizeof(start)) ||
|
||||
!stream.readRawData((char*)&end, sizeof(end))
|
||||
) {
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
// Network byte order to Host byte order
|
||||
// asio address_v4 contructor expects it
|
||||
// that way
|
||||
address_v4 first(ntohl(start));
|
||||
address_v4 last(ntohl(end));
|
||||
// Apply to bittorrent session
|
||||
filter.add_rule(first, last, ip_filter::blocked);
|
||||
}
|
||||
}
|
||||
else if(version==3) {
|
||||
qDebug ("p2b version 3");
|
||||
unsigned int namecount;
|
||||
if(!stream.readRawData((char*)&namecount, sizeof(namecount))) {
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
namecount=ntohl(namecount);
|
||||
// Reading names although, we don't really care about them
|
||||
for(unsigned int i=0; i<namecount; i++) {
|
||||
string name;
|
||||
if(!getlineInStream(stream, name, '\0')) {
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
if(abort) return;
|
||||
}
|
||||
// Reading the ranges
|
||||
unsigned int rangecount;
|
||||
if(!stream.readRawData((char*)&rangecount, sizeof(rangecount))) {
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
rangecount=ntohl(rangecount);
|
||||
|
||||
unsigned int name, start, end;
|
||||
|
||||
for(unsigned int i=0; i<rangecount; i++) {
|
||||
if(
|
||||
!stream.readRawData((char*)&name, sizeof(name)) ||
|
||||
!stream.readRawData((char*)&start, sizeof(start)) ||
|
||||
!stream.readRawData((char*)&end, sizeof(end))
|
||||
) {
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
// Network byte order to Host byte order
|
||||
// asio address_v4 contructor expects it
|
||||
// that way
|
||||
address_v4 first(ntohl(start));
|
||||
address_v4 last(ntohl(end));
|
||||
// Apply to bittorrent session
|
||||
filter.add_rule(first, last, ip_filter::blocked);
|
||||
if(abort) return;
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Process ip filter file
|
||||
// Supported formats:
|
||||
// * eMule IP list (DAT): http://wiki.phoenixlabs.org/wiki/DAT_Format
|
||||
// * PeerGuardian Text (P2P): http://wiki.phoenixlabs.org/wiki/P2P_Format
|
||||
// * PeerGuardian Binary (P2B): http://wiki.phoenixlabs.org/wiki/P2B_Format
|
||||
void processFilterFile(QString _filePath){
|
||||
if(isRunning()) {
|
||||
// Already parsing a filter, abort first
|
||||
abort = true;
|
||||
wait();
|
||||
}
|
||||
abort = false;
|
||||
filePath = _filePath;
|
||||
// Run it
|
||||
start();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora
|
||||
* ishanarora@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "httpconnection.h"
|
||||
#include "httpserver.h"
|
||||
#include "eventmanager.h"
|
||||
#include "json.h"
|
||||
#include <QTcpSocket>
|
||||
#include <QDateTime>
|
||||
#include <QStringList>
|
||||
#include <QHttpRequestHeader>
|
||||
#include <QHttpResponseHeader>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
|
||||
: QObject(parent), socket(socket), parent(parent)
|
||||
{
|
||||
socket->setParent(this);
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(read()));
|
||||
connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater()));
|
||||
}
|
||||
|
||||
HttpConnection::~HttpConnection()
|
||||
{
|
||||
delete socket;
|
||||
}
|
||||
|
||||
void HttpConnection::processDownloadedFile(QString url, QString file_path) {
|
||||
qDebug("URL %s successfully downloaded !", (const char*)url.toUtf8());
|
||||
emit torrentReadyToBeDownloaded(file_path, false, url, false);
|
||||
}
|
||||
|
||||
void HttpConnection::handleDownloadFailure(QString url, QString reason) {
|
||||
std::cerr << "Could not download " << (const char*)url.toUtf8() << ", reason: " << (const char*)reason.toUtf8() << "\n";
|
||||
}
|
||||
|
||||
void HttpConnection::read()
|
||||
{
|
||||
QByteArray input = socket->readAll();
|
||||
/*qDebug(" -------");
|
||||
qDebug("|REQUEST|");
|
||||
qDebug(" -------"); */
|
||||
//qDebug("%s", input.toAscii().constData());
|
||||
if(input.size() > 100000) {
|
||||
qDebug("Request too big");
|
||||
generator.setStatusLine(400, "Bad Request");
|
||||
write();
|
||||
return;
|
||||
}
|
||||
parser.write(input);
|
||||
if(parser.isError())
|
||||
{
|
||||
generator.setStatusLine(400, "Bad Request");
|
||||
write();
|
||||
}
|
||||
else
|
||||
if (parser.isParsable())
|
||||
respond();
|
||||
}
|
||||
|
||||
void HttpConnection::write()
|
||||
{
|
||||
QByteArray output = generator.toByteArray();
|
||||
/*qDebug(" --------");
|
||||
qDebug("|RESPONSE|");
|
||||
qDebug(" --------");
|
||||
qDebug()<<output;*/
|
||||
socket->write(output);
|
||||
socket->disconnectFromHost();
|
||||
}
|
||||
|
||||
void HttpConnection::respond()
|
||||
{
|
||||
//qDebug("Respond called");
|
||||
QStringList auth = parser.value("Authorization").split(" ", QString::SkipEmptyParts);
|
||||
if (auth.size() != 2 || QString::compare(auth[0], "Basic", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth[1].toUtf8()))
|
||||
{
|
||||
generator.setStatusLine(401, "Unauthorized");
|
||||
generator.setValue("WWW-Authenticate", "Basic realm=\"you know what\"");
|
||||
write();
|
||||
return;
|
||||
}
|
||||
QString url = parser.url();
|
||||
QStringList list = url.split('/', QString::SkipEmptyParts);
|
||||
if (list.contains(".") || list.contains(".."))
|
||||
{
|
||||
respondNotFound();
|
||||
return;
|
||||
}
|
||||
if (list.size() == 0)
|
||||
list.append("index.html");
|
||||
if (list.size() == 2)
|
||||
{
|
||||
if (list[0] == "json")
|
||||
{
|
||||
if (list[1] == "events")
|
||||
{
|
||||
respondJson();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (list[0] == "command")
|
||||
{
|
||||
QString command = list[1];
|
||||
respondCommand(command);
|
||||
generator.setStatusLine(200, "OK");
|
||||
write();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (list[0] == "images")
|
||||
list[0] = "Icons";
|
||||
else
|
||||
list.prepend("webui");
|
||||
url = ":/" + list.join("/");
|
||||
QFile file(url);
|
||||
if(!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
respondNotFound();
|
||||
return;
|
||||
}
|
||||
QString ext = list.last();
|
||||
int index = ext.lastIndexOf('.') + 1;
|
||||
if (index > 0)
|
||||
ext.remove(0, index);
|
||||
else
|
||||
ext.clear();
|
||||
QByteArray data = file.readAll();
|
||||
generator.setStatusLine(200, "OK");
|
||||
generator.setContentTypeByExt(ext);
|
||||
generator.setMessage(data);
|
||||
write();
|
||||
}
|
||||
|
||||
void HttpConnection::respondNotFound()
|
||||
{
|
||||
generator.setStatusLine(404, "File not found");
|
||||
write();
|
||||
}
|
||||
|
||||
void HttpConnection::respondJson()
|
||||
{
|
||||
EventManager* manager = parent->eventManager();
|
||||
QString string = json::toJson(manager->getEventList());
|
||||
generator.setStatusLine(200, "OK");
|
||||
generator.setContentTypeByExt("js");
|
||||
generator.setMessage(string);
|
||||
write();
|
||||
}
|
||||
|
||||
void HttpConnection::respondCommand(QString command)
|
||||
{
|
||||
if(command == "download")
|
||||
{
|
||||
QString urls = parser.post("urls");
|
||||
QStringList list = urls.split('\n');
|
||||
foreach(QString url, list){
|
||||
url = url.trimmed();
|
||||
if(!url.isEmpty()){
|
||||
qDebug("Downloading url: %s", (const char*)url.toUtf8());
|
||||
emit UrlReadyToBeDownloaded(url);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(command == "upload")
|
||||
{
|
||||
QByteArray torrentfile = parser.torrent();
|
||||
// XXX: Trick to get a unique filename
|
||||
QString filePath;
|
||||
QTemporaryFile *tmpfile = new QTemporaryFile();
|
||||
if (tmpfile->open()) {
|
||||
filePath = tmpfile->fileName();
|
||||
}
|
||||
delete tmpfile;
|
||||
// write it to HD
|
||||
QFile torrent(filePath);
|
||||
if(torrent.open(QIODevice::WriteOnly)) {
|
||||
torrent.write(torrentfile);
|
||||
torrent.close();
|
||||
}
|
||||
emit torrentReadyToBeDownloaded(filePath, false, QString(), false);
|
||||
return;
|
||||
}
|
||||
if(command == "resumeall") {
|
||||
emit resumeAllTorrents();
|
||||
return;
|
||||
}
|
||||
if(command == "pauseall") {
|
||||
emit pauseAllTorrents();
|
||||
return;
|
||||
}
|
||||
if(command == "resume") {
|
||||
emit resumeTorrent(parser.post("hash"));
|
||||
return;
|
||||
}
|
||||
if(command == "pause") {
|
||||
emit pauseTorrent(parser.post("hash"));
|
||||
return;
|
||||
}
|
||||
if(command == "delete") {
|
||||
emit deleteTorrent(parser.post("hash"), false);
|
||||
return;
|
||||
}
|
||||
if(command == "deletePerm") {
|
||||
emit deleteTorrent(parser.post("hash"), true);
|
||||
return;
|
||||
}
|
||||
if(command == "increasePrio") {
|
||||
emit increasePrioTorrent(parser.post("hash"));
|
||||
return;
|
||||
}
|
||||
if(command == "decreasePrio") {
|
||||
emit decreasePrioTorrent(parser.post("hash"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora
|
||||
* ishanarora@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HTTPCONNECTION_H
|
||||
#define HTTPCONNECTION_H
|
||||
|
||||
#include "httprequestparser.h"
|
||||
#include "httpresponsegenerator.h"
|
||||
#include <QObject>
|
||||
|
||||
class QTcpSocket;
|
||||
class HttpServer;
|
||||
|
||||
class HttpConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QTcpSocket *socket;
|
||||
HttpServer *parent;
|
||||
|
||||
protected:
|
||||
HttpRequestParser parser;
|
||||
HttpResponseGenerator generator;
|
||||
|
||||
protected slots:
|
||||
void write();
|
||||
virtual void respond();
|
||||
void respondJson();
|
||||
void respondCommand(QString command);
|
||||
void respondNotFound();
|
||||
void processDownloadedFile(QString, QString);
|
||||
void handleDownloadFailure(QString, QString);
|
||||
|
||||
public:
|
||||
HttpConnection(QTcpSocket *socket, HttpServer *parent);
|
||||
~HttpConnection();
|
||||
|
||||
private slots:
|
||||
void read();
|
||||
|
||||
signals:
|
||||
void UrlReadyToBeDownloaded(QString url);
|
||||
void torrentReadyToBeDownloaded(QString, bool, QString, bool);
|
||||
void deleteTorrent(QString hash, bool permanently);
|
||||
void resumeTorrent(QString hash);
|
||||
void pauseTorrent(QString hash);
|
||||
void increasePrioTorrent(QString hash);
|
||||
void decreasePrioTorrent(QString hash);
|
||||
void resumeAllTorrents();
|
||||
void pauseAllTorrents();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora
|
||||
* ishanarora@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "httprequestparser.h"
|
||||
#include <QUrl>
|
||||
#include <QDebug>
|
||||
|
||||
HttpRequestParser::HttpRequestParser()
|
||||
{
|
||||
headerDone = false;
|
||||
messageDone = false;
|
||||
error = false;
|
||||
}
|
||||
|
||||
HttpRequestParser::~HttpRequestParser()
|
||||
{
|
||||
}
|
||||
|
||||
bool HttpRequestParser::isParsable() const
|
||||
{
|
||||
return !error && headerDone && isValid() && (messageDone || !hasContentLength() || contentLength() == 0);
|
||||
}
|
||||
|
||||
bool HttpRequestParser::isError() const
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
QString HttpRequestParser::url() const
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
QByteArray HttpRequestParser::message() const
|
||||
{
|
||||
if(isParsable())
|
||||
return data;
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QString HttpRequestParser::get(const QString key) const
|
||||
{
|
||||
return getMap[key];
|
||||
}
|
||||
|
||||
QString HttpRequestParser::post(const QString key) const
|
||||
{
|
||||
return postMap[key];
|
||||
}
|
||||
|
||||
QByteArray HttpRequestParser::torrent() const
|
||||
{
|
||||
return torrent_content;
|
||||
}
|
||||
|
||||
void HttpRequestParser::write(QByteArray str)
|
||||
{
|
||||
while (!headerDone && str.size()>0)
|
||||
{
|
||||
int index = str.indexOf('\n') + 1;
|
||||
if(index == 0)
|
||||
{
|
||||
data += str;
|
||||
str.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
data += str.left(index);
|
||||
str.remove(0, index);
|
||||
if(data.right(4) == "\r\n\r\n")
|
||||
{
|
||||
QHttpRequestHeader::operator=(QHttpRequestHeader(data));
|
||||
headerDone = true;
|
||||
data.clear();
|
||||
QUrl url = QUrl::fromEncoded(QHttpRequestHeader::path().toAscii());
|
||||
path = url.path();
|
||||
//() << path;
|
||||
QListIterator<QPair<QString, QString> > i(url.queryItems());
|
||||
while (i.hasNext())
|
||||
{
|
||||
QPair<QString, QString> pair = i.next();
|
||||
getMap[pair.first] = pair.second;
|
||||
//qDebug() << pair.first << "=" << get(pair.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!messageDone && str.size()>0)
|
||||
{
|
||||
if(hasContentLength())
|
||||
{
|
||||
data += str;
|
||||
if(data.size() >= (int) contentLength())
|
||||
{
|
||||
data.resize(contentLength());
|
||||
messageDone = true;
|
||||
//parse POST data
|
||||
if(contentType() == "application/x-www-form-urlencoded")
|
||||
{
|
||||
QUrl url;
|
||||
url.setEncodedQuery(data);
|
||||
QListIterator<QPair<QString, QString> > i(url.queryItems());
|
||||
while (i.hasNext())
|
||||
{
|
||||
QPair<QString, QString> pair = i.next();
|
||||
postMap[pair.first] = pair.second;
|
||||
//qDebug() << pair.first << "=" << post(pair.first);
|
||||
}
|
||||
}
|
||||
if(contentType() == "multipart/form-data")
|
||||
{
|
||||
//qDebug() << data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
|
||||
torrent_content = data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora
|
||||
* ishanarora@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HTTPREQUESTPARSER_H
|
||||
#define HTTPREQUESTPARSER_H
|
||||
|
||||
#include<QHttpRequestHeader>
|
||||
|
||||
class HttpRequestParser : public QHttpRequestHeader
|
||||
{
|
||||
private:
|
||||
bool headerDone;
|
||||
bool messageDone;
|
||||
bool error;
|
||||
QByteArray data;
|
||||
QString path;
|
||||
QMap<QString, QString> postMap;
|
||||
QMap<QString, QString> getMap;
|
||||
QByteArray torrent_content;
|
||||
|
||||
public:
|
||||
HttpRequestParser();
|
||||
~HttpRequestParser();
|
||||
bool isParsable() const;
|
||||
bool isError() const;
|
||||
QString url() const;
|
||||
QByteArray message() const;
|
||||
QString get(const QString key) const;
|
||||
QString post(const QString key) const;
|
||||
QByteArray torrent() const;
|
||||
void write(QByteArray str);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 by Ishan Arora
|
||||
* ishanarora@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "httpresponsegenerator.h"
|
||||
|
||||
void HttpResponseGenerator::setMessage(const QByteArray message)
|
||||
{
|
||||
HttpResponseGenerator::message = message;
|
||||
setContentLength(message.size());
|
||||
}
|
||||
|
||||
void HttpResponseGenerator::setMessage(const QString message)
|
||||
{
|
||||
setMessage(message.QString::toUtf8());
|
||||
}
|
||||
|
||||
void HttpResponseGenerator::stripMessage()
|
||||
{
|
||||
message.clear();
|
||||
}
|
||||
|
||||
QByteArray HttpResponseGenerator::toByteArray() const
|
||||
{
|
||||
return QHttpResponseHeader::toString().toUtf8() + message;
|
||||
}
|
||||
|
||||
void HttpResponseGenerator::setContentTypeByExt(const QString ext)
|
||||
{
|
||||
if(ext == "css")
|
||||
{
|
||||
setContentType("text/css");
|
||||
return;
|
||||
}
|
||||
if(ext == "gif")
|
||||
{
|
||||
setContentType("image/gif");
|
||||
return;
|
||||
}
|
||||
if(ext == "htm" || ext == "html")
|
||||
{
|
||||
setContentType("text/html");
|
||||
return;
|
||||
}
|
||||
if(ext == "js")
|
||||
{
|
||||
setContentType("text/javascript");
|
||||
return;
|
||||
}
|
||||
if(ext == "png")
|
||||
{
|
||||
setContentType("image/x-png");
|
||||
return;
|
||||
}
|
||||
}
|
||||