mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-19 15:07:22 -06:00
Compare commits
1 Commits
release-1.
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91d9325c7c |
66
AUTHORS
66
AUTHORS
@@ -3,69 +3,3 @@ Author:
|
|||||||
|
|
||||||
Contributors:
|
Contributors:
|
||||||
* Arnaud Demaizière <arnaud@qbittorrent.org>
|
* Arnaud Demaizière <arnaud@qbittorrent.org>
|
||||||
* Ishan Arora <ishan@qbittorrent.org>
|
|
||||||
* Grigis Gaëtan <cipher16@gmail.com>
|
|
||||||
|
|
||||||
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/skins/*.png
|
|
||||||
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
|
|
||||||
license: GPLv2
|
|
||||||
|
|
||||||
* files: src/menuicons/YYxYY/*.png
|
|
||||||
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
|
|
||||||
license: GPLv2
|
|
||||||
|
|
||||||
* file: src/search_engine/engines/btjunkie.png
|
|
||||||
copyright: Downloaded from btjunkie.org
|
|
||||||
|
|
||||||
* 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 (guoyue0418@hotmail.com)
|
|
||||||
- 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
|
|
||||||
|
|||||||
36
Changelog
36
Changelog
@@ -1,35 +1,4 @@
|
|||||||
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.1.0
|
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.0.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
|
|
||||||
- FEATURE: Based on new libtorrent v0.13
|
- FEATURE: Based on new libtorrent v0.13
|
||||||
- FEATURE: Added UPnP / NAT-PMP port forwarding support
|
- FEATURE: Added UPnP / NAT-PMP port forwarding support
|
||||||
- FEATURE: Added encryption support (compatible with Azureus)
|
- FEATURE: Added encryption support (compatible with Azureus)
|
||||||
@@ -37,7 +6,6 @@
|
|||||||
- FEATURE: Added RSS support
|
- FEATURE: Added RSS support
|
||||||
- FEATURE: Support files prioritizing in a torrent
|
- FEATURE: Support files prioritizing in a torrent
|
||||||
- FEATURE: Brand new search engine plugins system
|
- FEATURE: Brand new search engine plugins system
|
||||||
- FEATURE: Filtered files don't appear on hard disk anymore
|
|
||||||
- FEATURE: Finished torrents are now moved to another tab for seeding
|
- FEATURE: Finished torrents are now moved to another tab for seeding
|
||||||
- FEATURE: Display more infos about the torrent in its properties
|
- FEATURE: Display more infos about the torrent in its properties
|
||||||
- FEATURE: Allow the user to edit torrents' trackers
|
- FEATURE: Allow the user to edit torrents' trackers
|
||||||
@@ -95,8 +63,6 @@
|
|||||||
- BUGFIX: Prevent downloadFromUrl flooding
|
- BUGFIX: Prevent downloadFromUrl flooding
|
||||||
- BUGFIX: ETA was wrong for torrents with filtered files
|
- BUGFIX: ETA was wrong for torrents with filtered files
|
||||||
- BUGFIX: Fixed drag'n drop on non-KDE systems
|
- 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: Redesigned torrent properties a little
|
||||||
- COSMETIC: Totally redesigned program preferences
|
- COSMETIC: Totally redesigned program preferences
|
||||||
- COSMETIC: Display more logs messages concerning features
|
- COSMETIC: Display more logs messages concerning features
|
||||||
|
|||||||
13
INSTALL
13
INSTALL
@@ -1,4 +1,4 @@
|
|||||||
qBittorrent - A BitTorrent client in C++ / Qt4
|
qBittorrent - A BitTorrent client in C++ / Qt4.2
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
*** Necessary if qt3 is default on your system ***
|
*** Necessary if qt3 is default on your system ***
|
||||||
@@ -14,17 +14,18 @@ qbittorrent
|
|||||||
will install and execute qBittorrent hopefully without any problems.
|
will install and execute qBittorrent hopefully without any problems.
|
||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
- Qt >= 4.2 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||||
Qt >= 4.4.0 is advised
|
|
||||||
|
|
||||||
- libtorrent-rasterbar by Arvid Norberg (>= v0.13.1 REQUIRED)
|
- rblibtorrent by Arvid Norberg (>= v0.13 REQUIRED)
|
||||||
-> http://www.qbittorrent.org/download.php (advised)
|
-> http://www.qbittorrent.org/download.php (advised)
|
||||||
-> http://www.libtorrent.net
|
-> http://www.libtorrent.net
|
||||||
Be careful: another library (the one used by rTorrent) uses a similar name.
|
Be careful: another library (the one used by rTorrent) 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
|
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
|
||||||
|
|
||||||
- libcurl
|
- libcommoncpp2
|
||||||
|
|
||||||
- python >= 2.3 (needed by search engine)
|
- python >= 2.3 (needed by search engine)
|
||||||
|
|
||||||
|
|||||||
51
TODO
51
TODO
@@ -8,9 +8,11 @@
|
|||||||
- Skins support? (contact Mateusz)
|
- Skins support? (contact Mateusz)
|
||||||
|
|
||||||
// Harder
|
// Harder
|
||||||
|
- Display a progress bar that really represents the pieces we have (like in eMule)
|
||||||
- Torrent scheduler ala µtorrent/Bitcomet
|
- Torrent scheduler ala µtorrent/Bitcomet
|
||||||
|
|
||||||
// Waiting for libtorrent
|
// Waiting for libtorrent
|
||||||
|
- File selection in a torrent in compact mode
|
||||||
- Allow to prioritize torrents (may code this in qBittorrent?)
|
- Allow to prioritize torrents (may code this in qBittorrent?)
|
||||||
|
|
||||||
// Unsure
|
// Unsure
|
||||||
@@ -23,29 +25,38 @@
|
|||||||
(http://techbase.kde.org/Development/Tutorials/D-Bus/Accessing_Interfaces)
|
(http://techbase.kde.org/Development/Tutorials/D-Bus/Accessing_Interfaces)
|
||||||
- When favicon can't be downloaded, try to parse the webpage for:
|
- 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">
|
<link rel="icon" href="http://example.com/favicon.ico" type="image/vnd.microsoft.icon">
|
||||||
* Be careful, the link can be relative
|
* Be carefull, the link can be relative
|
||||||
- Improve search plugin install (choose in a list taken from plugins.qbittorrent.org)
|
|
||||||
- support zipped torrents? (useful?)
|
|
||||||
- Allow to limit the number of downloading torrents simultaneously (other are paused until a download finishes)
|
|
||||||
|
|
||||||
// in v1.2.0
|
// in v1.2.0
|
||||||
- Allow user to organize the downloads into categories/folders?
|
- Allow user to organize the downloads into categories/folders?
|
||||||
|
|
||||||
// in v1.1.0
|
// in v1.1.0
|
||||||
- Stop calculating ETAs when ETA column is hidden
|
- Tabs support in search
|
||||||
-> See https://blueprints.launchpad.net/qbittorrent
|
- 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
|
||||||
|
|
||||||
Translations updated:
|
// in v1.0.0 - FEATURE FREEZE
|
||||||
- French
|
- Fix all (or almost all) opened bugs in bug tracker
|
||||||
- Chinese
|
- debug new torrent content selection
|
||||||
- Polish
|
- Recheck doc
|
||||||
- Portuguese
|
- Translations update (IN PROGRESS)
|
||||||
- Brazilian
|
- Make use of total_wanted
|
||||||
- Slovak
|
|
||||||
- Swedish
|
rc2->rc3 changelog:
|
||||||
- Romanian
|
- BUGFIX: Fixed a proxy problem causing connections to be rejected by trackers
|
||||||
- Finnish
|
- BUGFIX: Fixed compilation problem on FreeBSD
|
||||||
- Italian
|
|
||||||
- Turkish
|
|
||||||
- Korean
|
|
||||||
- Hungarian
|
|
||||||
145
configure
vendored
145
configure
vendored
@@ -18,14 +18,12 @@ Main options:
|
|||||||
--help This help text.
|
--help This help text.
|
||||||
|
|
||||||
Dependency options:
|
Dependency options:
|
||||||
--with-libtorrent-inc=[path] Path to libtorrent-rasterbar include
|
--with-libtorrent-inc=[path] Path to libtorrent include files
|
||||||
files
|
--with-libtorrent-lib=[path] Path to libtorrent library files
|
||||||
--with-libtorrent-lib=[path] Path to libtorrent-rasterbar library
|
--with-libtorrent-static-lib=[path] Path to libtorrent .a file
|
||||||
files
|
|
||||||
--with-libtorrent-static-lib=[path] Path to libtorrent-rasterbar .a file
|
|
||||||
--with-libboost-inc=[path] Path to libboost include files
|
--with-libboost-inc=[path] Path to libboost include files
|
||||||
--with-libcurl-inc=[path] Path to libcurl include files
|
--with-libcommoncpp2-inc=[path] Path to libcommoncpp2 include files
|
||||||
--with-libcurl-lib=[path] Path to libcurl library files
|
--with-libcommoncpp2-lib=[path] Path to libcommoncpp2 library files
|
||||||
--disable-libmagick Disable use of libmagick
|
--disable-libmagick Disable use of libmagick
|
||||||
--with-libmagick-inc=[path] Path to libmagick++ include files
|
--with-libmagick-inc=[path] Path to libmagick++ include files
|
||||||
--with-libmagick-lib=[path] Path to libmagick++ library files
|
--with-libmagick-lib=[path] Path to libmagick++ library files
|
||||||
@@ -168,13 +166,13 @@ while [ $# -gt 0 ]; do
|
|||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--with-libcurl-inc=*)
|
--with-libcommoncpp2-inc=*)
|
||||||
QC_WITH_LIBCURL_INC=$optarg
|
QC_WITH_LIBCOMMONCPP2_INC=$optarg
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--with-libcurl-lib=*)
|
--with-libcommoncpp2-lib=*)
|
||||||
QC_WITH_LIBCURL_LIB=$optarg
|
QC_WITH_LIBCOMMONCPP2_LIB=$optarg
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -233,8 +231,8 @@ echo QC_WITH_LIBTORRENT_INC=$QC_WITH_LIBTORRENT_INC
|
|||||||
echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB
|
echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB
|
||||||
echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB
|
echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB
|
||||||
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
||||||
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
|
echo QC_WITH_LIBCOMMONCPP2_INC=$QC_WITH_LIBCOMMONCPP2_INC
|
||||||
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
|
echo QC_WITH_LIBCOMMONCPP2_LIB=$QC_WITH_LIBCOMMONCPP2_LIB
|
||||||
echo QC_DISABLE_libmagick=$QC_DISABLE_libmagick
|
echo QC_DISABLE_libmagick=$QC_DISABLE_libmagick
|
||||||
echo QC_WITH_LIBMAGICK_INC=$QC_WITH_LIBMAGICK_INC
|
echo QC_WITH_LIBMAGICK_INC=$QC_WITH_LIBMAGICK_INC
|
||||||
echo QC_WITH_LIBMAGICK_LIB=$QC_WITH_LIBMAGICK_LIB
|
echo QC_WITH_LIBMAGICK_LIB=$QC_WITH_LIBMAGICK_LIB
|
||||||
@@ -356,28 +354,24 @@ public:
|
|||||||
QString shortname() const { return "Qt 4.3"; }
|
QString shortname() const { return "Qt 4.3"; }
|
||||||
bool exec()
|
bool exec()
|
||||||
{
|
{
|
||||||
if(QT_VERSION >= 0x040400) {
|
|
||||||
conf->addDefine("QT_4_4");
|
|
||||||
}
|
|
||||||
return(QT_VERSION >= 0x040300);
|
return(QT_VERSION >= 0x040300);
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#line 1 "libtorrent-rasterbar.qcm"
|
#line 1 "libtorrent.qcm"
|
||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: libtorrent-rasterbar
|
name: libtorrent
|
||||||
arg: with-libtorrent-inc=[path], Path to libtorrent-rasterbar include files
|
arg: with-libtorrent-inc=[path], Path to libtorrent include files
|
||||||
arg: with-libtorrent-lib=[path], Path to libtorrent-rasterbar library files
|
arg: with-libtorrent-lib=[path], Path to libtorrent library files
|
||||||
arg: with-libtorrent-static-lib=[path], Path to libtorrent-rasterbar .a file
|
arg: with-libtorrent-static-lib=[path], Path to libtorrent .a file
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_libtorrent_rasterbar : public ConfObj
|
class qc_libtorrent : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
qc_libtorrent(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libtorrent-rasterbar >= 0.13"; }
|
QString name() const { return "libtorrent >= 0.13"; }
|
||||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
QString shortname() const { return "libtorrent"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
QString s;
|
QString s;
|
||||||
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
||||||
@@ -411,19 +405,17 @@ public:
|
|||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
|
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkLibrary(s, "torrent-rasterbar")) {
|
if(!conf->checkLibrary(s, "torrent")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
conf->addLib(QString("-L") + s);
|
conf->addLib(QString("-L") + s);
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(conf->checkLibrary(s, "torrent-rasterbar")){
|
if(conf->checkLibrary(s, "torrent")){
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -431,6 +423,16 @@ public:
|
|||||||
if(!found) return false;
|
if(!found) return false;
|
||||||
conf->addLib(QString("-L") + s);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -491,25 +493,25 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#line 1 "libcurl.qcm"
|
#line 1 "libcommoncpp2.qcm"
|
||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: libcommoncpp2
|
name: libcommoncpp2
|
||||||
arg: with-libcurl-inc=[path], Path to libcurl include files
|
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files
|
||||||
arg: with-libcurl-lib=[path], Path to libcurl library files
|
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_libcurl : public ConfObj
|
class qc_libcommoncpp2 : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libcurl(Conf *c) : ConfObj(c) {}
|
qc_libcommoncpp2(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libcurl"; }
|
QString name() const { return "GNU Common C++ library (libcommoncpp2)"; }
|
||||||
QString shortname() const { return "libcurl"; }
|
QString shortname() const { return "libcommoncpp2"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
QString s;
|
QString s;
|
||||||
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_INC");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkHeader(s, "curl/curl.h")) {
|
if(!conf->checkHeader(s, "cc++/url.h")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -518,7 +520,7 @@ public:
|
|||||||
sl << "/usr/local/include";
|
sl << "/usr/local/include";
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(conf->checkHeader(s, "curl/curl.h")){
|
if(conf->checkHeader(s, "cc++/url.h")){
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -529,26 +531,38 @@ public:
|
|||||||
}
|
}
|
||||||
conf->addIncludePath(s);
|
conf->addIncludePath(s);
|
||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!QFile::exists(s+QString("/libcurl.so")))
|
if(!QFile::exists(s+QString("libccext2.so")))
|
||||||
|
return false;
|
||||||
|
if(!QFile::exists(s+QString("libccgnu2.so")))
|
||||||
return false;
|
return false;
|
||||||
conf->addLib(QString("-L") + s);
|
conf->addLib(QString("-L") + s);
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(QFile::exists(s+QString("libcurl.so"))){
|
if(QFile::exists(s+QString("libccext2.so"))){
|
||||||
|
if(QFile::exists(s+QString("libccgnu2.so"))){
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(!found) return false;
|
if(!found) return false;
|
||||||
conf->addLib(QString("-L") + s);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -600,18 +614,16 @@ public:
|
|||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkLibrary(s, "Magick++")) {
|
if(!QFile::exists(s+QString("libMagick++.so"))){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(conf->checkLibrary(s, "Magick++")) {
|
if(QFile::exists(s+QString("libMagick++.so"))){
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -680,15 +692,13 @@ public:
|
|||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!QFile::exists(s+QString("/libzzip.so"))){
|
if(!QFile::exists(s+QString("libzzip.so"))){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(QFile::exists(s+QString("libzzip.so"))){
|
if(QFile::exists(s+QString("libzzip.so"))){
|
||||||
@@ -705,19 +715,39 @@ public:
|
|||||||
return true;
|
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
|
EOT
|
||||||
cat >$1/modules_new.cpp <<EOT
|
cat >$1/modules_new.cpp <<EOT
|
||||||
o = new qc_qt4(conf);
|
o = new qc_qt4(conf);
|
||||||
o->required = true;
|
o->required = true;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
o = new qc_libtorrent_rasterbar(conf);
|
o = new qc_libtorrent(conf);
|
||||||
o->required = true;
|
o->required = true;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
o = new qc_libboost(conf);
|
o = new qc_libboost(conf);
|
||||||
o->required = true;
|
o->required = true;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
o = new qc_libcurl(conf);
|
o = new qc_libcommoncpp2(conf);
|
||||||
o->required = true;
|
o->required = true;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
o = new qc_libmagick(conf);
|
o = new qc_libmagick(conf);
|
||||||
@@ -726,6 +756,9 @@ cat >$1/modules_new.cpp <<EOT
|
|||||||
o = new qc_libzzip(conf);
|
o = new qc_libzzip(conf);
|
||||||
o->required = false;
|
o->required = false;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
|
o = new qc_python(conf);
|
||||||
|
o->required = true;
|
||||||
|
o->disabled = false;
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
cat >$1/conf4.h <<EOT
|
cat >$1/conf4.h <<EOT
|
||||||
@@ -1675,8 +1708,8 @@ export QC_WITH_LIBTORRENT_INC
|
|||||||
export QC_WITH_LIBTORRENT_LIB
|
export QC_WITH_LIBTORRENT_LIB
|
||||||
export QC_WITH_LIBTORRENT_STATIC_LIB
|
export QC_WITH_LIBTORRENT_STATIC_LIB
|
||||||
export QC_WITH_LIBBOOST_INC
|
export QC_WITH_LIBBOOST_INC
|
||||||
export QC_WITH_LIBCURL_INC
|
export QC_WITH_LIBCOMMONCPP2_INC
|
||||||
export QC_WITH_LIBCURL_LIB
|
export QC_WITH_LIBCOMMONCPP2_LIB
|
||||||
export QC_DISABLE_libmagick
|
export QC_DISABLE_libmagick
|
||||||
export QC_WITH_LIBMAGICK_INC
|
export QC_WITH_LIBMAGICK_INC
|
||||||
export QC_WITH_LIBMAGICK_LIB
|
export QC_WITH_LIBMAGICK_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
BIN
doc/qbittorrent.1.gz
Normal file
Binary file not shown.
134
packaging/debian-unstable/debian/changelog
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
1
packaging/debian-unstable/debian/compat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
4
|
||||||
15
packaging/debian-unstable/debian/control
Normal file
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
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
2
packaging/debian-unstable/debian/dirs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
usr/bin
|
||||||
|
usr/sbin
|
||||||
3
packaging/debian-unstable/debian/docs
Normal file
3
packaging/debian-unstable/debian/docs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
NEWS
|
||||||
|
README
|
||||||
|
TODO
|
||||||
107
packaging/debian-unstable/debian/rules
Executable file
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
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
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
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
1
packaging/ubuntu-dapper/debian/compat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
4
|
||||||
15
packaging/ubuntu-dapper/debian/control
Normal file
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
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
2
packaging/ubuntu-dapper/debian/dirs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
usr/bin
|
||||||
|
usr/sbin
|
||||||
3
packaging/ubuntu-dapper/debian/docs
Normal file
3
packaging/ubuntu-dapper/debian/docs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
NEWS
|
||||||
|
README
|
||||||
|
TODO
|
||||||
1
packaging/ubuntu-dapper/debian/files
Normal file
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
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
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
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
1
packaging/ubuntu-edgy/debian/compat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
4
|
||||||
15
packaging/ubuntu-edgy/debian/control
Normal file
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
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
2
packaging/ubuntu-edgy/debian/dirs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
usr/bin
|
||||||
|
usr/sbin
|
||||||
3
packaging/ubuntu-edgy/debian/docs
Normal file
3
packaging/ubuntu-edgy/debian/docs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
NEWS
|
||||||
|
README
|
||||||
|
TODO
|
||||||
1
packaging/ubuntu-edgy/debian/files
Normal file
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
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
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>
|
<includestyle>4</includestyle>
|
||||||
<designerintegration>ExternalDesigner</designerintegration>
|
<designerintegration>ExternalDesigner</designerintegration>
|
||||||
<root>/usr/lib/qt4</root>
|
<root>/usr/lib/qt4</root>
|
||||||
<qmake>/usr/bin/qmake</qmake>
|
<qmake>/usr/bin/qmake-qt4</qmake>
|
||||||
<designer>/usr/bin/designer</designer>
|
<designer>/usr/bin/designer-qt4</designer>
|
||||||
<designerpluginpaths/>
|
<designerpluginpaths/>
|
||||||
</qt>
|
</qt>
|
||||||
<references>
|
<references>
|
||||||
<pcs>automatic_%2Fhome%2Fishanarora%2Fprojects%2Fqbittorrent</pcs>
|
<pcs>automatic_%2Fhome%2Fchris%2Fqbittorrent_svn%2Ftrunk</pcs>
|
||||||
|
<pcs>Qt4</pcs>
|
||||||
</references>
|
</references>
|
||||||
<codecompletion>
|
<codecompletion>
|
||||||
<automaticCodeCompletion>true</automaticCodeCompletion>
|
<automaticCodeCompletion>true</automaticCodeCompletion>
|
||||||
@@ -148,14 +149,14 @@
|
|||||||
</kdevfilecreate>
|
</kdevfilecreate>
|
||||||
<kdevtrollproject>
|
<kdevtrollproject>
|
||||||
<general>
|
<general>
|
||||||
<activedir>src</activedir>
|
<activedir></activedir>
|
||||||
</general>
|
</general>
|
||||||
<run>
|
<run>
|
||||||
<directoryradio>executable</directoryradio>
|
<directoryradio>executable</directoryradio>
|
||||||
<mainprogram>/home/ishanarora/projects/qbittorrent/src/qbittorrent</mainprogram>
|
<mainprogram>/home/chris/qbittorrent_svn/trunk/src/qbittorrent</mainprogram>
|
||||||
<programargs/>
|
<programargs/>
|
||||||
<globaldebugarguments/>
|
<globaldebugarguments/>
|
||||||
<globalcwd>/home/ishanarora/projects/qbittorrent</globalcwd>
|
<globalcwd>/home/chris/qbittorrent_svn/trunk</globalcwd>
|
||||||
<useglobalprogram>true</useglobalprogram>
|
<useglobalprogram>true</useglobalprogram>
|
||||||
<terminal>false</terminal>
|
<terminal>false</terminal>
|
||||||
<autocompile>true</autocompile>
|
<autocompile>true</autocompile>
|
||||||
@@ -186,7 +187,7 @@
|
|||||||
</cppsupportpart>
|
</cppsupportpart>
|
||||||
<ctagspart>
|
<ctagspart>
|
||||||
<customArguments/>
|
<customArguments/>
|
||||||
<customTagfilePath>/home/ishanarora/projects/qbittorrent/tags</customTagfilePath>
|
<customTagfilePath>/home/chris/qbittorrent_svn/trunk/tags</customTagfilePath>
|
||||||
<activeTagsFiles/>
|
<activeTagsFiles/>
|
||||||
</ctagspart>
|
</ctagspart>
|
||||||
<kdevdocumentation>
|
<kdevdocumentation>
|
||||||
|
|||||||
@@ -6,15 +6,18 @@
|
|||||||
<dep type='qt4'>
|
<dep type='qt4'>
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
<dep type='libtorrent-rasterbar'>
|
<dep type='libtorrent'>
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
<dep type='libboost'>
|
<dep type='libboost'>
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
<dep type='libcurl'>
|
<dep type='libcommoncpp2'>
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
<dep type='libmagick'/>
|
<dep type='libmagick'/>
|
||||||
<dep type='libzzip'/>
|
<dep type='libzzip'/>
|
||||||
|
<dep type='python'>
|
||||||
|
<required/>
|
||||||
|
</dep>
|
||||||
</qconf>
|
</qconf>
|
||||||
|
|||||||
@@ -37,17 +37,15 @@ public:
|
|||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!QFile::exists(s+QString("/libccext2.so")))
|
if(!QFile::exists(s+QString("libccext2.so")))
|
||||||
return false;
|
return false;
|
||||||
if(!QFile::exists(s+QString("/libccgnu2.so")))
|
if(!QFile::exists(s+QString("libccgnu2.so")))
|
||||||
return false;
|
return false;
|
||||||
conf->addLib(QString("-L") + s);
|
conf->addLib(QString("-L") + s);
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(QFile::exists(s+QString("libccext2.so"))){
|
if(QFile::exists(s+QString("libccext2.so"))){
|
||||||
@@ -59,6 +57,16 @@ public:
|
|||||||
}
|
}
|
||||||
if(!found) return false;
|
if(!found) return false;
|
||||||
conf->addLib(QString("-L") + s);
|
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;
|
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,18 +44,16 @@ public:
|
|||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkLibrary(s, "Magick++")) {
|
if(!QFile::exists(s+QString("libMagick++.so"))){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(conf->checkLibrary(s, "Magick++")) {
|
if(QFile::exists(s+QString("libMagick++.so"))){
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: libtorrent-rasterbar
|
name: libtorrent
|
||||||
arg: with-libtorrent-inc=[path], Path to libtorrent-rasterbar include files
|
arg: with-libtorrent-inc=[path], Path to libtorrent include files
|
||||||
arg: with-libtorrent-lib=[path], Path to libtorrent-rasterbar library files
|
arg: with-libtorrent-lib=[path], Path to libtorrent library files
|
||||||
arg: with-libtorrent-static-lib=[path], Path to libtorrent-rasterbar .a file
|
arg: with-libtorrent-static-lib=[path], Path to libtorrent .a file
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_libtorrent_rasterbar : public ConfObj
|
class qc_libtorrent : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
qc_libtorrent(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libtorrent-rasterbar >= 0.13"; }
|
QString name() const { return "libtorrent >= 0.13"; }
|
||||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
QString shortname() const { return "libtorrent"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
QString s;
|
QString s;
|
||||||
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
|
||||||
@@ -45,19 +45,17 @@ public:
|
|||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
|
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkLibrary(s, "torrent-rasterbar")) {
|
if(!conf->checkLibrary(s, "torrent")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
conf->addLib(QString("-L") + s);
|
conf->addLib(QString("-L") + s);
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(conf->checkLibrary(s, "torrent-rasterbar")){
|
if(conf->checkLibrary(s, "torrent")){
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -65,6 +63,16 @@ public:
|
|||||||
if(!found) return false;
|
if(!found) return false;
|
||||||
conf->addLib(QString("-L") + s);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -44,15 +44,13 @@ public:
|
|||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!QFile::exists(s+QString("/libzzip.so"))){
|
if(!QFile::exists(s+QString("libzzip.so"))){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl << "/usr/lib/";
|
sl << "/usr/lib/";
|
||||||
sl << "/usr/lib64/";
|
|
||||||
sl << "/usr/local/lib/";
|
sl << "/usr/local/lib/";
|
||||||
sl << "/usr/local/lib64/";
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(s, sl){
|
foreach(s, sl){
|
||||||
if(QFile::exists(s+QString("libzzip.so"))){
|
if(QFile::exists(s+QString("libzzip.so"))){
|
||||||
|
|||||||
19
qcm/python.qcm
Normal file
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"; }
|
QString shortname() const { return "Qt 4.3"; }
|
||||||
bool exec()
|
bool exec()
|
||||||
{
|
{
|
||||||
if(QT_VERSION >= 0x040400) {
|
|
||||||
conf->addDefine("QT_4_4");
|
|
||||||
}
|
|
||||||
return(QT_VERSION >= 0x040300);
|
return(QT_VERSION >= 0x040300);
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -83,9 +83,12 @@ class DLListDelegate: public QItemDelegate {
|
|||||||
newopt.maximum = 100;
|
newopt.maximum = 100;
|
||||||
newopt.minimum = 0;
|
newopt.minimum = 0;
|
||||||
newopt.state |= QStyle::State_Enabled;
|
newopt.state |= QStyle::State_Enabled;
|
||||||
newopt.textVisible = true;
|
newopt.textVisible = false;
|
||||||
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt,
|
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt,
|
||||||
painter);
|
painter);
|
||||||
|
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||||
|
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
|
||||||
|
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -34,10 +34,11 @@
|
|||||||
// Defines for download list list columns
|
// Defines for download list list columns
|
||||||
#define F_NAME 0
|
#define F_NAME 0
|
||||||
#define F_SIZE 1
|
#define F_SIZE 1
|
||||||
#define F_UPSPEED 2
|
#define F_PROGRESS 2
|
||||||
#define F_LEECH 3
|
#define F_UPSPEED 3
|
||||||
#define F_RATIO 4
|
#define F_SEEDSLEECH 4
|
||||||
#define F_HASH 5
|
#define F_RATIO 5
|
||||||
|
#define F_HASH 6
|
||||||
|
|
||||||
class FinishedListDelegate: public QItemDelegate {
|
class FinishedListDelegate: public QItemDelegate {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -66,6 +67,23 @@ class FinishedListDelegate: public QItemDelegate {
|
|||||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
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 = false;
|
||||||
|
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt,
|
||||||
|
painter);
|
||||||
|
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||||
|
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
|
||||||
|
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
QItemDelegate::paint(painter, option, index);
|
QItemDelegate::paint(painter, option, index);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,22 +31,21 @@
|
|||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbFinished(0){
|
FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbFinished(0){
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
|
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
|
||||||
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
|
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
|
||||||
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool)));
|
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool)));
|
||||||
finishedListModel = new QStandardItemModel(0,6);
|
finishedListModel = new QStandardItemModel(0,7);
|
||||||
finishedListModel->setHeaderData(F_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
|
finishedListModel->setHeaderData(F_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
|
||||||
finishedListModel->setHeaderData(F_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
|
finishedListModel->setHeaderData(F_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
|
||||||
|
finishedListModel->setHeaderData(F_PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded"));
|
||||||
finishedListModel->setHeaderData(F_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed"));
|
finishedListModel->setHeaderData(F_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed"));
|
||||||
finishedListModel->setHeaderData(F_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"));
|
finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio"));
|
||||||
finishedList->setModel(finishedListModel);
|
finishedList->setModel(finishedListModel);
|
||||||
loadHiddenColumns();
|
// Hide ETA & hash column
|
||||||
// Hide hash column
|
|
||||||
finishedList->hideColumn(F_HASH);
|
finishedList->hideColumn(F_HASH);
|
||||||
// Load last columns width for download list
|
// Load last columns width for download list
|
||||||
if(!loadColWidthFinishedList()){
|
if(!loadColWidthFinishedList()){
|
||||||
@@ -59,9 +58,6 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
|
|||||||
finishedListDelegate = new FinishedListDelegate(finishedList);
|
finishedListDelegate = new FinishedListDelegate(finishedList);
|
||||||
finishedList->setItemDelegate(finishedListDelegate);
|
finishedList->setItemDelegate(finishedListDelegate);
|
||||||
connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&)));
|
connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&)));
|
||||||
finishedList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
connect(finishedList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedHoSMenu(const QPoint&)));
|
|
||||||
|
|
||||||
connect(finishedList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
|
connect(finishedList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
|
||||||
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
|
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
|
||||||
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
|
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
|
||||||
@@ -73,20 +69,11 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
|
|||||||
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
|
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
|
||||||
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered()));
|
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered()));
|
||||||
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
|
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
|
||||||
connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
|
|
||||||
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
|
|
||||||
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
|
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
|
||||||
|
|
||||||
connect(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(){
|
FinishedTorrents::~FinishedTorrents(){
|
||||||
saveColWidthFinishedList();
|
saveColWidthFinishedList();
|
||||||
saveHiddenColumns();
|
|
||||||
delete finishedListDelegate;
|
delete finishedListDelegate;
|
||||||
delete finishedListModel;
|
delete finishedListModel;
|
||||||
}
|
}
|
||||||
@@ -94,7 +81,7 @@ FinishedTorrents::~FinishedTorrents(){
|
|||||||
void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
|
void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
|
||||||
unsigned int row = index.row();
|
unsigned int row = index.row();
|
||||||
QString hash = getHashFromRow(row);
|
QString hash = getHashFromRow(row);
|
||||||
emit torrentDoubleClicked(hash, true);
|
emit torrentDoubleClicked(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinishedTorrents::addTorrent(QString hash){
|
void FinishedTorrents::addTorrent(QString hash){
|
||||||
@@ -110,9 +97,10 @@ void FinishedTorrents::addTorrent(QString hash){
|
|||||||
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name()));
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name()));
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
|
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.));
|
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.));
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_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_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_HASH), QVariant(hash));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.));
|
||||||
if(h.is_paused()) {
|
if(h.is_paused()) {
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
|
||||||
setRowColor(row, "red");
|
setRowColor(row, "red");
|
||||||
@@ -168,7 +156,7 @@ bool FinishedTorrents::loadColWidthFinishedList(){
|
|||||||
if(line.isEmpty())
|
if(line.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
QStringList width_list = line.split(' ');
|
QStringList width_list = line.split(' ');
|
||||||
if(width_list.size() < finishedListModel->columnCount()-1)
|
if(width_list.size() != finishedListModel->columnCount()-1)
|
||||||
return false;
|
return false;
|
||||||
unsigned int listSize = width_list.size();
|
unsigned int listSize = width_list.size();
|
||||||
for(unsigned int i=0; i<listSize; ++i){
|
for(unsigned int i=0; i<listSize; ++i){
|
||||||
@@ -184,27 +172,11 @@ void FinishedTorrents::saveColWidthFinishedList() const{
|
|||||||
qDebug("Saving columns width in finished list");
|
qDebug("Saving columns width in finished list");
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
QStringList width_list;
|
QStringList width_list;
|
||||||
QStringList new_width_list;
|
unsigned int nbColumns = finishedListModel->columnCount()-1;
|
||||||
short nbColumns = finishedListModel->columnCount()-1;
|
for(unsigned int i=0; i<nbColumns; ++i){
|
||||||
|
width_list << QString::fromUtf8(misc::toString(finishedList->columnWidth(i)).c_str());
|
||||||
QString line = settings.value("FinishedListColsWidth", QString()).toString();
|
|
||||||
if(!line.isEmpty()) {
|
|
||||||
width_list = line.split(' ');
|
|
||||||
}
|
}
|
||||||
for(short i=0; i<nbColumns; ++i){
|
settings.setValue("FinishedListColsWidth", width_list.join(" "));
|
||||||
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(" "));
|
|
||||||
qDebug("Finished list columns width saved");
|
qDebug("Finished list columns width saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,39 +211,29 @@ void FinishedTorrents::updateFinishedList(){
|
|||||||
Q_ASSERT(row != -1);
|
Q_ASSERT(row != -1);
|
||||||
if(h.is_paused()) continue;
|
if(h.is_paused()) continue;
|
||||||
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
|
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)h.progress()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(h.state() == torrent_status::downloading || (h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking && h.progress() < 1.)) {
|
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!
|
// What are you doing here? go back to download tab!
|
||||||
int reponse = QMessageBox::question(this, tr("Incomplete torrent in seeding list"), tr("It appears that the state of '%1' torrent changed from 'seeding' to 'downloading'. Would you like to move it back to download list? (otherwise the torrent will simply be deleted)").arg(h.name()), QMessageBox::Yes | QMessageBox::No);
|
|
||||||
if (reponse == QMessageBox::Yes) {
|
|
||||||
qDebug("Info: a torrent was moved from finished to download tab");
|
qDebug("Info: a torrent was moved from finished to download tab");
|
||||||
deleteTorrent(hash);
|
deleteTorrent(hash);
|
||||||
BTSession->setFinishedTorrent(hash);
|
BTSession->setFinishedTorrent(hash);
|
||||||
emit torrentMovedFromFinishedList(hash);
|
emit torrentMovedFromFinishedList(hash);
|
||||||
}
|
|
||||||
else if (reponse == QMessageBox::No) {
|
|
||||||
qDebug("Deleted from the finished");
|
|
||||||
BTSession->deleteTorrent(hash, true);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(h.state() == torrent_status::checking_files){
|
if(h.state() == torrent_status::checking_files){
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
|
||||||
setRowColor(row, QString::fromUtf8("grey"));
|
setRowColor(row, QString::fromUtf8("grey"));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)h.progress()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
setRowColor(row, QString::fromUtf8("orange"));
|
setRowColor(row, QString::fromUtf8("orange"));
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
|
||||||
if(!finishedList->isColumnHidden(F_UPSPEED)) {
|
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
|
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
|
||||||
}
|
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+"/"+misc::toQString(h.num_peers() - h.num_seeds(), true)));
|
||||||
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_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
|
||||||
}
|
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,11 +250,10 @@ int FinishedTorrents::getRowFromHash(QString hash) const{
|
|||||||
// Note: does not actually pause the torrent in BT Session
|
// Note: does not actually pause the torrent in BT Session
|
||||||
void FinishedTorrents::pauseTorrent(QString hash) {
|
void FinishedTorrents::pauseTorrent(QString hash) {
|
||||||
int row = getRowFromHash(hash);
|
int row = getRowFromHash(hash);
|
||||||
if(row == -1)
|
Q_ASSERT(row != -1);
|
||||||
return;
|
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0));
|
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0));
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
|
||||||
finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant(QString::fromUtf8("0")));
|
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
|
||||||
setRowColor(row, QString::fromUtf8("red"));
|
setRowColor(row, QString::fromUtf8("red"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,14 +283,11 @@ void FinishedTorrents::deleteTorrent(QString hash){
|
|||||||
|
|
||||||
// Show torrent properties dialog
|
// Show torrent properties dialog
|
||||||
void FinishedTorrents::showProperties(const QModelIndex &index){
|
void FinishedTorrents::showProperties(const QModelIndex &index){
|
||||||
showPropertiesFromHash(finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString());
|
int row = index.row();
|
||||||
}
|
QString hash = finishedListModel->data(finishedListModel->index(row, F_HASH)).toString();
|
||||||
|
|
||||||
void FinishedTorrents::showPropertiesFromHash(QString hash){
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
properties *prop = new properties(this, BTSession, h);
|
properties *prop = new properties(this, BTSession, h);
|
||||||
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSize(QString)));
|
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSize(QString)));
|
||||||
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
|
|
||||||
prop->show();
|
prop->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,6 +313,8 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
|
|||||||
QModelIndex index;
|
QModelIndex index;
|
||||||
// Enable/disable pause/start action given the DL state
|
// Enable/disable pause/start action given the DL state
|
||||||
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||||
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
|
QString previewProgram = settings.value("Preferences/general/MediaPlayer", QString()).toString();
|
||||||
bool has_pause = false, has_start = false, has_preview = false;
|
bool has_pause = false, has_start = false, has_preview = false;
|
||||||
foreach(index, selectedIndexes) {
|
foreach(index, selectedIndexes) {
|
||||||
if(index.column() == F_NAME) {
|
if(index.column() == F_NAME) {
|
||||||
@@ -374,7 +334,7 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
|
|||||||
has_pause = true;
|
has_pause = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||||
myFinishedListMenu.addAction(actionPreview_file);
|
myFinishedListMenu.addAction(actionPreview_file);
|
||||||
has_preview = true;
|
has_preview = true;
|
||||||
}
|
}
|
||||||
@@ -387,150 +347,12 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
|
|||||||
myFinishedListMenu.addSeparator();
|
myFinishedListMenu.addSeparator();
|
||||||
myFinishedListMenu.addAction(actionSet_upload_limit);
|
myFinishedListMenu.addAction(actionSet_upload_limit);
|
||||||
myFinishedListMenu.addSeparator();
|
myFinishedListMenu.addSeparator();
|
||||||
myFinishedListMenu.addAction(actionOpen_destination_folder);
|
|
||||||
myFinishedListMenu.addAction(actionTorrent_Properties);
|
myFinishedListMenu.addAction(actionTorrent_Properties);
|
||||||
myFinishedListMenu.addSeparator();
|
|
||||||
myFinishedListMenu.addAction(actionBuy_it);
|
|
||||||
|
|
||||||
// Call menu
|
// Call menu
|
||||||
// XXX: why mapToGlobal() is not enough?
|
// XXX: why mapToGlobal() is not enough?
|
||||||
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,55));
|
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"));
|
|
||||||
for(int i=0; i<=F_RATIO; i++) {
|
|
||||||
hideshowColumn.addAction(getActionHoSCol(i));
|
|
||||||
}
|
|
||||||
// Call menu
|
|
||||||
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,55));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
* Sorting functions
|
||||||
*/
|
*/
|
||||||
@@ -548,6 +370,7 @@ void FinishedTorrents::sortFinishedList(int index){
|
|||||||
switch(index){
|
switch(index){
|
||||||
case F_SIZE:
|
case F_SIZE:
|
||||||
case F_UPSPEED:
|
case F_UPSPEED:
|
||||||
|
case F_PROGRESS:
|
||||||
sortFinishedListFloat(index, sortOrder);
|
sortFinishedListFloat(index, sortOrder);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -39,10 +39,6 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
|||||||
FinishedListDelegate *finishedListDelegate;
|
FinishedListDelegate *finishedListDelegate;
|
||||||
QStandardItemModel *finishedListModel;
|
QStandardItemModel *finishedListModel;
|
||||||
unsigned int nbFinished;
|
unsigned int nbFinished;
|
||||||
void hideOrShowColumn(int index);
|
|
||||||
bool loadHiddenColumns();
|
|
||||||
void saveHiddenColumns();
|
|
||||||
QAction* getActionHoSCol(int index);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FinishedTorrents(QObject *parent, bittorrent *BTSession);
|
FinishedTorrents(QObject *parent, bittorrent *BTSession);
|
||||||
@@ -57,7 +53,6 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
|||||||
protected slots:
|
protected slots:
|
||||||
void showProperties(const QModelIndex &index);
|
void showProperties(const QModelIndex &index);
|
||||||
void displayFinishedListMenu(const QPoint&);
|
void displayFinishedListMenu(const QPoint&);
|
||||||
void displayFinishedHoSMenu(const QPoint&);
|
|
||||||
void setRowColor(int row, QString color);
|
void setRowColor(int row, QString color);
|
||||||
void saveColWidthFinishedList() const;
|
void saveColWidthFinishedList() const;
|
||||||
void sortFinishedList(int index);
|
void sortFinishedList(int index);
|
||||||
@@ -67,11 +62,6 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
|||||||
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume);
|
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume);
|
||||||
void on_actionSet_upload_limit_triggered();
|
void on_actionSet_upload_limit_triggered();
|
||||||
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
||||||
void hideOrShowColumnName();
|
|
||||||
void hideOrShowColumnSize();
|
|
||||||
void hideOrShowColumnUpSpeed();
|
|
||||||
void hideOrShowColumnLeechers();
|
|
||||||
void hideOrShowColumnRatio();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addTorrent(QString hash);
|
void addTorrent(QString hash);
|
||||||
@@ -80,11 +70,10 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
|
|||||||
void resumeTorrent(QString hash);
|
void resumeTorrent(QString hash);
|
||||||
void propertiesSelection();
|
void propertiesSelection();
|
||||||
void deleteTorrent(QString hash);
|
void deleteTorrent(QString hash);
|
||||||
void showPropertiesFromHash(QString hash);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void torrentMovedFromFinishedList(QString);
|
void torrentMovedFromFinishedList(QString);
|
||||||
void torrentDoubleClicked(QString hash, bool finished);
|
void torrentDoubleClicked(QString hash);
|
||||||
void finishedTorrentsNumberChanged(unsigned int);
|
void finishedTorrentsNumberChanged(unsigned int);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
440
src/GUI.cpp
440
src/GUI.cpp
@@ -23,23 +23,14 @@
|
|||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#ifdef QT_4_4
|
|
||||||
#include <QLocalServer>
|
|
||||||
#include <QLocalSocket>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
|
||||||
#include "GUI.h"
|
#include "GUI.h"
|
||||||
#include "httpserver.h"
|
|
||||||
#include "downloadingTorrents.h"
|
#include "downloadingTorrents.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "createtorrent_imp.h"
|
#include "createtorrent_imp.h"
|
||||||
@@ -54,9 +45,9 @@
|
|||||||
#include "options_imp.h"
|
#include "options_imp.h"
|
||||||
#include "previewSelect.h"
|
#include "previewSelect.h"
|
||||||
#include "allocationDlg.h"
|
#include "allocationDlg.h"
|
||||||
#include "stdlib.h"
|
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* *
|
* *
|
||||||
@@ -70,21 +61,14 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
|||||||
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
|
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
systrayIntegration = settings.value(QString::fromUtf8("Preferences/General/SystrayEnabled"), true).toBool();
|
systrayIntegration = settings.value(QString::fromUtf8("Preferences/General/SystrayEnabled"), true).toBool();
|
||||||
systrayCreator = 0;
|
|
||||||
// Create tray icon
|
// Create tray icon
|
||||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
if(systrayIntegration) {
|
if(systrayIntegration) {
|
||||||
createTrayIcon();
|
createTrayIcon();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(systrayIntegration) {
|
|
||||||
// May be system startup, check again later
|
|
||||||
systrayCreator = new QTimer(this);
|
|
||||||
connect(systrayCreator, SIGNAL(timeout()), this, SLOT(createSystrayDelayed()));
|
|
||||||
systrayCreator->start(1000);
|
|
||||||
}
|
|
||||||
systrayIntegration = false;
|
systrayIntegration = false;
|
||||||
qDebug("Info: System tray unavailable");
|
qDebug("Info: System tray unavailable\n");
|
||||||
}
|
}
|
||||||
// Setting icons
|
// Setting icons
|
||||||
this->setWindowIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent32.png")));
|
this->setWindowIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent32.png")));
|
||||||
@@ -115,8 +99,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
|||||||
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
|
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
|
||||||
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
|
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
|
||||||
actionCreate_torrent->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/new.png")));
|
actionCreate_torrent->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/new.png")));
|
||||||
// Set default ratio
|
|
||||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png")));
|
|
||||||
// Fix Tool bar layout
|
// Fix Tool bar layout
|
||||||
toolBar->layout()->setSpacing(7);
|
toolBar->layout()->setSpacing(7);
|
||||||
// creating options
|
// creating options
|
||||||
@@ -130,24 +112,21 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
|||||||
connect(BTSession, SIGNAL(scanDirFoundTorrents(const QStringList&)), this, SLOT(processScannedFiles(const QStringList&)));
|
connect(BTSession, SIGNAL(scanDirFoundTorrents(const QStringList&)), this, SLOT(processScannedFiles(const QStringList&)));
|
||||||
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
|
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
|
||||||
connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString)));
|
connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString)));
|
||||||
connect(BTSession, SIGNAL(deletedTorrent(QString)), this, SLOT(deleteTorrent(QString)));
|
connect(BTSession, SIGNAL(torrent_deleted(QString, QString, bool)), this, SLOT(deleteTorrent(QString, QString, bool)));
|
||||||
connect(BTSession, SIGNAL(torrent_ratio_deleted(QString)), this, SLOT(deleteRatioTorrent(QString)));
|
|
||||||
connect(BTSession, SIGNAL(pausedTorrent(QString)), this, SLOT(pauseTorrent(QString)));
|
|
||||||
qDebug("create tabWidget");
|
qDebug("create tabWidget");
|
||||||
tabs = new QTabWidget();
|
tabs = new QTabWidget();
|
||||||
// Download torrents tab
|
// Download torrents tab
|
||||||
downloadingTorrentTab = new DownloadingTorrents(this, BTSession);
|
downloadingTorrentTab = new DownloadingTorrents(this, BTSession);
|
||||||
tabs->addTab(downloadingTorrentTab, tr("Downloads") + QString::fromUtf8(" (0/0)"));
|
tabs->addTab(downloadingTorrentTab, tr("Downloads") + QString::fromUtf8(" (0)"));
|
||||||
tabs->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
|
tabs->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
|
||||||
vboxLayout->addWidget(tabs);
|
vboxLayout->addWidget(tabs);
|
||||||
connect(downloadingTorrentTab, SIGNAL(unfinishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateUnfinishedTorrentNumber(unsigned int)));
|
connect(downloadingTorrentTab, SIGNAL(unfinishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateUnfinishedTorrentNumber(unsigned int)));
|
||||||
connect(downloadingTorrentTab, SIGNAL(torrentDoubleClicked(QString, bool)), this, SLOT(torrentDoubleClicked(QString, bool)));
|
connect(downloadingTorrentTab, SIGNAL(torrentDoubleClicked(QString)), this, SLOT(togglePausedState(QString)));
|
||||||
// Finished torrents tab
|
// Finished torrents tab
|
||||||
finishedTorrentTab = new FinishedTorrents(this, BTSession);
|
finishedTorrentTab = new FinishedTorrents(this, BTSession);
|
||||||
tabs->addTab(finishedTorrentTab, tr("Finished") + QString::fromUtf8(" (0/0)"));
|
tabs->addTab(finishedTorrentTab, tr("Finished") + QString::fromUtf8(" (0)"));
|
||||||
tabs->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
|
tabs->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
|
||||||
connect(finishedTorrentTab, SIGNAL(torrentDoubleClicked(QString, bool)), this, SLOT(torrentDoubleClicked(QString, bool)));
|
connect(finishedTorrentTab, SIGNAL(torrentDoubleClicked(QString)), this, SLOT(togglePausedState(QString)));
|
||||||
|
|
||||||
connect(finishedTorrentTab, SIGNAL(finishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateFinishedTorrentNumber(unsigned int)));
|
connect(finishedTorrentTab, SIGNAL(finishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateFinishedTorrentNumber(unsigned int)));
|
||||||
// Smooth torrent switching between tabs Downloading <--> Finished
|
// Smooth torrent switching between tabs Downloading <--> Finished
|
||||||
connect(downloadingTorrentTab, SIGNAL(torrentFinished(QString)), finishedTorrentTab, SLOT(addTorrent(QString)));
|
connect(downloadingTorrentTab, SIGNAL(torrentFinished(QString)), finishedTorrentTab, SLOT(addTorrent(QString)));
|
||||||
@@ -171,42 +150,21 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
|||||||
readSettings();
|
readSettings();
|
||||||
// Add torrent given on command line
|
// Add torrent given on command line
|
||||||
processParams(torrentCmdLine);
|
processParams(torrentCmdLine);
|
||||||
// Initialize Web UI
|
|
||||||
httpServer = 0;
|
|
||||||
if(settings.value("Preferences/WebUI/Enabled", false).toBool())
|
|
||||||
{
|
|
||||||
quint16 port = settings.value("Preferences/WebUI/Port", 8080).toUInt();
|
|
||||||
QString username = settings.value("Preferences/WebUI/Username", "").toString();
|
|
||||||
QString password = settings.value("Preferences/WebUI/Password", "").toString();
|
|
||||||
initWebUi(username, password, port);
|
|
||||||
}
|
|
||||||
// Use a tcp server to allow only one instance of qBittorrent
|
// Use a tcp server to allow only one instance of qBittorrent
|
||||||
#ifdef QT_4_4
|
tcpServer = new QTcpServer();
|
||||||
localServer = new QLocalServer();
|
if (!tcpServer->listen(QHostAddress::LocalHost, 1666)) {
|
||||||
QString uid = QString::number(getuid());
|
|
||||||
if (!localServer->listen("qBittorrent-"+uid)) {
|
|
||||||
#else
|
|
||||||
localServer = new QTcpServer();
|
|
||||||
if (!localServer->listen(QHostAddress::LocalHost)) {
|
|
||||||
#endif
|
|
||||||
std::cerr << "Couldn't create socket, single instance mode won't work...\n";
|
std::cerr << "Couldn't create socket, single instance mode won't work...\n";
|
||||||
}
|
}
|
||||||
#ifndef QT_4_4
|
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
||||||
else {
|
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
|
||||||
settings.setValue(QString::fromUtf8("uniqueInstancePort"), localServer->serverPort());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
|
||||||
// Start connection checking timer
|
// Start connection checking timer
|
||||||
checkConnect = new QTimer(this);
|
checkConnect = new QTimer(this);
|
||||||
connect(checkConnect, SIGNAL(timeout()), this, SLOT(checkConnectionStatus()));
|
connect(checkConnect, SIGNAL(timeout()), this, SLOT(checkConnectionStatus()));
|
||||||
checkConnect->start(5000);
|
checkConnect->start(5000);
|
||||||
|
previewProcess = new QProcess(this);
|
||||||
|
connect(previewProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(cleanTempPreviewFile(int, QProcess::ExitStatus)));
|
||||||
// Accept drag 'n drops
|
// Accept drag 'n drops
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
if(!settings.value(QString::fromUtf8("Preferences/General/StartMinimized"), false).toBool()) {
|
|
||||||
show();
|
show();
|
||||||
}
|
|
||||||
createKeyboardShortcuts();
|
createKeyboardShortcuts();
|
||||||
qDebug("GUI Built");
|
qDebug("GUI Built");
|
||||||
}
|
}
|
||||||
@@ -220,57 +178,23 @@ GUI::~GUI() {
|
|||||||
delete downloadingTorrentTab;
|
delete downloadingTorrentTab;
|
||||||
delete finishedTorrentTab;
|
delete finishedTorrentTab;
|
||||||
delete checkConnect;
|
delete checkConnect;
|
||||||
qDebug("1");
|
|
||||||
if(systrayCreator) {
|
|
||||||
delete systrayCreator;
|
|
||||||
}
|
|
||||||
if(systrayIntegration) {
|
if(systrayIntegration) {
|
||||||
delete myTrayIcon;
|
delete myTrayIcon;
|
||||||
delete myTrayIconMenu;
|
delete myTrayIconMenu;
|
||||||
}
|
}
|
||||||
qDebug("2");
|
delete tcpServer;
|
||||||
delete localServer;
|
previewProcess->kill();
|
||||||
|
previewProcess->waitForFinished();
|
||||||
|
delete previewProcess;
|
||||||
delete connecStatusLblIcon;
|
delete connecStatusLblIcon;
|
||||||
delete tabs;
|
delete tabs;
|
||||||
// HTTP Server
|
|
||||||
if(httpServer)
|
|
||||||
delete httpServer;
|
|
||||||
qDebug("3");
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
delete switchSearchShortcut;
|
delete switchSearchShortcut;
|
||||||
delete switchSearchShortcut2;
|
delete switchSearchShortcut2;
|
||||||
delete switchDownShortcut;
|
delete switchDownShortcut;
|
||||||
delete switchUpShortcut;
|
delete switchUpShortcut;
|
||||||
delete switchRSSShortcut;
|
delete switchRSSShortcut;
|
||||||
qDebug("4");
|
|
||||||
delete BTSession;
|
delete BTSession;
|
||||||
qDebug("5");
|
|
||||||
}
|
|
||||||
|
|
||||||
void GUI::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 GUI::on_actionWebsite_triggered() const {
|
void GUI::on_actionWebsite_triggered() const {
|
||||||
@@ -419,7 +343,7 @@ void GUI::balloonClicked() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GUI::acceptConnection() {
|
void GUI::acceptConnection() {
|
||||||
clientConnection = localServer->nextPendingConnection();
|
clientConnection = tcpServer->nextPendingConnection();
|
||||||
connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket()));
|
connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket()));
|
||||||
qDebug("accepted connection from another instance");
|
qDebug("accepted connection from another instance");
|
||||||
}
|
}
|
||||||
@@ -465,47 +389,9 @@ void GUI::on_actionPreview_file_triggered() {
|
|||||||
new previewSelect(this, h);
|
new previewSelect(this, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::openDestinationFolder() const {
|
void GUI::cleanTempPreviewFile(int, QProcess::ExitStatus) const {
|
||||||
QStringList hashes;
|
if(!QFile::remove(QDir::tempPath()+QDir::separator()+QString::fromUtf8("qBT_preview.tmp"))) {
|
||||||
switch(tabs->currentIndex()){
|
std::cerr << "Couldn't remove temporary file: " << (QDir::tempPath()+QDir::separator()+QString::fromUtf8("qBT_preview.tmp")).toUtf8().data() << "\n";
|
||||||
case 0:
|
|
||||||
hashes = downloadingTorrentTab->getSelectedTorrents(true);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
hashes = finishedTorrentTab->getSelectedTorrents(true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QString hash;
|
|
||||||
QStringList pathsList;
|
|
||||||
foreach(hash, hashes) {
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
|
||||||
QString savePath = h.save_path();
|
|
||||||
if(!pathsList.contains(savePath)) {
|
|
||||||
pathsList.append(savePath);
|
|
||||||
QDesktopServices::openUrl(QString("file://")+savePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GUI::goBuyPage() const {
|
|
||||||
QStringList hashes;
|
|
||||||
switch(tabs->currentIndex()){
|
|
||||||
case 0:
|
|
||||||
hashes = downloadingTorrentTab->getSelectedTorrents(true);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
hashes = finishedTorrentTab->getSelectedTorrents(true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QString hash;
|
|
||||||
QStringList pathsList;
|
|
||||||
foreach(hash, hashes) {
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
|
||||||
QDesktopServices::openUrl("http://match.sharemonkey.com/?info_hash="+hash+"&n="+h.name()+"&cid=33");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,10 +403,24 @@ void GUI::on_actionExit_triggered() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GUI::previewFile(QString filePath) {
|
void GUI::previewFile(QString filePath) {
|
||||||
QDesktopServices::openUrl(QString("file://")+filePath);
|
// Check if there is already one preview running
|
||||||
|
if(previewProcess->state() == QProcess::NotRunning) {
|
||||||
|
// First copy temporarily (XXX: is it necessary?)
|
||||||
|
QString tmpPath = QDir::tempPath()+QDir::separator()+QString::fromUtf8("qBT_preview.tmp");
|
||||||
|
QFile::remove(tmpPath);
|
||||||
|
QFile::copy(filePath, tmpPath);
|
||||||
|
// Launch program preview
|
||||||
|
QStringList params;
|
||||||
|
params << tmpPath;
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
|
QString previewProgram = settings.value(QString::fromUtf8("Preferences/General/MediaPlayer"), QString()).toString();
|
||||||
|
previewProcess->start(previewProgram, params, QIODevice::ReadOnly);
|
||||||
|
}else{
|
||||||
|
QMessageBox::critical(0, tr("Preview process already running"), tr("There is already another preview process running.\nPlease close the other one first."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GUI::getCurrentTabIndex() const{
|
unsigned int GUI::getCurrentTabIndex() const{
|
||||||
if(isMinimized() || isHidden())
|
if(isMinimized() || isHidden())
|
||||||
return -1;
|
return -1;
|
||||||
return tabs->currentIndex();
|
return tabs->currentIndex();
|
||||||
@@ -574,7 +474,7 @@ void GUI::on_actionAbout_triggered() {
|
|||||||
|
|
||||||
// Called when we close the program
|
// Called when we close the program
|
||||||
void GUI::closeEvent(QCloseEvent *e) {
|
void GUI::closeEvent(QCloseEvent *e) {
|
||||||
|
qDebug("Mainwindow received closeEvent");
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
bool goToSystrayOnExit = settings.value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool();
|
bool goToSystrayOnExit = settings.value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool();
|
||||||
if(!force_exit && systrayIntegration && goToSystrayOnExit && !this->isHidden()) {
|
if(!force_exit && systrayIntegration && goToSystrayOnExit && !this->isHidden()) {
|
||||||
@@ -586,18 +486,15 @@ void GUI::closeEvent(QCloseEvent *e) {
|
|||||||
show();
|
show();
|
||||||
if(!isMaximized())
|
if(!isMaximized())
|
||||||
showNormal();
|
showNormal();
|
||||||
if(e->spontaneous() == true || force_exit == true) {
|
|
||||||
if(QMessageBox::question(this,
|
if(QMessageBox::question(this,
|
||||||
tr("Are you sure you want to quit?")+QString::fromUtf8(" -- ")+tr("qBittorrent"),
|
tr("Are you sure you want to quit?")+QString::fromUtf8(" -- ")+tr("qBittorrent"),
|
||||||
tr("The download list is not empty.\nAre you sure you want to quit qBittorrent?"),
|
tr("The download list is not empty.\nAre you sure you want to quit qBittorrent?"),
|
||||||
tr("&Yes"), tr("&No"),
|
tr("&Yes"), tr("&No"),
|
||||||
QString(), 0, 1)) {
|
QString(), 0, 1)) {
|
||||||
e->ignore();
|
e->ignore();
|
||||||
force_exit = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
hide();
|
hide();
|
||||||
if(systrayIntegration) {
|
if(systrayIntegration) {
|
||||||
// Hide tray icon
|
// Hide tray icon
|
||||||
@@ -613,17 +510,16 @@ void GUI::closeEvent(QCloseEvent *e) {
|
|||||||
qApp->exit();
|
qApp->exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Display window to create a torrent
|
// Display window to create a torrent
|
||||||
void GUI::on_actionCreate_torrent_triggered() {
|
void GUI::on_actionCreate_torrent_triggered() {
|
||||||
createtorrent *ct = new createtorrent(this);
|
createtorrent *ct = new createtorrent(this);
|
||||||
connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString)));
|
connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when we minimize the program
|
// Called when we minimize the program
|
||||||
void GUI::hideEvent(QHideEvent *e) {
|
void GUI::hideEvent(QHideEvent *e) {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
if(systrayIntegration && settings.value(QString::fromUtf8("Preferences/General/MinimizeToTray"), false).toBool()) {
|
if(systrayIntegration && settings.value(QString::fromUtf8("Preferences/General/MinimizeToTray"), false).toBool() && !e->spontaneous()) {
|
||||||
// Hide window
|
// Hide window
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
@@ -661,7 +557,7 @@ void GUI::dropEvent(QDropEvent *event) {
|
|||||||
if(useTorrentAdditionDialog) {
|
if(useTorrentAdditionDialog) {
|
||||||
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
|
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
|
||||||
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
|
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
|
||||||
connect(dialog, SIGNAL(setInfoBarGUI(QString, QColor)), downloadingTorrentTab, SLOT(setInfoBar(QString, QColor)));
|
connect(dialog, SIGNAL(setInfoBarGUI(QString, QString)), downloadingTorrentTab, SLOT(setInfoBar(QString, QString)));
|
||||||
dialog->showLoad(file);
|
dialog->showLoad(file);
|
||||||
}else{
|
}else{
|
||||||
BTSession->addTorrent(file);
|
BTSession->addTorrent(file);
|
||||||
@@ -702,7 +598,7 @@ void GUI::on_actionOpen_triggered() {
|
|||||||
if(useTorrentAdditionDialog) {
|
if(useTorrentAdditionDialog) {
|
||||||
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
|
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
|
||||||
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
|
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
|
||||||
connect(dialog, SIGNAL(setInfoBarGUI(QString, QColor)), downloadingTorrentTab, SLOT(setInfoBar(QString, QColor)));
|
connect(dialog, SIGNAL(setInfoBarGUI(QString, QString)), downloadingTorrentTab, SLOT(setInfoBar(QString, QString)));
|
||||||
dialog->showLoad(pathsList.at(i));
|
dialog->showLoad(pathsList.at(i));
|
||||||
}else{
|
}else{
|
||||||
BTSession->addTorrent(pathsList.at(i));
|
BTSession->addTorrent(pathsList.at(i));
|
||||||
@@ -755,22 +651,27 @@ void GUI::on_actionDelete_Permanently_triggered() {
|
|||||||
QString fileName = h.name();
|
QString fileName = h.name();
|
||||||
// Remove the torrent
|
// Remove the torrent
|
||||||
BTSession->deleteTorrent(hash, true);
|
BTSession->deleteTorrent(hash, true);
|
||||||
|
// Delete item from list
|
||||||
|
if(inDownloadList) {
|
||||||
|
downloadingTorrentTab->deleteTorrent(hash);
|
||||||
|
} else {
|
||||||
|
finishedTorrentTab->deleteTorrent(hash);
|
||||||
|
}
|
||||||
// Update info bar
|
// Update info bar
|
||||||
downloadingTorrentTab->setInfoBar(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName));
|
downloadingTorrentTab->setInfoBar(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::deleteRatioTorrent(QString fileName) {
|
void GUI::deleteTorrent(QString hash, QString fileName, bool finished) {
|
||||||
|
if(finished) {
|
||||||
|
finishedTorrentTab->deleteTorrent(hash);
|
||||||
|
} else {
|
||||||
|
downloadingTorrentTab->deleteTorrent(hash);
|
||||||
|
}
|
||||||
// Update info bar
|
// Update info bar
|
||||||
downloadingTorrentTab->setInfoBar(tr("'%1' was removed because its ratio reached the maximum value you set.", "%1 is a file name").arg(fileName));
|
downloadingTorrentTab->setInfoBar(tr("'%1' was removed because its ratio reached the maximum value you set.", "%1 is a file name").arg(fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::deleteTorrent(QString hash) {
|
|
||||||
// Delete item from list
|
|
||||||
downloadingTorrentTab->deleteTorrent(hash);
|
|
||||||
finishedTorrentTab->deleteTorrent(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete selected items in the list
|
// delete selected items in the list
|
||||||
void GUI::on_actionDelete_triggered() {
|
void GUI::on_actionDelete_triggered() {
|
||||||
QStringList hashes;
|
QStringList hashes;
|
||||||
@@ -815,6 +716,12 @@ void GUI::on_actionDelete_triggered() {
|
|||||||
QString fileName = h.name();
|
QString fileName = h.name();
|
||||||
// Remove the torrent
|
// Remove the torrent
|
||||||
BTSession->deleteTorrent(hash, false);
|
BTSession->deleteTorrent(hash, false);
|
||||||
|
// Delete item from list
|
||||||
|
if(inDownloadList) {
|
||||||
|
downloadingTorrentTab->deleteTorrent(hash);
|
||||||
|
} else {
|
||||||
|
finishedTorrentTab->deleteTorrent(hash);
|
||||||
|
}
|
||||||
// Update info bar
|
// Update info bar
|
||||||
downloadingTorrentTab->setInfoBar(tr("'%1' was removed.", "'xxx.avi' was removed.").arg(fileName));
|
downloadingTorrentTab->setInfoBar(tr("'%1' was removed.", "'xxx.avi' was removed.").arg(fileName));
|
||||||
}
|
}
|
||||||
@@ -882,12 +789,7 @@ void GUI::processDownloadedFiles(QString path, QString url) {
|
|||||||
void GUI::configureSession(bool deleteOptions) {
|
void GUI::configureSession(bool deleteOptions) {
|
||||||
qDebug("Configuring session");
|
qDebug("Configuring session");
|
||||||
// General
|
// General
|
||||||
bool new_displaySpeedInTitle = options->speedInTitleBar();
|
displaySpeedInTitle = options->speedInTitleBar();
|
||||||
if(!new_displaySpeedInTitle && new_displaySpeedInTitle != displaySpeedInTitle) {
|
|
||||||
// Reset title
|
|
||||||
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
|
|
||||||
}
|
|
||||||
displaySpeedInTitle = new_displaySpeedInTitle;
|
|
||||||
unsigned int new_refreshInterval = options->getRefreshInterval();
|
unsigned int new_refreshInterval = options->getRefreshInterval();
|
||||||
if(refreshInterval != new_refreshInterval) {
|
if(refreshInterval != new_refreshInterval) {
|
||||||
refreshInterval = new_refreshInterval;
|
refreshInterval = new_refreshInterval;
|
||||||
@@ -902,8 +804,6 @@ void GUI::configureSession(bool deleteOptions) {
|
|||||||
if(options->getScanDir().isNull()) {
|
if(options->getScanDir().isNull()) {
|
||||||
BTSession->disableDirectoryScanning();
|
BTSession->disableDirectoryScanning();
|
||||||
}else{
|
}else{
|
||||||
//Interval first
|
|
||||||
BTSession->setTimerScanInterval(options->getFolderScanInterval());
|
|
||||||
BTSession->enableDirectoryScanning(options->getScanDir());
|
BTSession->enableDirectoryScanning(options->getScanDir());
|
||||||
}
|
}
|
||||||
// Connection
|
// Connection
|
||||||
@@ -950,21 +850,12 @@ void GUI::configureSession(bool deleteOptions) {
|
|||||||
// * Proxy settings
|
// * Proxy settings
|
||||||
proxy_settings proxySettings;
|
proxy_settings proxySettings;
|
||||||
if(options->isProxyEnabled()) {
|
if(options->isProxyEnabled()) {
|
||||||
proxySettings.hostname = options->getProxyIp().toStdString();
|
|
||||||
proxySettings.port = options->getProxyPort();
|
|
||||||
if(options->isProxyAuthEnabled()) {
|
|
||||||
proxySettings.username = options->getProxyUsername().toStdString();
|
|
||||||
proxySettings.password = options->getProxyPassword().toStdString();
|
|
||||||
}
|
|
||||||
QString proxy_str;
|
|
||||||
switch(options->getProxyType()) {
|
switch(options->getProxyType()) {
|
||||||
case HTTP:
|
case HTTP:
|
||||||
proxySettings.type = proxy_settings::http;
|
proxySettings.type = proxy_settings::http;
|
||||||
proxy_str = misc::toQString("http://")+options->getProxyIp()+":"+misc::toQString(proxySettings.port);
|
|
||||||
break;
|
break;
|
||||||
case HTTP_PW:
|
case HTTP_PW:
|
||||||
proxySettings.type = proxy_settings::http_pw;
|
proxySettings.type = proxy_settings::http_pw;
|
||||||
proxy_str = misc::toQString("http://")+options->getProxyUsername()+":"+options->getProxyPassword()+"@"+options->getProxyIp()+":"+misc::toQString(proxySettings.port);
|
|
||||||
break;
|
break;
|
||||||
case SOCKS5:
|
case SOCKS5:
|
||||||
proxySettings.type = proxy_settings::socks5;
|
proxySettings.type = proxy_settings::socks5;
|
||||||
@@ -973,32 +864,17 @@ void GUI::configureSession(bool deleteOptions) {
|
|||||||
proxySettings.type = proxy_settings::socks5_pw;
|
proxySettings.type = proxy_settings::socks5_pw;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!proxy_str.isEmpty()) {
|
proxySettings.hostname = options->getProxyIp().toStdString();
|
||||||
// We need this for urllib in search engine plugins
|
proxySettings.port = options->getProxyPort();
|
||||||
#ifdef Q_WS_WIN
|
if(options->isProxyAuthEnabled()) {
|
||||||
char proxystr[512];
|
proxySettings.username = options->getProxyUsername().toStdString();
|
||||||
snprintf(proxystr, 512, "http_proxy=%s", proxy_str.toUtf8().data());
|
proxySettings.password = options->getProxyPassword().toStdString();
|
||||||
putenv(proxystr);
|
|
||||||
#else
|
|
||||||
setenv("http_proxy", proxy_str.toUtf8().data(), 1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
#ifdef Q_WS_WIN
|
|
||||||
putenv("http_proxy=");
|
|
||||||
#else
|
|
||||||
unsetenv("http_proxy");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT());
|
BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT());
|
||||||
// * Session settings
|
// * Session settings
|
||||||
session_settings sessionSettings;
|
session_settings sessionSettings;
|
||||||
if(options->shouldSpoofAzureus()) {
|
|
||||||
sessionSettings.user_agent = "Azureus 3.0.5.2";
|
|
||||||
} else {
|
|
||||||
sessionSettings.user_agent = "qBittorrent "VERSION;
|
sessionSettings.user_agent = "qBittorrent "VERSION;
|
||||||
}
|
|
||||||
sessionSettings.upnp_ignore_nonrouters = true;
|
|
||||||
BTSession->setSessionSettings(sessionSettings);
|
BTSession->setSessionSettings(sessionSettings);
|
||||||
// Bittorrent
|
// Bittorrent
|
||||||
// * Max connections limit
|
// * Max connections limit
|
||||||
@@ -1009,13 +885,10 @@ void GUI::configureSession(bool deleteOptions) {
|
|||||||
BTSession->setMaxUploadsPerTorrent(options->getMaxUploadsPerTorrent());
|
BTSession->setMaxUploadsPerTorrent(options->getMaxUploadsPerTorrent());
|
||||||
// * DHT
|
// * DHT
|
||||||
if(options->isDHTEnabled()) {
|
if(options->isDHTEnabled()) {
|
||||||
|
BTSession->enableDHT(true);
|
||||||
|
downloadingTorrentTab->setInfoBar(tr("DHT support [ON], port: %1").arg(new_listenPort), QString::fromUtf8("blue"));
|
||||||
// Set DHT Port
|
// Set DHT Port
|
||||||
BTSession->setDHTPort(new_listenPort);
|
BTSession->setDHTPort(new_listenPort);
|
||||||
if(BTSession->enableDHT(true)) {
|
|
||||||
downloadingTorrentTab->setInfoBar(tr("DHT support [ON], port: %1").arg(new_listenPort), QString::fromUtf8("blue"));
|
|
||||||
} else {
|
|
||||||
downloadingTorrentTab->setInfoBar(tr("DHT support [OFF]"), QString::fromUtf8("red"));
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
BTSession->enableDHT(false);
|
BTSession->enableDHT(false);
|
||||||
downloadingTorrentTab->setInfoBar(tr("DHT support [OFF]"), QString::fromUtf8("blue"));
|
downloadingTorrentTab->setInfoBar(tr("DHT support [OFF]"), QString::fromUtf8("blue"));
|
||||||
@@ -1079,45 +952,11 @@ void GUI::configureSession(bool deleteOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateUnfinishedTorrentNumber(unsigned int nb) {
|
void GUI::updateUnfinishedTorrentNumber(unsigned int nb) {
|
||||||
unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb();
|
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb)+QString::fromUtf8(")"));
|
||||||
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateFinishedTorrentNumber(unsigned int nb) {
|
void GUI::updateFinishedTorrentNumber(unsigned int nb) {
|
||||||
unsigned int paused = BTSession->getFinishedPausedTorrentsNb();
|
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb)+QString::fromUtf8(")"));
|
||||||
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow to change action on double-click
|
|
||||||
void GUI::torrentDoubleClicked(QString hash, bool finished) {
|
|
||||||
int action;
|
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
|
||||||
|
|
||||||
if(finished) {
|
|
||||||
action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorFN"), 0).toInt();
|
|
||||||
} else {
|
|
||||||
action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorDl"), 0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(action) {
|
|
||||||
case TOGGLE_PAUSE:
|
|
||||||
this->togglePausedState(hash);
|
|
||||||
break;
|
|
||||||
case OPEN_DEST: {
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
|
||||||
QString savePath = h.save_path();
|
|
||||||
QDesktopServices::openUrl(QUrl(savePath));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SHOW_PROPERTIES :
|
|
||||||
if(finished) {
|
|
||||||
finishedTorrentTab->showPropertiesFromHash(hash);
|
|
||||||
} else {
|
|
||||||
downloadingTorrentTab->showPropertiesFromHash(hash);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle paused state of selected torrent
|
// Toggle paused state of selected torrent
|
||||||
@@ -1132,19 +971,15 @@ void GUI::togglePausedState(QString hash) {
|
|||||||
downloadingTorrentTab->setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(h.name()));
|
downloadingTorrentTab->setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(h.name()));
|
||||||
if(inDownloadList) {
|
if(inDownloadList) {
|
||||||
downloadingTorrentTab->resumeTorrent(hash);
|
downloadingTorrentTab->resumeTorrent(hash);
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
|
||||||
}else{
|
}else{
|
||||||
finishedTorrentTab->resumeTorrent(hash);
|
finishedTorrentTab->resumeTorrent(hash);
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
BTSession->pauseTorrent(hash);
|
BTSession->pauseTorrent(hash);
|
||||||
if(inDownloadList) {
|
if(inDownloadList) {
|
||||||
downloadingTorrentTab->pauseTorrent(hash);
|
downloadingTorrentTab->pauseTorrent(hash);
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
|
||||||
}else{
|
}else{
|
||||||
finishedTorrentTab->pauseTorrent(hash);
|
finishedTorrentTab->pauseTorrent(hash);
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
|
||||||
}
|
}
|
||||||
downloadingTorrentTab->setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(h.name()));
|
downloadingTorrentTab->setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(h.name()));
|
||||||
}
|
}
|
||||||
@@ -1153,8 +988,30 @@ void GUI::togglePausedState(QString hash) {
|
|||||||
// Pause All Downloads in DL list
|
// Pause All Downloads in DL list
|
||||||
void GUI::on_actionPause_All_triggered() {
|
void GUI::on_actionPause_All_triggered() {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
QStringList DL_hashes = BTSession->getUnfinishedTorrents();
|
bool inDownloadList = true;
|
||||||
QStringList F_hashes = BTSession->getFinishedTorrents();
|
bool hidden = false;
|
||||||
|
switch(getCurrentTabIndex()) {
|
||||||
|
case -1:
|
||||||
|
hidden = true;
|
||||||
|
inDownloadList = false;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
inDownloadList = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DL_hashes;
|
||||||
|
QStringList F_hashes;
|
||||||
|
if(hidden || inDownloadList) {
|
||||||
|
DL_hashes = BTSession->getUnfinishedTorrents();
|
||||||
|
}
|
||||||
|
if(hidden || !inDownloadList) {
|
||||||
|
F_hashes = BTSession->getFinishedTorrents();
|
||||||
|
}
|
||||||
QString hash;
|
QString hash;
|
||||||
foreach(hash, DL_hashes) {
|
foreach(hash, DL_hashes) {
|
||||||
if(BTSession->pauseTorrent(hash)){
|
if(BTSession->pauseTorrent(hash)){
|
||||||
@@ -1168,12 +1025,9 @@ void GUI::on_actionPause_All_triggered() {
|
|||||||
finishedTorrentTab->pauseTorrent(hash);
|
finishedTorrentTab->pauseTorrent(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(change) {
|
if(change)
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
|
||||||
downloadingTorrentTab->setInfoBar(tr("All downloads were paused."));
|
downloadingTorrentTab->setInfoBar(tr("All downloads were paused."));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// pause selected items in the list
|
// pause selected items in the list
|
||||||
void GUI::on_actionPause_triggered() {
|
void GUI::on_actionPause_triggered() {
|
||||||
@@ -1192,28 +1046,41 @@ void GUI::on_actionPause_triggered() {
|
|||||||
if(BTSession->pauseTorrent(hash)){
|
if(BTSession->pauseTorrent(hash)){
|
||||||
if(inDownloadList) {
|
if(inDownloadList) {
|
||||||
downloadingTorrentTab->pauseTorrent(hash);
|
downloadingTorrentTab->pauseTorrent(hash);
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
|
||||||
} else {
|
} else {
|
||||||
finishedTorrentTab->pauseTorrent(hash);
|
finishedTorrentTab->pauseTorrent(hash);
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
|
||||||
}
|
}
|
||||||
downloadingTorrentTab->setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(BTSession->getTorrentHandle(hash).name()));
|
downloadingTorrentTab->setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(BTSession->getTorrentHandle(hash).name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::pauseTorrent(QString hash) {
|
|
||||||
downloadingTorrentTab->pauseTorrent(hash);
|
|
||||||
finishedTorrentTab->pauseTorrent(hash);
|
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resume All Downloads in DL list
|
// Resume All Downloads in DL list
|
||||||
void GUI::on_actionStart_All_triggered() {
|
void GUI::on_actionStart_All_triggered() {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
QStringList DL_hashes = BTSession->getUnfinishedTorrents();
|
bool inDownloadList = true;
|
||||||
QStringList F_hashes = BTSession->getFinishedTorrents();
|
bool hidden = false;
|
||||||
|
switch(getCurrentTabIndex()) {
|
||||||
|
case -1:
|
||||||
|
hidden = true;
|
||||||
|
inDownloadList = false;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
inDownloadList = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DL_hashes;
|
||||||
|
QStringList F_hashes;
|
||||||
|
if(hidden || inDownloadList) {
|
||||||
|
DL_hashes = BTSession->getUnfinishedTorrents();
|
||||||
|
}
|
||||||
|
if(hidden || !inDownloadList) {
|
||||||
|
F_hashes = BTSession->getFinishedTorrents();
|
||||||
|
}
|
||||||
QString hash;
|
QString hash;
|
||||||
foreach(hash, DL_hashes) {
|
foreach(hash, DL_hashes) {
|
||||||
if(BTSession->resumeTorrent(hash)){
|
if(BTSession->resumeTorrent(hash)){
|
||||||
@@ -1227,12 +1094,9 @@ void GUI::on_actionStart_All_triggered() {
|
|||||||
finishedTorrentTab->resumeTorrent(hash);
|
finishedTorrentTab->resumeTorrent(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(change) {
|
if(change)
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
|
||||||
downloadingTorrentTab->setInfoBar(tr("All downloads were resumed."));
|
downloadingTorrentTab->setInfoBar(tr("All downloads were resumed."));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// start selected items in the list
|
// start selected items in the list
|
||||||
void GUI::on_actionStart_triggered() {
|
void GUI::on_actionStart_triggered() {
|
||||||
@@ -1251,10 +1115,8 @@ void GUI::on_actionStart_triggered() {
|
|||||||
if(BTSession->resumeTorrent(hash)){
|
if(BTSession->resumeTorrent(hash)){
|
||||||
if(inDownloadList) {
|
if(inDownloadList) {
|
||||||
downloadingTorrentTab->resumeTorrent(hash);
|
downloadingTorrentTab->resumeTorrent(hash);
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
|
||||||
} else {
|
} else {
|
||||||
finishedTorrentTab->resumeTorrent(hash);
|
finishedTorrentTab->resumeTorrent(hash);
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
|
||||||
}
|
}
|
||||||
downloadingTorrentTab->setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(BTSession->getTorrentHandle(hash).name()));
|
downloadingTorrentTab->setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(BTSession->getTorrentHandle(hash).name()));
|
||||||
}
|
}
|
||||||
@@ -1281,9 +1143,6 @@ void GUI::on_actionTorrent_Properties_triggered() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateLists() {
|
void GUI::updateLists() {
|
||||||
// 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
|
|
||||||
switch(getCurrentTabIndex()){
|
switch(getCurrentTabIndex()){
|
||||||
case 0:
|
case 0:
|
||||||
downloadingTorrentTab->updateDlList();
|
downloadingTorrentTab->updateDlList();
|
||||||
@@ -1313,7 +1172,8 @@ void GUI::trackerAuthenticationRequired(QTorrentHandle& h) {
|
|||||||
void GUI::checkConnectionStatus() {
|
void GUI::checkConnectionStatus() {
|
||||||
// qDebug("Checking connection status");
|
// qDebug("Checking connection status");
|
||||||
// Update Ratio
|
// Update Ratio
|
||||||
updateRatio();
|
if(getCurrentTabIndex() == 0)
|
||||||
|
downloadingTorrentTab->updateRatio();
|
||||||
// update global informations
|
// update global informations
|
||||||
if(systrayIntegration) {
|
if(systrayIntegration) {
|
||||||
QString html = "<div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'>";
|
QString html = "<div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'>";
|
||||||
@@ -1361,37 +1221,9 @@ void GUI::downloadFromURLList(const QStringList& urls) {
|
|||||||
* *
|
* *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
void GUI::createSystrayDelayed() {
|
|
||||||
static int timeout = 10;
|
|
||||||
if(QSystemTrayIcon::isSystemTrayAvailable()) {
|
|
||||||
// Ok, systray integration is now supported
|
|
||||||
// Create systray icon
|
|
||||||
createTrayIcon();
|
|
||||||
systrayIntegration = true;
|
|
||||||
delete systrayCreator;
|
|
||||||
systrayCreator = 0;
|
|
||||||
} else {
|
|
||||||
if(timeout) {
|
|
||||||
// Retry a bit later
|
|
||||||
systrayCreator->start(1000);
|
|
||||||
--timeout;
|
|
||||||
} else {
|
|
||||||
// Timed out, apparently system really does not
|
|
||||||
// support systray icon
|
|
||||||
delete systrayCreator;
|
|
||||||
systrayCreator = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GUI::createTrayIcon() {
|
void GUI::createTrayIcon() {
|
||||||
// Tray icon
|
// Tray icon
|
||||||
#ifdef Q_WS_WIN
|
|
||||||
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent16.png")), this);
|
|
||||||
#endif
|
|
||||||
#ifndef Q_WS_WIN
|
|
||||||
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent22.png")), this);
|
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/qbittorrent22.png")), this);
|
||||||
#endif
|
|
||||||
// Tray icon Menu
|
// Tray icon Menu
|
||||||
myTrayIconMenu = new QMenu(this);
|
myTrayIconMenu = new QMenu(this);
|
||||||
myTrayIconMenu->addAction(actionOpen);
|
myTrayIconMenu->addAction(actionOpen);
|
||||||
@@ -1433,40 +1265,10 @@ void GUI::OptionsSaved(QString info, bool deleteOptions) {
|
|||||||
systrayIntegration = newSystrayIntegration;
|
systrayIntegration = newSystrayIntegration;
|
||||||
// Update info bar
|
// Update info bar
|
||||||
downloadingTorrentTab->setInfoBar(info);
|
downloadingTorrentTab->setInfoBar(info);
|
||||||
// Update Web UI
|
|
||||||
if (options->isWebUiEnabled())
|
|
||||||
{
|
|
||||||
quint16 port = options->webUiPort();
|
|
||||||
QString username = options->webUiUsername();
|
|
||||||
QString password = options->webUiPassword();
|
|
||||||
initWebUi(username, password, port);
|
|
||||||
}
|
|
||||||
else if(httpServer)
|
|
||||||
{
|
|
||||||
delete httpServer;
|
|
||||||
httpServer = 0;
|
|
||||||
}
|
|
||||||
// Update session
|
// Update session
|
||||||
configureSession(deleteOptions);
|
configureSession(deleteOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GUI::initWebUi(QString username, QString password, int port)
|
|
||||||
{
|
|
||||||
if(httpServer)
|
|
||||||
{
|
|
||||||
httpServer->close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
httpServer = new HttpServer(BTSession, 500, this);
|
|
||||||
httpServer->setAuthorization(username, password);
|
|
||||||
bool success = httpServer->listen(QHostAddress::Any, port);
|
|
||||||
if (success)
|
|
||||||
qDebug("Web UI listening on port %d", port);
|
|
||||||
else
|
|
||||||
QMessageBox::critical(this, "Web User Interface Error", "Unable to initialize HTTP Server on port " + misc::toQString(port));
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* *
|
* *
|
||||||
* HTTP Downloader *
|
* HTTP Downloader *
|
||||||
|
|||||||
31
src/GUI.h
31
src/GUI.h
@@ -35,13 +35,8 @@ class DownloadingTorrents;
|
|||||||
class FinishedTorrents;
|
class FinishedTorrents;
|
||||||
class downloadFromURL;
|
class downloadFromURL;
|
||||||
class SearchEngine;
|
class SearchEngine;
|
||||||
#ifdef QT_4_4
|
|
||||||
class QLocalServer;
|
|
||||||
class QLocalSocket;
|
|
||||||
#else
|
|
||||||
class QTcpServer;
|
class QTcpServer;
|
||||||
class QTcpSocket;
|
class QTcpSocket;
|
||||||
#endif
|
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
class RSSImp;
|
class RSSImp;
|
||||||
class QShortcut;
|
class QShortcut;
|
||||||
@@ -51,7 +46,6 @@ class options_imp;
|
|||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
class HttpServer;
|
|
||||||
|
|
||||||
class GUI : public QMainWindow, private Ui::MainWindow{
|
class GUI : public QMainWindow, private Ui::MainWindow{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -65,7 +59,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
QTabWidget *tabs;
|
QTabWidget *tabs;
|
||||||
options_imp *options;
|
options_imp *options;
|
||||||
QSystemTrayIcon *myTrayIcon;
|
QSystemTrayIcon *myTrayIcon;
|
||||||
QTimer *systrayCreator;
|
|
||||||
QMenu *myTrayIconMenu;
|
QMenu *myTrayIconMenu;
|
||||||
DownloadingTorrents *downloadingTorrentTab;
|
DownloadingTorrents *downloadingTorrentTab;
|
||||||
FinishedTorrents *finishedTorrentTab;
|
FinishedTorrents *finishedTorrentTab;
|
||||||
@@ -81,20 +74,15 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
QShortcut *switchDownShortcut;
|
QShortcut *switchDownShortcut;
|
||||||
QShortcut *switchUpShortcut;
|
QShortcut *switchUpShortcut;
|
||||||
QShortcut *switchRSSShortcut;
|
QShortcut *switchRSSShortcut;
|
||||||
|
// Preview
|
||||||
|
QProcess *previewProcess;
|
||||||
// Search
|
// Search
|
||||||
SearchEngine *searchEngine;
|
SearchEngine *searchEngine;
|
||||||
// RSS
|
// RSS
|
||||||
RSSImp *rssWidget;
|
RSSImp *rssWidget;
|
||||||
// Web UI
|
|
||||||
HttpServer *httpServer;
|
|
||||||
// Misc
|
// Misc
|
||||||
#ifdef QT_4_4
|
QTcpServer *tcpServer;
|
||||||
QLocalServer *localServer;
|
|
||||||
QLocalSocket *clientConnection;
|
|
||||||
#else
|
|
||||||
QTcpServer *localServer;
|
|
||||||
QTcpSocket *clientConnection;
|
QTcpSocket *clientConnection;
|
||||||
#endif
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
// GUI related slots
|
// GUI related slots
|
||||||
@@ -108,9 +96,9 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
void readParamsOnSocket();
|
void readParamsOnSocket();
|
||||||
void acceptConnection();
|
void acceptConnection();
|
||||||
void togglePausedState(QString hash);
|
void togglePausedState(QString hash);
|
||||||
void torrentDoubleClicked(QString hash, bool finished);
|
|
||||||
void on_actionPreview_file_triggered();
|
void on_actionPreview_file_triggered();
|
||||||
void previewFile(QString filePath);
|
void previewFile(QString filePath);
|
||||||
|
void cleanTempPreviewFile(int, QProcess::ExitStatus) const;
|
||||||
void balloonClicked();
|
void balloonClicked();
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
void readSettings();
|
void readSettings();
|
||||||
@@ -120,7 +108,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
void updateFinishedTorrentNumber(unsigned int nb);
|
void updateFinishedTorrentNumber(unsigned int nb);
|
||||||
void fullDiskError(QTorrentHandle& h) const;
|
void fullDiskError(QTorrentHandle& h) const;
|
||||||
void handleDownloadFromUrlFailure(QString, QString) const;
|
void handleDownloadFromUrlFailure(QString, QString) const;
|
||||||
void createSystrayDelayed();
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
void createKeyboardShortcuts();
|
void createKeyboardShortcuts();
|
||||||
void displayDownTab() const;
|
void displayDownTab() const;
|
||||||
@@ -147,13 +134,10 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
void processScannedFiles(const QStringList& params);
|
void processScannedFiles(const QStringList& params);
|
||||||
void processDownloadedFiles(QString path, QString url);
|
void processDownloadedFiles(QString path, QString url);
|
||||||
void downloadFromURLList(const QStringList& urls);
|
void downloadFromURLList(const QStringList& urls);
|
||||||
void deleteTorrent(QString hash);
|
void deleteTorrent(QString hash, QString fileName, bool finished);
|
||||||
void deleteRatioTorrent(QString fileName);
|
|
||||||
void finishedTorrent(QTorrentHandle& h) const;
|
void finishedTorrent(QTorrentHandle& h) const;
|
||||||
void torrentChecked(QString hash) const;
|
void torrentChecked(QString hash) const;
|
||||||
void updateLists();
|
void updateLists();
|
||||||
bool initWebUi(QString username, QString password, int port);
|
|
||||||
void pauseTorrent(QString hash);
|
|
||||||
// Options slots
|
// Options slots
|
||||||
void on_actionOptions_triggered();
|
void on_actionOptions_triggered();
|
||||||
void OptionsSaved(QString info, bool deleteOptions);
|
void OptionsSaved(QString info, bool deleteOptions);
|
||||||
@@ -164,9 +148,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
public slots:
|
public slots:
|
||||||
void trackerAuthenticationRequired(QTorrentHandle& h);
|
void trackerAuthenticationRequired(QTorrentHandle& h);
|
||||||
void setTabText(int index, QString text) const;
|
void setTabText(int index, QString text) const;
|
||||||
void openDestinationFolder() const;
|
|
||||||
void goBuyPage() const;
|
|
||||||
void updateRatio();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *);
|
void closeEvent(QCloseEvent *);
|
||||||
@@ -177,7 +158,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList());
|
GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList());
|
||||||
~GUI();
|
~GUI();
|
||||||
// Methods
|
// Methods
|
||||||
int getCurrentTabIndex() const;
|
unsigned int getCurrentTabIndex() const;
|
||||||
QPoint screenCenter() const;
|
QPoint screenCenter() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 575 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 813 B |
@@ -1,23 +1,22 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Categories=Qt;Application;Network;P2P
|
Categories=Qt;Application;Network;P2P
|
||||||
Comment=V1.1.0
|
Comment=V1.0.0
|
||||||
|
Encoding=UTF-8
|
||||||
Exec=qbittorrent
|
Exec=qbittorrent
|
||||||
GenericName=Bittorrent client
|
GenericName=Bittorrent client
|
||||||
GenericName[bg]=Торент клиент
|
|
||||||
GenericName[de]=Bittorren Client
|
|
||||||
GenericName[el]=Τορεντ πελάτης
|
|
||||||
GenericName[es]=Cliente Bittorrent
|
|
||||||
GenericName[fr]=Client Bittorrent
|
GenericName[fr]=Client Bittorrent
|
||||||
GenericName[it]=Client Bittorrent
|
|
||||||
GenericName[ja]=Bittorrent クライアント
|
|
||||||
GenericName[ko]=비토렌트 클라이언트
|
|
||||||
GenericName[nl]=Bittorrent client
|
GenericName[nl]=Bittorrent client
|
||||||
GenericName[pl]=Klient Bittorrent
|
GenericName[es]=Cliente Bittorrent
|
||||||
GenericName[ru]=клиент Bittorrent
|
|
||||||
GenericName[sv]=Bittorrent-klient
|
GenericName[sv]=Bittorrent-klient
|
||||||
GenericName[tr]=Bittorrent istemcisi
|
GenericName[tr]=Bittorrent istemcisi
|
||||||
GenericName[uk]=Bittorrent-клієнт
|
GenericName[de]=Bittorren Client
|
||||||
|
GenericName[pl]=Klient Bittorrent
|
||||||
GenericName[zh]=Bittorrent之用户
|
GenericName[zh]=Bittorrent之用户
|
||||||
|
GenericName[ko]=비토렌트 클라이언트
|
||||||
|
GenericName[el]=Τορεντ πελάτης
|
||||||
|
GenericName[bg]=Торент клиент
|
||||||
|
GenericName[uk]=Bittorrent-клієнт
|
||||||
|
GenericName[ru]=клиент Bittorrent
|
||||||
Icon=qbittorrent
|
Icon=qbittorrent
|
||||||
MimeType=application/x-bittorrent
|
MimeType=application/x-bittorrent
|
||||||
Name=qBittorrent
|
Name=qBittorrent
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 68 KiB |
@@ -16,194 +16,13 @@
|
|||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget" >
|
<widget class="QWidget" name="centralwidget" >
|
||||||
<property name="geometry" >
|
<layout class="QVBoxLayout" >
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>58</y>
|
|
||||||
<width>849</width>
|
|
||||||
<height>505</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vboxLayout" >
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="_3" >
|
|
||||||
<property name="spacing" >
|
<property name="spacing" >
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin" >
|
||||||
<number>0</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<spacer>
|
|
||||||
<property name="orientation" >
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0" >
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lbl_DLSpeed_2" >
|
|
||||||
<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_2" >
|
|
||||||
<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" stdset="0" >
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_2" >
|
|
||||||
<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" stdset="0" >
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lbl_UPSpeed_2" >
|
|
||||||
<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_2" >
|
|
||||||
<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" stdset="0" >
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar" >
|
<widget class="QMenuBar" name="menubar" >
|
||||||
@@ -212,7 +31,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>849</width>
|
<width>849</width>
|
||||||
<height>26</height>
|
<height>29</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menu_Edit" >
|
<widget class="QMenu" name="menu_Edit" >
|
||||||
@@ -263,14 +82,6 @@
|
|||||||
<property name="enabled" >
|
<property name="enabled" >
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="geometry" >
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>26</y>
|
|
||||||
<width>849</width>
|
|
||||||
<height>32</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="contextMenuPolicy" >
|
<property name="contextMenuPolicy" >
|
||||||
<enum>Qt::NoContextMenu</enum>
|
<enum>Qt::NoContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
@@ -287,7 +98,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="toolBarArea" >
|
<attribute name="toolBarArea" >
|
||||||
<enum>TopToolBarArea</enum>
|
<number>4</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
<attribute name="toolBarBreak" >
|
<attribute name="toolBarBreak" >
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
|||||||
@@ -61,8 +61,11 @@ class PreviewListDelegate: public QItemDelegate {
|
|||||||
newopt.maximum = 100;
|
newopt.maximum = 100;
|
||||||
newopt.minimum = 0;
|
newopt.minimum = 0;
|
||||||
newopt.state |= QStyle::State_Enabled;
|
newopt.state |= QStyle::State_Enabled;
|
||||||
newopt.textVisible = true;
|
newopt.textVisible = false;
|
||||||
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
|
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
|
||||||
|
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||||
|
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
|
||||||
|
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -75,8 +75,11 @@ class PropListDelegate: public QItemDelegate {
|
|||||||
newopt.maximum = 100;
|
newopt.maximum = 100;
|
||||||
newopt.minimum = 0;
|
newopt.minimum = 0;
|
||||||
newopt.state |= QStyle::State_Enabled;
|
newopt.state |= QStyle::State_Enabled;
|
||||||
newopt.textVisible = true;
|
newopt.textVisible = false;
|
||||||
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
|
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
|
||||||
|
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||||
|
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
|
||||||
|
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PRIORITY:{
|
case PRIORITY:{
|
||||||
@@ -174,16 +177,14 @@ class PropListDelegate: public QItemDelegate {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// if(old_val != NORMAL){
|
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));
|
model->setData(index, QVariant(NORMAL));
|
||||||
if(filteredFilesChanged != 0)
|
if(filteredFilesChanged != 0)
|
||||||
*filteredFilesChanged = true;
|
*filteredFilesChanged = true;
|
||||||
// }
|
} else {
|
||||||
|
model->setData(index, QVariant(HIGH));
|
||||||
|
model->setData(index, QVariant(NORMAL));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if(old_val != HIGH){
|
if(old_val != HIGH){
|
||||||
|
|||||||
@@ -1,190 +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
|
// Thanks
|
||||||
te_thanks->append(QString::fromUtf8("<a name='top'></a>"));
|
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("<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 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>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>"));
|
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>"));
|
||||||
@@ -62,7 +62,7 @@ class about : public QDialog, private Ui::AboutDlg{
|
|||||||
- <u>Finnish:</u> Niklas Laxström (nikerabbit@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>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\
|
||||||
- <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\
|
- <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\
|
||||||
- <u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)<br>\
|
- <u>Hungarian:</u> Majoros Péter (majoros.j.p@t-online.hu)<br>\
|
||||||
- <u>Italian:</u> Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)<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>Japanese:</u> Nardog (nardog@e2umail.com)<br>\
|
||||||
- <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\
|
- <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\
|
||||||
|
|||||||
@@ -27,19 +27,19 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
class torrent_file {
|
class file {
|
||||||
private:
|
private:
|
||||||
torrent_file *parent;
|
file *parent;
|
||||||
bool is_dir;
|
bool is_dir;
|
||||||
QString rel_path;
|
QString rel_path;
|
||||||
QList<torrent_file*> children;
|
QList<file*> children;
|
||||||
size_type size;
|
size_type size;
|
||||||
float progress;
|
float progress;
|
||||||
int priority;
|
int priority;
|
||||||
int index; // Index in torrent_info
|
int index; // Index in torrent_info
|
||||||
|
|
||||||
public:
|
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);
|
qDebug("created a file with index %d", index);
|
||||||
rel_path = QDir::cleanPath(path);
|
rel_path = QDir::cleanPath(path);
|
||||||
if(parent) {
|
if(parent) {
|
||||||
@@ -48,7 +48,7 @@ class torrent_file {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~torrent_file() {
|
~file() {
|
||||||
qDeleteAll(children);
|
qDeleteAll(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,25 +62,17 @@ class torrent_file {
|
|||||||
|
|
||||||
void updateProgress() {
|
void updateProgress() {
|
||||||
Q_ASSERT(is_dir);
|
Q_ASSERT(is_dir);
|
||||||
if(children.isEmpty()) {
|
float sum = 0;
|
||||||
progress = 0.;
|
file *child;
|
||||||
return;
|
|
||||||
}
|
|
||||||
float wanted = 0.;
|
|
||||||
float done = 0.;
|
|
||||||
torrent_file *child;
|
|
||||||
foreach(child, children) {
|
foreach(child, children) {
|
||||||
wanted += child->getSize();
|
sum += child->getProgress();
|
||||||
done += child->getSize()*child->getProgress();
|
|
||||||
}
|
}
|
||||||
progress = done / wanted;
|
progress = sum / (float)children.size();
|
||||||
Q_ASSERT(progress >= 0.);
|
|
||||||
Q_ASSERT(progress <= 1.);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePriority(int prio) {
|
void updatePriority(int prio) {
|
||||||
Q_ASSERT(is_dir);
|
Q_ASSERT(is_dir);
|
||||||
torrent_file *child;
|
file *child;
|
||||||
foreach(child, children) {
|
foreach(child, children) {
|
||||||
if(child->getPriority() != prio) return;
|
if(child->getPriority() != prio) return;
|
||||||
}
|
}
|
||||||
@@ -111,13 +103,13 @@ class torrent_file {
|
|||||||
return (!children.isEmpty());
|
return (!children.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<torrent_file*> getChildren() const {
|
QList<file*> getChildren() const {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent_file* getChild(QString fileName) const {
|
file* getChild(QString fileName) const {
|
||||||
Q_ASSERT(is_dir);
|
Q_ASSERT(is_dir);
|
||||||
torrent_file* f;
|
file* f;
|
||||||
foreach(f, children) {
|
foreach(f, children) {
|
||||||
if(f->name() == fileName) return f;
|
if(f->name() == fileName) return f;
|
||||||
}
|
}
|
||||||
@@ -130,10 +122,10 @@ class torrent_file {
|
|||||||
parent->addBytes(b);
|
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);
|
Q_ASSERT(is_dir);
|
||||||
qDebug("Adding a new child of size: %ld", (long)size);
|
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;
|
children << f;
|
||||||
if(size) {
|
if(size) {
|
||||||
addBytes(size);
|
addBytes(size);
|
||||||
@@ -148,7 +140,7 @@ class torrent_file {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool success = true;
|
bool success = true;
|
||||||
torrent_file *f;
|
file *f;
|
||||||
qDebug("We have %d children", children.size());
|
qDebug("We have %d children", children.size());
|
||||||
foreach(f, children) {
|
foreach(f, children) {
|
||||||
bool s = f->removeFromFS(saveDir);
|
bool s = f->removeFromFS(saveDir);
|
||||||
@@ -169,16 +161,16 @@ class torrent_file {
|
|||||||
|
|
||||||
class arborescence {
|
class arborescence {
|
||||||
private:
|
private:
|
||||||
torrent_file *root;
|
file *root;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
arborescence(torrent_info t) {
|
arborescence(torrent_info t) {
|
||||||
torrent_info::file_iterator fi = t.begin_files();
|
torrent_info::file_iterator fi = t.begin_files();
|
||||||
if(t.num_files() > 1) {
|
if(t.num_files() > 1) {
|
||||||
root = new torrent_file(0, misc::toQString(t.name()), true);
|
root = new file(0, misc::toQString(t.name()), true);
|
||||||
} else {
|
} else {
|
||||||
// XXX: Will crash if there is no file in torrent
|
// XXX: Will crash if there is no file in torrent
|
||||||
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0);
|
root = new file(0, misc::toQString(t.name()), false, fi->size, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -196,11 +188,11 @@ class arborescence {
|
|||||||
torrent_info::file_iterator fi = t.begin_files();
|
torrent_info::file_iterator fi = t.begin_files();
|
||||||
if(t.num_files() > 1) {
|
if(t.num_files() > 1) {
|
||||||
qDebug("More than one file in the torrent, setting a folder as root");
|
qDebug("More than one file in the torrent, setting a folder as root");
|
||||||
root = new torrent_file(0, misc::toQString(t.name()), true);
|
root = new file(0, misc::toQString(t.name()), true);
|
||||||
} else {
|
} else {
|
||||||
// XXX: Will crash if there is no file in torrent
|
// XXX: Will crash if there is no file in torrent
|
||||||
qDebug("one file in the torrent, setting it as root with index 0");
|
qDebug("one file in the torrent, setting it as root with index 0");
|
||||||
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]);
|
root = new file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -218,7 +210,7 @@ class arborescence {
|
|||||||
delete root;
|
delete root;
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent_file* getRoot() const {
|
file* getRoot() const {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,19 +226,19 @@ class arborescence {
|
|||||||
void addFile(QString path, size_type file_size, int index, float progress=0., int priority=1) {
|
void addFile(QString path, size_type file_size, int index, float progress=0., int priority=1) {
|
||||||
Q_ASSERT(root->isDir());
|
Q_ASSERT(root->isDir());
|
||||||
path = QDir::cleanPath(path);
|
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());
|
QString relative_path = path.remove(0, root->path().size());
|
||||||
if(relative_path.at(0) ==QDir::separator())
|
if(relative_path.at(0) ==QDir::separator())
|
||||||
relative_path.remove(0, 1);
|
relative_path.remove(0, 1);
|
||||||
QStringList fileNames = relative_path.split(QDir::separator());
|
QStringList fileNames = relative_path.split(QDir::separator());
|
||||||
QString fileName;
|
QString fileName;
|
||||||
torrent_file *dad = root;
|
file *dad = root;
|
||||||
unsigned int nb_i = 0;
|
unsigned int nb_i = 0;
|
||||||
unsigned int size = fileNames.size();
|
unsigned int size = fileNames.size();
|
||||||
foreach(fileName, fileNames) {
|
foreach(fileName, fileNames) {
|
||||||
++nb_i;
|
++nb_i;
|
||||||
if(fileName == ".") continue;
|
if(fileName == ".") continue;
|
||||||
torrent_file* child = dad->getChild(fileName);
|
file* child = dad->getChild(fileName);
|
||||||
if(!child) {
|
if(!child) {
|
||||||
if(nb_i != size) {
|
if(nb_i != size) {
|
||||||
// Folder
|
// Folder
|
||||||
|
|||||||
@@ -23,13 +23,11 @@
|
|||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QSettings>
|
|
||||||
|
|
||||||
#include "bittorrent.h"
|
#include "bittorrent.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "downloadThread.h"
|
#include "downloadThread.h"
|
||||||
#include "deleteThread.h"
|
#include "deleteThread.h"
|
||||||
#include "filterParserThread.h"
|
|
||||||
|
|
||||||
#include <libtorrent/extensions/metadata_transfer.hpp>
|
#include <libtorrent/extensions/metadata_transfer.hpp>
|
||||||
#include <libtorrent/extensions/ut_pex.hpp>
|
#include <libtorrent/extensions/ut_pex.hpp>
|
||||||
@@ -37,23 +35,20 @@
|
|||||||
#include <libtorrent/bencode.hpp>
|
#include <libtorrent/bencode.hpp>
|
||||||
#include <libtorrent/identify_client.hpp>
|
#include <libtorrent/identify_client.hpp>
|
||||||
#include <libtorrent/alert_types.hpp>
|
#include <libtorrent/alert_types.hpp>
|
||||||
|
#include <libtorrent/ip_filter.hpp>
|
||||||
#include <libtorrent/torrent_info.hpp>
|
#include <libtorrent/torrent_info.hpp>
|
||||||
#include <boost/filesystem/exception.hpp>
|
#include <boost/filesystem/exception.hpp>
|
||||||
|
|
||||||
|
#define ETAS_MAX_VALUES 3
|
||||||
|
#define ETA_REFRESH_INTERVAL 10000
|
||||||
#define MAX_TRACKER_ERRORS 2
|
#define MAX_TRACKER_ERRORS 2
|
||||||
|
|
||||||
// Main constructor
|
// Main constructor
|
||||||
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), folderScanInterval(5) {
|
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1) {
|
||||||
// To avoid some exceptions
|
// To avoid some exceptions
|
||||||
fs::path::default_name_check(fs::no_check);
|
fs::path::default_name_check(fs::no_check);
|
||||||
// Creating bittorrent session
|
// Creating bittorrent session
|
||||||
// Check if we should spoof azureus
|
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
|
||||||
if(settings.value(QString::fromUtf8("AzureusSpoof"), false).toBool()) {
|
|
||||||
s = new session(fingerprint("AZ", 3, 0, 5, 2));
|
|
||||||
} else {
|
|
||||||
s = new session(fingerprint("qB", VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, 0));
|
s = new session(fingerprint("qB", VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, 0));
|
||||||
}
|
|
||||||
// Set severity level of libtorrent session
|
// Set severity level of libtorrent session
|
||||||
s->set_severity_level(alert::info);
|
s->set_severity_level(alert::info);
|
||||||
// Enabling metadata plugin
|
// Enabling metadata plugin
|
||||||
@@ -61,63 +56,46 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false
|
|||||||
timerAlerts = new QTimer();
|
timerAlerts = new QTimer();
|
||||||
connect(timerAlerts, SIGNAL(timeout()), this, SLOT(readAlerts()));
|
connect(timerAlerts, SIGNAL(timeout()), this, SLOT(readAlerts()));
|
||||||
timerAlerts->start(3000);
|
timerAlerts->start(3000);
|
||||||
fastResumeSaver = new QTimer();
|
ETARefresher = new QTimer();
|
||||||
connect(fastResumeSaver, SIGNAL(timeout()), this, SLOT(saveFastResumeAndRatioData()));
|
connect(ETARefresher, SIGNAL(timeout()), this, SLOT(updateETAs()));
|
||||||
fastResumeSaver->start(60000);
|
ETARefresher->start(ETA_REFRESH_INTERVAL);
|
||||||
// To download from urls
|
// To download from urls
|
||||||
downloader = new downloadThread(this);
|
downloader = new downloadThread(this);
|
||||||
connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString)));
|
connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString)));
|
||||||
connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
||||||
// File deleter (thread)
|
// File deleter (thread)
|
||||||
deleter = new deleteThread(this);
|
deleter = new deleteThread(this);
|
||||||
BigRatioTimer = 0;
|
|
||||||
filterParser = 0;
|
|
||||||
qDebug("* BTSession constructed");
|
qDebug("* BTSession constructed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main destructor
|
// Main destructor
|
||||||
bittorrent::~bittorrent() {
|
bittorrent::~bittorrent() {
|
||||||
qDebug("BTSession deletion");
|
|
||||||
// Set Session settings
|
|
||||||
session_settings ss;
|
|
||||||
ss.tracker_receive_timeout = 1;
|
|
||||||
ss.stop_tracker_timeout = 1;
|
|
||||||
ss.tracker_completion_timeout = 1;
|
|
||||||
ss.piece_timeout = 1;
|
|
||||||
ss.peer_timeout = 1;
|
|
||||||
ss.urlseed_timeout = 1;
|
|
||||||
s->set_settings(ss);
|
|
||||||
// Disable directory scanning
|
// Disable directory scanning
|
||||||
disableDirectoryScanning();
|
disableDirectoryScanning();
|
||||||
// Delete our objects
|
// Delete our objects
|
||||||
delete deleter;
|
delete deleter;
|
||||||
delete fastResumeSaver;
|
|
||||||
delete timerAlerts;
|
delete timerAlerts;
|
||||||
if(BigRatioTimer != 0)
|
delete ETARefresher;
|
||||||
delete BigRatioTimer;
|
|
||||||
if(filterParser != 0)
|
|
||||||
delete filterParser;
|
|
||||||
delete downloader;
|
delete downloader;
|
||||||
// Delete BT session
|
// Delete BT session
|
||||||
qDebug("Deleting session");
|
|
||||||
delete s;
|
delete s;
|
||||||
qDebug("Session deleted");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::preAllocateAllFiles(bool b) {
|
void bittorrent::preAllocateAllFiles(bool b) {
|
||||||
bool change = (preAllocateAll != b);
|
|
||||||
if(change) {
|
|
||||||
qDebug("PreAllocateAll changed, reloading all torrents!");
|
|
||||||
preAllocateAll = b;
|
preAllocateAll = b;
|
||||||
// Reload All unfinished torrents
|
if(b) {
|
||||||
QString hash;
|
// Reload All Torrents
|
||||||
foreach(hash, unfinishedTorrents) {
|
std::vector<torrent_handle> handles = s->get_torrents();
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
unsigned int nbHandles = handles.size();
|
||||||
|
for(unsigned int i=0; i<nbHandles; ++i) {
|
||||||
|
QTorrentHandle h = handles[i];
|
||||||
if(!h.is_valid()) {
|
if(!h.is_valid()) {
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
reloadTorrent(h, b);
|
QString hash = h.hash();
|
||||||
|
if(has_filtered_files(hash)) continue;
|
||||||
|
reloadTorrent(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,7 +113,7 @@ void bittorrent::deleteBigRatios() {
|
|||||||
if(getRealRatio(hash) > max_ratio) {
|
if(getRealRatio(hash) > max_ratio) {
|
||||||
QString fileName = h.name();
|
QString fileName = h.name();
|
||||||
deleteTorrent(hash);
|
deleteTorrent(hash);
|
||||||
emit torrent_ratio_deleted(fileName);
|
emit torrent_deleted(hash, fileName, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,34 +141,43 @@ void bittorrent::startTorrentsInPause(bool b) {
|
|||||||
addInPause = b;
|
addInPause = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the ETA using GASA
|
void bittorrent::updateETAs() {
|
||||||
// GASA: global Average Speed Algorithm
|
QString hash;
|
||||||
qlonglong bittorrent::getETA(QString hash) const {
|
foreach(hash, unfinishedTorrents) {
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
if(!h.is_valid()) return -1;
|
if(h.is_valid()) {
|
||||||
switch(h.state()) {
|
if(h.is_paused()) continue;
|
||||||
case torrent_status::downloading:
|
QString hash = h.hash();
|
||||||
case torrent_status::connecting_to_tracker: {
|
QList<qlonglong> listEtas = ETAstats.value(hash, QList<qlonglong>());
|
||||||
if(!TorrentsStartTime.contains(hash)) return -1;
|
if(listEtas.size() == ETAS_MAX_VALUES) {
|
||||||
int timeElapsed = TorrentsStartTime.value(hash).secsTo(QDateTime::currentDateTime());
|
listEtas.removeFirst();
|
||||||
double avg_speed;
|
|
||||||
if(timeElapsed) {
|
|
||||||
size_type data_origin = TorrentsStartData.value(hash, 0);
|
|
||||||
avg_speed = (double)(h.total_payload_download()-data_origin) / (double)timeElapsed;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
if(avg_speed) {
|
if(h.download_payload_rate()) {
|
||||||
return (qlonglong) floor((double) (h.actual_size() - h.total_wanted_done()) / avg_speed);
|
listEtas << (qlonglong)((h.actual_size()-h.total_done())/(double)h.download_payload_rate());
|
||||||
|
ETAstats[hash] = listEtas;
|
||||||
|
qlonglong moy = 0;
|
||||||
|
qlonglong val;
|
||||||
|
unsigned int nbETAs = listEtas.size();
|
||||||
|
Q_ASSERT(nbETAs);
|
||||||
|
foreach(val, listEtas) {
|
||||||
|
moy += (qlonglong)((double)val/(double)nbETAs);
|
||||||
|
if(moy < 0) break;
|
||||||
|
}
|
||||||
|
if(moy < 0) {
|
||||||
|
ETAs.remove(hash);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
ETAs[hash] = moy;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
}
|
||||||
return -1;
|
// Delete big ratios
|
||||||
|
if(max_ratio != -1)
|
||||||
|
deleteBigRatios();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long bittorrent::getETA(QString hash) const{
|
||||||
|
return ETAs.value(hash, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the torrent handle, given its hash
|
// Return the torrent handle, given its hash
|
||||||
@@ -211,26 +198,6 @@ bool bittorrent::isPaused(QString hash) const{
|
|||||||
return h.is_paused();
|
return h.is_paused();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int bittorrent::getFinishedPausedTorrentsNb() const {
|
|
||||||
unsigned int nbPaused = 0;
|
|
||||||
foreach(QString hash, finishedTorrents) {
|
|
||||||
if(isPaused(hash)) {
|
|
||||||
++nbPaused;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nbPaused;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int bittorrent::getUnfinishedPausedTorrentsNb() const {
|
|
||||||
unsigned int nbPaused = 0;
|
|
||||||
foreach(QString hash, unfinishedTorrents) {
|
|
||||||
if(isPaused(hash)) {
|
|
||||||
++nbPaused;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nbPaused;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete a torrent from the session, given its hash
|
// Delete a torrent from the session, given its hash
|
||||||
// permanent = true means that the torrent will be removed from the hard-drive too
|
// permanent = true means that the torrent will be removed from the hard-drive too
|
||||||
void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
||||||
@@ -257,9 +224,9 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
|||||||
foreach(file, files) {
|
foreach(file, files) {
|
||||||
torrentBackup.remove(file);
|
torrentBackup.remove(file);
|
||||||
}
|
}
|
||||||
// Remove it from TorrentsStartTime hash table
|
// Remove it from ETAs hash tables
|
||||||
TorrentsStartTime.remove(hash);
|
ETAstats.remove(hash);
|
||||||
TorrentsStartData.remove(hash);
|
ETAs.remove(hash);
|
||||||
// Remove tracker errors
|
// Remove tracker errors
|
||||||
trackersErrors.remove(hash);
|
trackersErrors.remove(hash);
|
||||||
// Remove it from ratio table
|
// Remove it from ratio table
|
||||||
@@ -281,7 +248,6 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
|||||||
// Deleting in a thread to avoid GUI freeze
|
// Deleting in a thread to avoid GUI freeze
|
||||||
deleter->deleteTorrent(savePath, files_arb);
|
deleter->deleteTorrent(savePath, files_arb);
|
||||||
}
|
}
|
||||||
emit deletedTorrent(hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a list of hashes for the finished torrents
|
// Return a list of hashes for the finished torrents
|
||||||
@@ -308,9 +274,6 @@ void bittorrent::setUnfinishedTorrent(QString hash) {
|
|||||||
}
|
}
|
||||||
if(!unfinishedTorrents.contains(hash)) {
|
if(!unfinishedTorrents.contains(hash)) {
|
||||||
unfinishedTorrents << hash;
|
unfinishedTorrents << hash;
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
|
||||||
TorrentsStartData[hash] = h.total_payload_download();
|
|
||||||
TorrentsStartTime[hash] = QDateTime::currentDateTime();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,11 +291,9 @@ void bittorrent::setFinishedTorrent(QString hash) {
|
|||||||
if(index != -1) {
|
if(index != -1) {
|
||||||
unfinishedTorrents.removeAt(index);
|
unfinishedTorrents.removeAt(index);
|
||||||
}
|
}
|
||||||
// Remove it from TorrentsStartTime hash table
|
// Remove it from ETAs hash tables
|
||||||
TorrentsStartTime.remove(hash);
|
ETAstats.remove(hash);
|
||||||
TorrentsStartData.remove(hash);
|
ETAs.remove(hash);
|
||||||
// Save fast resume data
|
|
||||||
saveFastResumeAndRatioData(hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause a running torrent
|
// Pause a running torrent
|
||||||
@@ -342,10 +303,7 @@ bool bittorrent::pauseTorrent(QString hash) {
|
|||||||
if(h.is_valid() && !h.is_paused()) {
|
if(h.is_valid() && !h.is_paused()) {
|
||||||
h.pause();
|
h.pause();
|
||||||
change = true;
|
change = true;
|
||||||
// Save fast resume data
|
|
||||||
saveFastResumeAndRatioData(hash);
|
|
||||||
qDebug("Torrent paused successfully");
|
qDebug("Torrent paused successfully");
|
||||||
emit pausedTorrent(hash);
|
|
||||||
}else{
|
}else{
|
||||||
if(!h.is_valid()) {
|
if(!h.is_valid()) {
|
||||||
qDebug("Could not pause torrent %s, reason: invalid", hash.toUtf8().data());
|
qDebug("Could not pause torrent %s, reason: invalid", hash.toUtf8().data());
|
||||||
@@ -359,9 +317,9 @@ bool bittorrent::pauseTorrent(QString hash) {
|
|||||||
paused_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
paused_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
paused_file.close();
|
paused_file.close();
|
||||||
}
|
}
|
||||||
// Remove it from TorrentsStartTime hash table
|
// Remove it from ETAs hash tables
|
||||||
TorrentsStartTime.remove(hash);
|
ETAstats.remove(hash);
|
||||||
TorrentsStartData.remove(hash);
|
ETAs.remove(hash);
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,12 +328,8 @@ bool bittorrent::resumeTorrent(QString hash) {
|
|||||||
bool success = false;
|
bool success = false;
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
if(h.is_valid() && h.is_paused()) {
|
if(h.is_valid() && h.is_paused()) {
|
||||||
// Save Addition DateTime
|
|
||||||
TorrentsStartData[hash] = h.total_payload_download();
|
|
||||||
TorrentsStartTime[hash] = QDateTime::currentDateTime();
|
|
||||||
h.resume();
|
h.resume();
|
||||||
success = true;
|
success = true;
|
||||||
emit resumedTorrent(hash);
|
|
||||||
}
|
}
|
||||||
// Delete .paused file
|
// Delete .paused file
|
||||||
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused"))
|
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused"))
|
||||||
@@ -388,18 +342,6 @@ bool bittorrent::resumeTorrent(QString hash) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::pauseAllTorrents() {
|
|
||||||
QStringList list = getUnfinishedTorrents() + getFinishedTorrents();
|
|
||||||
foreach(QString hash, list)
|
|
||||||
pauseTorrent(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bittorrent::resumeAllTorrents() {
|
|
||||||
QStringList list = getUnfinishedTorrents() + getFinishedTorrents();
|
|
||||||
foreach(QString hash, list)
|
|
||||||
resumeTorrent(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bittorrent::loadWebSeeds(QString hash) {
|
void bittorrent::loadWebSeeds(QString hash) {
|
||||||
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
|
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
|
||||||
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
||||||
@@ -432,7 +374,7 @@ void bittorrent::loadWebSeeds(QString hash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a torrent to the bittorrent session
|
// Add a torrent to the bittorrent session
|
||||||
void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) {
|
void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url) {
|
||||||
QTorrentHandle h;
|
QTorrentHandle h;
|
||||||
entry resume_data;
|
entry resume_data;
|
||||||
bool fastResume=false;
|
bool fastResume=false;
|
||||||
@@ -502,12 +444,12 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo
|
|||||||
}
|
}
|
||||||
QString savePath = getSavePath(hash);
|
QString savePath = getSavePath(hash);
|
||||||
// Adding files to bittorrent session
|
// Adding files to bittorrent session
|
||||||
if(preAllocateAll) {
|
if(has_filtered_files(hash) || preAllocateAll) {
|
||||||
h = s->add_torrent(t, fs::path(savePath.toUtf8().data()), resume_data, storage_mode_allocate, true);
|
h = s->add_torrent(t, fs::path(savePath.toUtf8().data()), resume_data, false, true);
|
||||||
qDebug(" -> Full allocation mode");
|
qDebug(" -> Full allocation mode");
|
||||||
}else{
|
}else{
|
||||||
h = s->add_torrent(t, fs::path(savePath.toUtf8().data()), resume_data, storage_mode_sparse, true);
|
h = s->add_torrent(t, fs::path(savePath.toUtf8().data()), resume_data, true, true);
|
||||||
qDebug(" -> Sparse allocation mode");
|
qDebug(" -> Compact allocation mode");
|
||||||
}
|
}
|
||||||
if(!h.is_valid()) {
|
if(!h.is_valid()) {
|
||||||
// No need to keep on, it failed.
|
// No need to keep on, it failed.
|
||||||
@@ -544,7 +486,7 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo
|
|||||||
QFile::copy(file, newFile);
|
QFile::copy(file, newFile);
|
||||||
}
|
}
|
||||||
// Pause torrent if it was paused last time
|
// Pause torrent if it was paused last time
|
||||||
if((!resumed && addInPause) || QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) {
|
if(addInPause || QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) {
|
||||||
torrentsToPauseAfterChecking << hash;
|
torrentsToPauseAfterChecking << hash;
|
||||||
qDebug("Adding a torrent to the torrentsToPauseAfterChecking list");
|
qDebug("Adding a torrent to the torrentsToPauseAfterChecking list");
|
||||||
}
|
}
|
||||||
@@ -577,7 +519,6 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo
|
|||||||
// Display warning to tell user we can't decode the torrent file
|
// Display warning to tell user we can't decode the torrent file
|
||||||
if(!from_url.isNull()) {
|
if(!from_url.isNull()) {
|
||||||
emit invalidTorrent(from_url);
|
emit invalidTorrent(from_url);
|
||||||
QFile::remove(file);
|
|
||||||
}else{
|
}else{
|
||||||
emit invalidTorrent(file);
|
emit invalidTorrent(file);
|
||||||
}
|
}
|
||||||
@@ -592,24 +533,6 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo
|
|||||||
// Display warning to tell user we can't decode the torrent file
|
// Display warning to tell user we can't decode the torrent file
|
||||||
if(!from_url.isNull()) {
|
if(!from_url.isNull()) {
|
||||||
emit invalidTorrent(from_url);
|
emit invalidTorrent(from_url);
|
||||||
qDebug("File path is: %s", file.toUtf8().data());
|
|
||||||
QFile::remove(file);
|
|
||||||
}else{
|
|
||||||
emit invalidTorrent(file);
|
|
||||||
}
|
|
||||||
if(fromScanDir) {
|
|
||||||
// Remove .corrupt file in case it already exists
|
|
||||||
QFile::remove(file+".corrupt");
|
|
||||||
//Rename file extension so that it won't display error message more than once
|
|
||||||
QFile::rename(file,file+".corrupt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception& e) {
|
|
||||||
std::cerr << "Could not decode file, reason: " << e.what() << '\n';
|
|
||||||
// Display warning to tell user we can't decode the torrent file
|
|
||||||
if(!from_url.isNull()) {
|
|
||||||
emit invalidTorrent(from_url);
|
|
||||||
QFile::remove(file);
|
|
||||||
}else{
|
}else{
|
||||||
emit invalidTorrent(file);
|
emit invalidTorrent(file);
|
||||||
}
|
}
|
||||||
@@ -688,54 +611,30 @@ bool bittorrent::isDHTEnabled() const{
|
|||||||
|
|
||||||
void bittorrent::enableUPnP(bool b) {
|
void bittorrent::enableUPnP(bool b) {
|
||||||
if(b) {
|
if(b) {
|
||||||
if(!UPnPEnabled) {
|
|
||||||
qDebug("Enabling UPnP");
|
|
||||||
s->start_upnp();
|
s->start_upnp();
|
||||||
UPnPEnabled = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(UPnPEnabled) {
|
|
||||||
qDebug("Disabling UPnP");
|
|
||||||
s->stop_upnp();
|
s->stop_upnp();
|
||||||
UPnPEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::enableNATPMP(bool b) {
|
void bittorrent::enableNATPMP(bool b) {
|
||||||
if(b) {
|
if(b) {
|
||||||
if(!NATPMPEnabled) {
|
|
||||||
qDebug("Enabling NAT-PMP");
|
|
||||||
s->start_natpmp();
|
s->start_natpmp();
|
||||||
NATPMPEnabled = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(NATPMPEnabled) {
|
|
||||||
qDebug("Disabling NAT-PMP");
|
|
||||||
s->stop_natpmp();
|
s->stop_natpmp();
|
||||||
NATPMPEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::enableLSD(bool b) {
|
void bittorrent::enableLSD(bool b) {
|
||||||
if(b) {
|
if(b) {
|
||||||
if(!LSDEnabled) {
|
|
||||||
qDebug("Enabling LSD");
|
|
||||||
s->start_lsd();
|
s->start_lsd();
|
||||||
LSDEnabled = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(LSDEnabled) {
|
|
||||||
qDebug("Disabling LSD");
|
|
||||||
s->stop_lsd();
|
s->stop_lsd();
|
||||||
LSDEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable DHT
|
// Enable DHT
|
||||||
bool bittorrent::enableDHT(bool b) {
|
void bittorrent::enableDHT(bool b) {
|
||||||
if(b) {
|
if(b) {
|
||||||
if(!DHTEnabled) {
|
if(!DHTEnabled) {
|
||||||
boost::filesystem::ifstream dht_state_file((misc::qBittorrentPath()+QString::fromUtf8("dht_state")).toUtf8().data(), std::ios_base::binary);
|
boost::filesystem::ifstream dht_state_file((misc::qBittorrentPath()+QString::fromUtf8("dht_state")).toUtf8().data(), std::ios_base::binary);
|
||||||
@@ -744,17 +643,12 @@ bool bittorrent::enableDHT(bool b) {
|
|||||||
try{
|
try{
|
||||||
dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>());
|
dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>());
|
||||||
}catch (std::exception&) {}
|
}catch (std::exception&) {}
|
||||||
try {
|
|
||||||
s->start_dht(dht_state);
|
s->start_dht(dht_state);
|
||||||
s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));
|
s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));
|
||||||
s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));
|
s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));
|
||||||
s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));
|
s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));
|
||||||
DHTEnabled = true;
|
DHTEnabled = true;
|
||||||
qDebug("DHT enabled");
|
qDebug("DHT enabled");
|
||||||
}catch(std::exception e) {
|
|
||||||
qDebug("Could not enable DHT, reason: %s", e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(DHTEnabled) {
|
if(DHTEnabled) {
|
||||||
@@ -763,7 +657,6 @@ bool bittorrent::enableDHT(bool b) {
|
|||||||
qDebug("DHT disabled");
|
qDebug("DHT disabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::saveTorrentSpeedLimits(QString hash) {
|
void bittorrent::saveTorrentSpeedLimits(QString hash) {
|
||||||
@@ -801,7 +694,6 @@ void bittorrent::loadTorrentSpeedLimits(QString hash) {
|
|||||||
// Read pieces priorities from .priorities file
|
// Read pieces priorities from .priorities file
|
||||||
// and ask QTorrentHandle to consider them
|
// and ask QTorrentHandle to consider them
|
||||||
void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
||||||
qDebug("Applying pieces priorities");
|
|
||||||
if(!h.is_valid()) {
|
if(!h.is_valid()) {
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
return;
|
return;
|
||||||
@@ -830,7 +722,7 @@ void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
|||||||
if( priority < 0 || priority > 7) {
|
if( priority < 0 || priority > 7) {
|
||||||
priority = 1;
|
priority = 1;
|
||||||
}
|
}
|
||||||
qDebug("Setting piece piority to %d", priority);
|
//qDebug("Setting piece piority to %d", priority);
|
||||||
v.push_back(priority);
|
v.push_back(priority);
|
||||||
}
|
}
|
||||||
h.prioritize_files(v);
|
h.prioritize_files(v);
|
||||||
@@ -916,26 +808,10 @@ void bittorrent::saveDownloadUploadForTorrent(QString hash) {
|
|||||||
ratio_file.close();
|
ratio_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only save fast resume data for unfinished and unpaused torrents (Optimization)
|
// Save fastresume data for all torrents
|
||||||
// Called periodically and on exit
|
// and remove them from the session
|
||||||
void bittorrent::saveFastResumeAndRatioData() {
|
void bittorrent::saveFastResumeAndRatioData() {
|
||||||
QString hash;
|
qDebug("Saving fast resume and ratio data");
|
||||||
QStringList hashes = getUnfinishedTorrents();
|
|
||||||
foreach(hash, hashes) {
|
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
|
||||||
if(!h.is_valid()) {
|
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(h.is_paused()) {
|
|
||||||
// Do not need to save fast resume data for paused torrents
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
saveFastResumeAndRatioData(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bittorrent::saveFastResumeAndRatioData(QString hash) {
|
|
||||||
QString file;
|
QString file;
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||||
// Checking if torrentBackup Dir exists
|
// Checking if torrentBackup Dir exists
|
||||||
@@ -943,13 +819,35 @@ void bittorrent::saveFastResumeAndRatioData(QString hash) {
|
|||||||
if(! torrentBackup.exists()) {
|
if(! torrentBackup.exists()) {
|
||||||
torrentBackup.mkpath(torrentBackup.path());
|
torrentBackup.mkpath(torrentBackup.path());
|
||||||
}
|
}
|
||||||
// Extracting resume data
|
// Pause torrents
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
std::vector<torrent_handle> handles = s->get_torrents();
|
||||||
|
for(unsigned int i=0; i<handles.size(); ++i) {
|
||||||
|
QTorrentHandle h = handles[i];
|
||||||
if(!h.is_valid()) {
|
if(!h.is_valid()) {
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
if (h.has_metadata() && h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking) {
|
// Pause download (needed before fast resume writing)
|
||||||
|
if(!h.is_paused()){
|
||||||
|
waitingForPause << h.hash();
|
||||||
|
h.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Write fast resume data
|
||||||
|
for(unsigned int i=0; i<handles.size(); ++i) {
|
||||||
|
QTorrentHandle h = handles[i];
|
||||||
|
if(!h.is_valid()) {
|
||||||
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QString hash = h.hash();
|
||||||
|
while(waitingForPause.contains(hash)) {
|
||||||
|
//qDebug("Sleeping while waiting that %s is paused", misc::toString(h.info_hash()).c_str());
|
||||||
|
SleeperThread::msleep(300);
|
||||||
|
readAlerts();
|
||||||
|
}
|
||||||
|
// Extracting resume data
|
||||||
|
if (h.has_metadata()) {
|
||||||
if(QFile::exists(torrentBackup.path()+QDir::separator()+hash+".torrent")) {
|
if(QFile::exists(torrentBackup.path()+QDir::separator()+hash+".torrent")) {
|
||||||
// Remove old .fastresume data in case it exists
|
// Remove old .fastresume data in case it exists
|
||||||
QFile::remove(torrentBackup.path()+QDir::separator()+hash + ".fastresume");
|
QFile::remove(torrentBackup.path()+QDir::separator()+hash + ".fastresume");
|
||||||
@@ -962,7 +860,13 @@ void bittorrent::saveFastResumeAndRatioData(QString hash) {
|
|||||||
}
|
}
|
||||||
// Save ratio data
|
// Save ratio data
|
||||||
saveDownloadUploadForTorrent(hash);
|
saveDownloadUploadForTorrent(hash);
|
||||||
|
// Save trackers
|
||||||
|
saveTrackerFile(hash);
|
||||||
}
|
}
|
||||||
|
// Remove torrent
|
||||||
|
s->remove_torrent(h.get_torrent_handle());
|
||||||
|
}
|
||||||
|
qDebug("Fast resume and ratio data saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bittorrent::isFilePreviewPossible(QString hash) const{
|
bool bittorrent::isFilePreviewPossible(QString hash) const{
|
||||||
@@ -1005,22 +909,13 @@ void bittorrent::setDefaultSavePath(QString savepath) {
|
|||||||
defaultSavePath = savepath;
|
defaultSavePath = savepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::setTimerScanInterval(int secs) {
|
|
||||||
if(folderScanInterval != secs) {
|
|
||||||
folderScanInterval = secs;
|
|
||||||
if(!scan_dir.isNull()) {
|
|
||||||
timerScan->start(folderScanInterval*1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable directory scanning
|
// Enable directory scanning
|
||||||
void bittorrent::enableDirectoryScanning(QString _scan_dir) {
|
void bittorrent::enableDirectoryScanning(QString _scan_dir) {
|
||||||
if(!_scan_dir.isEmpty()) {
|
if(!_scan_dir.isEmpty()) {
|
||||||
scan_dir = _scan_dir;
|
scan_dir = _scan_dir;
|
||||||
timerScan = new QTimer(this);
|
timerScan = new QTimer(this);
|
||||||
connect(timerScan, SIGNAL(timeout()), this, SLOT(scanDirectory()));
|
connect(timerScan, SIGNAL(timeout()), this, SLOT(scanDirectory()));
|
||||||
timerScan->start(folderScanInterval*1000);
|
timerScan->start(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1084,23 +979,10 @@ void bittorrent::setGlobalRatio(float ratio) {
|
|||||||
// be automatically deleted
|
// be automatically deleted
|
||||||
void bittorrent::setDeleteRatio(float ratio) {
|
void bittorrent::setDeleteRatio(float ratio) {
|
||||||
if(ratio != -1 && ratio < 1.) ratio = 1.;
|
if(ratio != -1 && ratio < 1.) ratio = 1.;
|
||||||
if(max_ratio == -1 && ratio != -1) {
|
|
||||||
Q_ASSERT(!BigRatioTimer);
|
|
||||||
BigRatioTimer = new QTimer(this);
|
|
||||||
connect(BigRatioTimer, SIGNAL(timeout()), this, SLOT(deleteBigRatios()));
|
|
||||||
BigRatioTimer->start(5000);
|
|
||||||
} else {
|
|
||||||
if(max_ratio != -1 && ratio == -1) {
|
|
||||||
delete BigRatioTimer;
|
|
||||||
BigRatioTimer = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(max_ratio != ratio) {
|
|
||||||
max_ratio = ratio;
|
max_ratio = ratio;
|
||||||
qDebug("* Set deleteRatio to %.1f", max_ratio);
|
qDebug("* Set deleteRatio to %.1f", max_ratio);
|
||||||
deleteBigRatios();
|
deleteBigRatios();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool bittorrent::loadTrackerFile(QString hash) {
|
bool bittorrent::loadTrackerFile(QString hash) {
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||||
@@ -1120,7 +1002,6 @@ bool bittorrent::loadTrackerFile(QString hash) {
|
|||||||
if(trackers.size() != 0) {
|
if(trackers.size() != 0) {
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
h.replace_trackers(trackers);
|
h.replace_trackers(trackers);
|
||||||
h.force_reannounce();
|
|
||||||
return true;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
return false;
|
return false;
|
||||||
@@ -1128,7 +1009,6 @@ bool bittorrent::loadTrackerFile(QString hash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::saveTrackerFile(QString hash) {
|
void bittorrent::saveTrackerFile(QString hash) {
|
||||||
qDebug("Saving tracker file for %s", hash.toUtf8().data());
|
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||||
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
|
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
|
||||||
if(tracker_file.exists()) {
|
if(tracker_file.exists()) {
|
||||||
@@ -1160,25 +1040,15 @@ void bittorrent::setDHTPort(int dht_port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enable IP Filtering
|
// Enable IP Filtering
|
||||||
void bittorrent::enableIPFilter(QString filter) {
|
void bittorrent::enableIPFilter(ip_filter filter) {
|
||||||
qDebug("Enabling IPFiler");
|
qDebug("Enabling IPFiler");
|
||||||
if(!filterParser) {
|
s->set_ip_filter(filter);
|
||||||
filterParser = new FilterParserThread(this, s);
|
|
||||||
}
|
|
||||||
if(filterPath.isEmpty() || filterPath != filter) {
|
|
||||||
filterPath = filter;
|
|
||||||
filterParser->processFilterFile(filter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable IP Filtering
|
// Disable IP Filtering
|
||||||
void bittorrent::disableIPFilter() {
|
void bittorrent::disableIPFilter() {
|
||||||
qDebug("Disabling IPFilter");
|
qDebug("Disabling IPFilter");
|
||||||
s->set_ip_filter(ip_filter());
|
s->set_ip_filter(ip_filter());
|
||||||
if(filterParser) {
|
|
||||||
delete filterParser;
|
|
||||||
}
|
|
||||||
filterPath = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set BT session settings (user_agent)
|
// Set BT session settings (user_agent)
|
||||||
@@ -1229,36 +1099,33 @@ void bittorrent::readAlerts() {
|
|||||||
// Level: fatal
|
// Level: fatal
|
||||||
QTorrentHandle h(p->handle);
|
QTorrentHandle h(p->handle);
|
||||||
if(h.is_valid()){
|
if(h.is_valid()){
|
||||||
// Authentication
|
|
||||||
if(p->status_code != 401) {
|
|
||||||
QString hash = h.hash();
|
QString hash = h.hash();
|
||||||
qDebug("Received a tracker error for %s", p->url.c_str());
|
QList<QPair<QString, QString> > errors = trackersErrors.value(hash, QList<QPair<QString, QString> >());
|
||||||
QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>());
|
if(errors.size() > MAX_TRACKER_ERRORS)
|
||||||
// p->url requires at least libtorrent v0.13.1
|
errors.removeAt(0);
|
||||||
errors[misc::toQString(p->url)] = QString::fromUtf8(a->msg().c_str());
|
errors << QPair<QString,QString>(QTime::currentTime().toString("hh:mm:ss"), QString::fromUtf8(a->msg().c_str()));
|
||||||
trackersErrors[hash] = errors;
|
trackersErrors[hash] = errors;
|
||||||
} else {
|
// Authentication
|
||||||
|
if(p->status_code == 401) {
|
||||||
emit trackerAuthenticationRequired(h);
|
emit trackerAuthenticationRequired(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tracker_reply_alert* p = dynamic_cast<tracker_reply_alert*>(a.get())) {
|
else if (torrent_paused_alert* p = dynamic_cast<torrent_paused_alert*>(a.get())) {
|
||||||
QTorrentHandle h(p->handle);
|
QTorrentHandle h(p->handle);
|
||||||
if(h.is_valid()){
|
if(h.is_valid()){
|
||||||
qDebug("Received a tracker reply from %s", (const char*)h.current_tracker().toUtf8());
|
|
||||||
QString hash = h.hash();
|
QString hash = h.hash();
|
||||||
QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>());
|
qDebug("Received torrent_paused_alert for %s", hash.toUtf8().data());
|
||||||
// p->url requires at least libtorrent v0.13.1
|
int index = waitingForPause.indexOf(hash);
|
||||||
errors.remove(h.current_tracker());
|
if(index != -1){
|
||||||
trackersErrors[hash] = errors;
|
waitingForPause.removeAt(index);
|
||||||
|
}
|
||||||
|
index = reloadingTorrents.indexOf(hash);
|
||||||
|
if(index != -1) {
|
||||||
|
reloadingTorrents.removeAt(index);
|
||||||
|
reloadTorrent(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) {
|
|
||||||
emit UPnPError(QString(p->msg().c_str()));
|
|
||||||
}
|
|
||||||
else if (portmap_alert* p = dynamic_cast<portmap_alert*>(a.get())) {
|
|
||||||
qDebug("UPnP Success, msg: %s", p->msg().c_str());
|
|
||||||
emit UPnPSuccess(QString(p->msg().c_str()));
|
|
||||||
}
|
}
|
||||||
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
|
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
|
||||||
emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
|
emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
|
||||||
@@ -1284,10 +1151,6 @@ void bittorrent::readAlerts() {
|
|||||||
// Pause torrent
|
// Pause torrent
|
||||||
pauseTorrent(hash);
|
pauseTorrent(hash);
|
||||||
qDebug("%s was paused after checking", hash.toUtf8().data());
|
qDebug("%s was paused after checking", hash.toUtf8().data());
|
||||||
} else {
|
|
||||||
// Save Addition DateTime
|
|
||||||
TorrentsStartTime[hash] = QDateTime::currentDateTime();
|
|
||||||
TorrentsStartData[hash] = h.total_payload_download();
|
|
||||||
}
|
}
|
||||||
emit torrentFinishedChecking(hash);
|
emit torrentFinishedChecking(hash);
|
||||||
}
|
}
|
||||||
@@ -1296,16 +1159,32 @@ void bittorrent::readAlerts() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, QString> bittorrent::getTrackersErrors(QString hash) const{
|
QList<QPair<QString, QString> > bittorrent::getTrackersErrors(QString hash) const{
|
||||||
return trackersErrors.value(hash, QHash<QString, QString>());
|
return trackersErrors.value(hash, QList<QPair<QString, QString> >());
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList bittorrent::getTorrentsToPauseAfterChecking() const{
|
QStringList bittorrent::getTorrentsToPauseAfterChecking() const{
|
||||||
return torrentsToPauseAfterChecking;
|
return torrentsToPauseAfterChecking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to reload the torrent async after the torrent is actually
|
||||||
|
// paused so that we can get fastresume data
|
||||||
|
void bittorrent::pauseAndReloadTorrent(QTorrentHandle h) {
|
||||||
|
if(!h.is_valid()) {
|
||||||
|
std::cerr << "/!\\ Error: Invalid handle\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ask to pause the torrent (async)
|
||||||
|
h.pause();
|
||||||
|
QString hash = h.hash();
|
||||||
|
// Add it to reloadingTorrents list so that we now we
|
||||||
|
// we should reload the torrent once we receive the
|
||||||
|
// torrent_paused_alert. pause() is async now...
|
||||||
|
reloadingTorrents << hash;
|
||||||
|
}
|
||||||
|
|
||||||
// Reload a torrent with full allocation mode
|
// Reload a torrent with full allocation mode
|
||||||
void bittorrent::reloadTorrent(const QTorrentHandle &h, bool full_alloc) {
|
void bittorrent::reloadTorrent(const QTorrentHandle &h) {
|
||||||
qDebug("** Reloading a torrent");
|
qDebug("** Reloading a torrent");
|
||||||
if(!h.is_valid()) {
|
if(!h.is_valid()) {
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
@@ -1333,18 +1212,11 @@ void bittorrent::reloadTorrent(const QTorrentHandle &h, bool full_alloc) {
|
|||||||
// Add torrent again to session
|
// Add torrent again to session
|
||||||
unsigned int timeout = 0;
|
unsigned int timeout = 0;
|
||||||
while(h.is_valid() && timeout < 6) {
|
while(h.is_valid() && timeout < 6) {
|
||||||
qDebug("Waiting for the torrent to be removed...");
|
|
||||||
SleeperThread::msleep(1000);
|
SleeperThread::msleep(1000);
|
||||||
++timeout;
|
++timeout;
|
||||||
}
|
}
|
||||||
QTorrentHandle new_h;
|
QTorrentHandle new_h = s->add_torrent(t, saveDir, resumeData, false);
|
||||||
if(full_alloc) {
|
|
||||||
new_h = s->add_torrent(t, saveDir, resumeData, storage_mode_allocate);
|
|
||||||
qDebug("Using full allocation mode");
|
qDebug("Using full allocation mode");
|
||||||
} else {
|
|
||||||
new_h = s->add_torrent(t, saveDir, resumeData, storage_mode_sparse);
|
|
||||||
qDebug("Using sparse mode");
|
|
||||||
}
|
|
||||||
// Connections limit per torrent
|
// Connections limit per torrent
|
||||||
new_h.set_max_connections(maxConnecsPerTorrent);
|
new_h.set_max_connections(maxConnecsPerTorrent);
|
||||||
// Uploads limit per torrent
|
// Uploads limit per torrent
|
||||||
@@ -1389,7 +1261,6 @@ QString bittorrent::getSavePath(QString hash) {
|
|||||||
savePath = QString::fromUtf8(line.data());
|
savePath = QString::fromUtf8(line.data());
|
||||||
}else{
|
}else{
|
||||||
// use default save path
|
// use default save path
|
||||||
qDebug("Using default save path because none was set");
|
|
||||||
savePath = defaultSavePath;
|
savePath = defaultSavePath;
|
||||||
}
|
}
|
||||||
// Checking if savePath Dir exists
|
// Checking if savePath Dir exists
|
||||||
@@ -1465,7 +1336,7 @@ void bittorrent::applyEncryptionSettings(pe_settings se) {
|
|||||||
s->set_pe_settings(se);
|
s->set_pe_settings(se);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will fast resume torrents in
|
// Will fast resume unfinished torrents in
|
||||||
// backup directory
|
// backup directory
|
||||||
void bittorrent::resumeUnfinishedTorrents() {
|
void bittorrent::resumeUnfinishedTorrents() {
|
||||||
qDebug("Resuming unfinished torrents");
|
qDebug("Resuming unfinished torrents");
|
||||||
@@ -1481,7 +1352,7 @@ void bittorrent::resumeUnfinishedTorrents() {
|
|||||||
}
|
}
|
||||||
// Resume downloads
|
// Resume downloads
|
||||||
foreach(fileName, filePaths) {
|
foreach(fileName, filePaths) {
|
||||||
addTorrent(fileName, false, QString(), true);
|
addTorrent(fileName, false);
|
||||||
}
|
}
|
||||||
qDebug("Unfinished torrents resumed");
|
qDebug("Unfinished torrents resumed");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,8 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
#include <libtorrent/session.hpp>
|
#include <libtorrent/session.hpp>
|
||||||
#include <libtorrent/ip_filter.hpp>
|
|
||||||
#include "qtorrenthandle.h"
|
#include "qtorrenthandle.h"
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
@@ -36,7 +34,6 @@ using namespace libtorrent;
|
|||||||
class downloadThread;
|
class downloadThread;
|
||||||
class deleteThread;
|
class deleteThread;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
class FilterParserThread;
|
|
||||||
|
|
||||||
class bittorrent : public QObject{
|
class bittorrent : public QObject{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -46,17 +43,18 @@ class bittorrent : public QObject{
|
|||||||
QString scan_dir;
|
QString scan_dir;
|
||||||
QTimer *timerScan;
|
QTimer *timerScan;
|
||||||
QTimer *timerAlerts;
|
QTimer *timerAlerts;
|
||||||
QTimer *fastResumeSaver;
|
|
||||||
QTimer *BigRatioTimer;
|
|
||||||
bool DHTEnabled;
|
bool DHTEnabled;
|
||||||
downloadThread *downloader;
|
downloadThread *downloader;
|
||||||
QString defaultSavePath;
|
QString defaultSavePath;
|
||||||
QStringList torrentsToPauseAfterChecking;
|
QStringList torrentsToPauseAfterChecking;
|
||||||
QHash<QString, QDateTime> TorrentsStartTime;
|
QStringList reloadingTorrents;
|
||||||
QHash<QString, size_type> TorrentsStartData;
|
QHash<QString, QList<qlonglong> > ETAstats;
|
||||||
|
QHash<QString, qlonglong> ETAs;
|
||||||
QHash<QString, QPair<size_type,size_type> > ratioData;
|
QHash<QString, QPair<size_type,size_type> > ratioData;
|
||||||
QHash<QString, QHash<QString, QString> > trackersErrors;
|
QTimer *ETARefresher;
|
||||||
|
QHash<QString, QList<QPair<QString, QString> > > trackersErrors;
|
||||||
deleteThread *deleter;
|
deleteThread *deleter;
|
||||||
|
QStringList waitingForPause;
|
||||||
QStringList finishedTorrents;
|
QStringList finishedTorrents;
|
||||||
QStringList unfinishedTorrents;
|
QStringList unfinishedTorrents;
|
||||||
bool preAllocateAll;
|
bool preAllocateAll;
|
||||||
@@ -64,12 +62,6 @@ class bittorrent : public QObject{
|
|||||||
int maxConnecsPerTorrent;
|
int maxConnecsPerTorrent;
|
||||||
int maxUploadsPerTorrent;
|
int maxUploadsPerTorrent;
|
||||||
float max_ratio;
|
float max_ratio;
|
||||||
bool UPnPEnabled;
|
|
||||||
bool NATPMPEnabled;
|
|
||||||
bool LSDEnabled;
|
|
||||||
FilterParserThread *filterParser;
|
|
||||||
QString filterPath;
|
|
||||||
int folderScanInterval; // in seconds
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString getSavePath(QString hash);
|
QString getSavePath(QString hash);
|
||||||
@@ -87,36 +79,33 @@ class bittorrent : public QObject{
|
|||||||
session_status getSessionStatus() const;
|
session_status getSessionStatus() const;
|
||||||
int getListenPort() const;
|
int getListenPort() const;
|
||||||
QStringList getTorrentsToPauseAfterChecking() const;
|
QStringList getTorrentsToPauseAfterChecking() const;
|
||||||
qlonglong getETA(QString hash) const;
|
long getETA(QString hash) const;
|
||||||
float getRealRatio(QString hash) const;
|
float getRealRatio(QString hash) const;
|
||||||
session* getSession() const;
|
session* getSession() const;
|
||||||
QHash<QString, QString> getTrackersErrors(QString hash) const;
|
QList<QPair<QString, QString> > getTrackersErrors(QString hash) const;
|
||||||
QStringList getFinishedTorrents() const;
|
QStringList getFinishedTorrents() const;
|
||||||
QStringList getUnfinishedTorrents() const;
|
QStringList getUnfinishedTorrents() const;
|
||||||
bool isFinished(QString hash) const;
|
bool isFinished(QString hash) const;
|
||||||
bool has_filtered_files(QString hash) const;
|
bool has_filtered_files(QString hash) const;
|
||||||
unsigned int getFinishedPausedTorrentsNb() const;
|
|
||||||
unsigned int getUnfinishedPausedTorrentsNb() const;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString());
|
||||||
void downloadFromUrl(QString url);
|
void downloadFromUrl(QString url);
|
||||||
void downloadFromURLList(const QStringList& url_list);
|
void downloadFromURLList(const QStringList& url_list);
|
||||||
void deleteTorrent(QString hash, bool permanent = false);
|
void deleteTorrent(QString hash, bool permanent = false);
|
||||||
bool pauseTorrent(QString hash);
|
bool pauseTorrent(QString hash);
|
||||||
bool resumeTorrent(QString hash);
|
bool resumeTorrent(QString hash);
|
||||||
void pauseAllTorrents();
|
|
||||||
void resumeAllTorrents();
|
|
||||||
void saveDHTEntry();
|
void saveDHTEntry();
|
||||||
void preAllocateAllFiles(bool b);
|
void preAllocateAllFiles(bool b);
|
||||||
void saveFastResumeAndRatioData();
|
void saveFastResumeAndRatioData();
|
||||||
void saveFastResumeAndRatioData(QString hash);
|
|
||||||
void enableDirectoryScanning(QString scan_dir);
|
void enableDirectoryScanning(QString scan_dir);
|
||||||
void disableDirectoryScanning();
|
void disableDirectoryScanning();
|
||||||
void enablePeerExchange();
|
void enablePeerExchange();
|
||||||
void enableIPFilter(QString filter);
|
void enableIPFilter(ip_filter filter);
|
||||||
void disableIPFilter();
|
void disableIPFilter();
|
||||||
|
void pauseAndReloadTorrent(QTorrentHandle h);
|
||||||
void resumeUnfinishedTorrents();
|
void resumeUnfinishedTorrents();
|
||||||
|
void updateETAs();
|
||||||
void saveTorrentSpeedLimits(QString hash);
|
void saveTorrentSpeedLimits(QString hash);
|
||||||
void loadTorrentSpeedLimits(QString hash);
|
void loadTorrentSpeedLimits(QString hash);
|
||||||
void saveDownloadUploadForTorrent(QString hash);
|
void saveDownloadUploadForTorrent(QString hash);
|
||||||
@@ -146,9 +135,7 @@ class bittorrent : public QObject{
|
|||||||
void enableUPnP(bool b);
|
void enableUPnP(bool b);
|
||||||
void enableNATPMP(bool b);
|
void enableNATPMP(bool b);
|
||||||
void enableLSD(bool b);
|
void enableLSD(bool b);
|
||||||
bool enableDHT(bool b);
|
void enableDHT(bool b);
|
||||||
void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
|
|
||||||
void setTimerScanInterval(int secs);
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void scanDirectory();
|
void scanDirectory();
|
||||||
@@ -156,15 +143,13 @@ class bittorrent : public QObject{
|
|||||||
void processDownloadedFile(QString, QString);
|
void processDownloadedFile(QString, QString);
|
||||||
bool loadTrackerFile(QString hash);
|
bool loadTrackerFile(QString hash);
|
||||||
void saveTrackerFile(QString hash);
|
void saveTrackerFile(QString hash);
|
||||||
|
void reloadTorrent(const QTorrentHandle &h); // This is protected now, call pauseAndReloadTorrent() instead
|
||||||
void deleteBigRatios();
|
void deleteBigRatios();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void invalidTorrent(QString path);
|
void invalidTorrent(QString path);
|
||||||
void duplicateTorrent(QString path);
|
void duplicateTorrent(QString path);
|
||||||
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume);
|
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume);
|
||||||
void deletedTorrent(QString hash);
|
|
||||||
void pausedTorrent(QString hash);
|
|
||||||
void resumedTorrent(QString hash);
|
|
||||||
void finishedTorrent(QTorrentHandle& h);
|
void finishedTorrent(QTorrentHandle& h);
|
||||||
void fullDiskError(QTorrentHandle& h);
|
void fullDiskError(QTorrentHandle& h);
|
||||||
void trackerError(QString hash, QString time, QString msg);
|
void trackerError(QString hash, QString time, QString msg);
|
||||||
@@ -179,9 +164,7 @@ class bittorrent : public QObject{
|
|||||||
void fastResumeDataRejected(QString name);
|
void fastResumeDataRejected(QString name);
|
||||||
void urlSeedProblem(QString url, QString msg);
|
void urlSeedProblem(QString url, QString msg);
|
||||||
void torrentFinishedChecking(QString hash);
|
void torrentFinishedChecking(QString hash);
|
||||||
void torrent_ratio_deleted(QString fileName);
|
void torrent_deleted(QString hash, QString fileName, bool finished);
|
||||||
void UPnPError(QString msg);
|
|
||||||
void UPnPSuccess(QString msg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
19
src/convertPOtoTS.py
Normal file
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
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>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>592</width>
|
<width>592</width>
|
||||||
<height>655</height>
|
<height>590</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle" >
|
||||||
@@ -477,20 +477,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<layout class="QHBoxLayout" >
|
<layout class="QHBoxLayout" >
|
||||||
<property name="spacing" >
|
<property name="spacing" >
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
#include <libtorrent/file_pool.hpp>
|
#include <libtorrent/file_pool.hpp>
|
||||||
|
|
||||||
#include "createtorrent_imp.h"
|
#include "createtorrent_imp.h"
|
||||||
#include "misc.h"
|
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
using namespace boost::filesystem;
|
using namespace boost::filesystem;
|
||||||
@@ -44,17 +43,9 @@ using namespace boost::filesystem;
|
|||||||
createtorrent::createtorrent(QWidget *parent): QDialog(parent){
|
createtorrent::createtorrent(QWidget *parent): QDialog(parent){
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
creatorThread = new torrentCreatorThread();
|
|
||||||
connect(creatorThread, SIGNAL(creationSuccess(QString)), this, SLOT(handleCreationSucess(QString)));
|
|
||||||
connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString)));
|
|
||||||
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
|
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
createtorrent::~createtorrent() {
|
|
||||||
delete creatorThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
void createtorrent::on_addFolder_button_clicked(){
|
void createtorrent::on_addFolder_button_clicked(){
|
||||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly);
|
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly);
|
||||||
if(!dir.isEmpty())
|
if(!dir.isEmpty())
|
||||||
@@ -129,13 +120,11 @@ void createtorrent::on_addURLSeed_button_clicked(){
|
|||||||
// Subfunction to add files to a torrent_info structure
|
// Subfunction to add files to a torrent_info structure
|
||||||
// Written by Arvid Norberg (libtorrent Author)
|
// Written by Arvid Norberg (libtorrent Author)
|
||||||
void add_files(torrent_info& t, path const& p, path const& l){
|
void add_files(torrent_info& t, path const& p, path const& l){
|
||||||
qDebug("p: %s, l: %s, l.leaf(): %s", p.string().c_str(), l.string().c_str(), l.leaf().c_str());
|
|
||||||
path f(p / l);
|
path f(p / l);
|
||||||
if (is_directory(f)){
|
if (is_directory(f)){
|
||||||
for (directory_iterator i(f), end; i != end; ++i)
|
for (directory_iterator i(f), end; i != end; ++i)
|
||||||
add_files(t, p, l / i->leaf());
|
add_files(t, p, l / i->leaf());
|
||||||
}else{
|
}else{
|
||||||
qDebug("Adding %s", l.string().c_str());
|
|
||||||
t.add_file(l, file_size(f));
|
t.add_file(l, file_size(f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,9 +141,7 @@ QStringList createtorrent::allItems(QListWidget *list){
|
|||||||
// Main function that create a .torrent file
|
// Main function that create a .torrent file
|
||||||
void createtorrent::on_createButton_clicked(){
|
void createtorrent::on_createButton_clicked(){
|
||||||
QString input = textInputPath->text().trimmed();
|
QString input = textInputPath->text().trimmed();
|
||||||
if (input.endsWith(QDir::separator()))
|
if(input.isEmpty() == 0){
|
||||||
input.chop(1);
|
|
||||||
if(input.isEmpty()){
|
|
||||||
QMessageBox::critical(0, tr("No input path set"), tr("Please type an input path first"));
|
QMessageBox::critical(0, tr("No input path set"), tr("Please type an input path first"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -170,70 +157,27 @@ void createtorrent::on_createButton_clicked(){
|
|||||||
} else {
|
} else {
|
||||||
return;
|
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, QString hash) {
|
|
||||||
if(checkStartSeeding->isChecked()) {
|
|
||||||
// Create save path file
|
|
||||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
|
||||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
savepath_file.write(branch_path);
|
|
||||||
savepath_file.close();
|
|
||||||
emit torrent_to_seed(path);
|
|
||||||
}
|
|
||||||
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void createtorrent::updateProgressBar(int progress) {
|
|
||||||
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 torrentCreatorThread::run() {
|
|
||||||
emit updateProgress(0);
|
|
||||||
char const* creator_str = "qBittorrent "VERSION;
|
char const* creator_str = "qBittorrent "VERSION;
|
||||||
try {
|
try {
|
||||||
boost::intrusive_ptr<torrent_info> t(new torrent_info);
|
boost::intrusive_ptr<torrent_info> t(new torrent_info);
|
||||||
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
|
ofstream out(complete(path((const char*)destination.toUtf8())), std::ios_base::binary);
|
||||||
|
path full_path;
|
||||||
// Adding files to the torrent
|
// Adding files to the torrent
|
||||||
path full_path = complete(path(input_path.toUtf8().data()));
|
full_path = complete(path(input.toUtf8().data()));
|
||||||
add_files(*t, full_path.branch_path(), full_path.leaf());
|
add_files(*t, full_path.branch_path(), full_path.leaf());
|
||||||
if(abort) return;
|
|
||||||
// Set piece size
|
// Set piece size
|
||||||
|
int piece_size = getPieceSize();
|
||||||
t->set_piece_size(piece_size);
|
t->set_piece_size(piece_size);
|
||||||
// Add url seeds
|
// Add url seeds
|
||||||
|
QStringList urlSeeds = allItems(URLSeeds_list);
|
||||||
QString seed;
|
QString seed;
|
||||||
foreach(seed, url_seeds){
|
foreach(seed, urlSeeds){
|
||||||
t->add_url_seed(seed.toUtf8().data());
|
t->add_url_seed(seed.toUtf8().data());
|
||||||
}
|
}
|
||||||
for(int i=0; i<trackers.size(); ++i){
|
for(int i=0; i<trackers.size(); ++i){
|
||||||
t->add_tracker(trackers.at(i).toUtf8().data());
|
t->add_tracker(trackers.at(i).toUtf8().data());
|
||||||
}
|
}
|
||||||
if(abort) return;
|
|
||||||
// calculate the hash for all pieces
|
// calculate the hash for all pieces
|
||||||
file_pool fp;
|
file_pool fp;
|
||||||
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp));
|
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp));
|
||||||
@@ -243,26 +187,27 @@ void torrentCreatorThread::run() {
|
|||||||
st->read(&buf[0], i, 0, t->piece_size(i));
|
st->read(&buf[0], i, 0, t->piece_size(i));
|
||||||
hasher h(&buf[0], t->piece_size(i));
|
hasher h(&buf[0], t->piece_size(i));
|
||||||
t->set_hash(i, h.final());
|
t->set_hash(i, h.final());
|
||||||
emit updateProgress((int)(i*100./(float)num));
|
|
||||||
if(abort) return;
|
|
||||||
}
|
}
|
||||||
// Set qBittorrent as creator and add user comment to
|
// Set qBittorrent as creator and add user comment to
|
||||||
// torrent_info structure
|
// torrent_info structure
|
||||||
t->set_creator(creator_str);
|
t->set_creator(creator_str);
|
||||||
t->set_comment((const char*)comment.toUtf8());
|
t->set_comment((const char*)txt_comment->toPlainText().toUtf8());
|
||||||
// Is private ?
|
// Is private ?
|
||||||
if(is_private){
|
if(check_private->isChecked()){
|
||||||
t->set_priv(true);
|
t->set_priv(true);
|
||||||
}
|
}
|
||||||
if(abort) return;
|
|
||||||
// create the torrent and print it to out
|
// create the torrent and print it to out
|
||||||
entry e = t->create_torrent();
|
entry e = t->create_torrent();
|
||||||
libtorrent::bencode(std::ostream_iterator<char>(out), e);
|
libtorrent::bencode(std::ostream_iterator<char>(out), e);
|
||||||
out.flush();
|
if(checkStartSeeding->isChecked())
|
||||||
emit updateProgress(100);
|
emit torrent_to_seed(destination);
|
||||||
emit creationSuccess(save_path, full_path.branch_path().string().c_str(), misc::toQString(t->info_hash()));
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e){
|
catch (std::exception& e){
|
||||||
emit creationFailure(QString::fromUtf8(e.what()));
|
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,48 +22,13 @@
|
|||||||
#ifndef CREATE_TORRENT_IMP_H
|
#ifndef CREATE_TORRENT_IMP_H
|
||||||
#define CREATE_TORRENT_IMP_H
|
#define CREATE_TORRENT_IMP_H
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include "ui_createtorrent.h"
|
#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;
|
|
||||||
|
|
||||||
public:
|
|
||||||
torrentCreatorThread() {}
|
|
||||||
~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, QString hash);
|
|
||||||
void updateProgress(int progress);
|
|
||||||
};
|
|
||||||
|
|
||||||
class createtorrent : public QDialog, private Ui::createTorrentDialog{
|
class createtorrent : public QDialog, private Ui::createTorrentDialog{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
|
||||||
torrentCreatorThread *creatorThread;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
createtorrent(QWidget *parent = 0);
|
createtorrent(QWidget *parent = 0);
|
||||||
~createtorrent();
|
|
||||||
QStringList allItems(QListWidget *list);
|
QStringList allItems(QListWidget *list);
|
||||||
int getPieceSize() const;
|
int getPieceSize() const;
|
||||||
|
|
||||||
@@ -78,9 +43,6 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
|
|||||||
void on_removeTracker_button_clicked();
|
void on_removeTracker_button_clicked();
|
||||||
void on_addURLSeed_button_clicked();
|
void on_addURLSeed_button_clicked();
|
||||||
void on_removeURLSeed_button_clicked();
|
void on_removeURLSeed_button_clicked();
|
||||||
void handleCreationFailure(QString msg);
|
|
||||||
void handleCreationSuccess(QString path, const char* branch_path, QString hash);
|
|
||||||
void updateProgressBar(int progress);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
263
src/download.ui
263
src/download.ui
@@ -21,6 +21,185 @@
|
|||||||
<property name="margin" >
|
<property name="margin" >
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</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>
|
<item>
|
||||||
<widget class="QTreeView" name="downloadList" >
|
<widget class="QTreeView" name="downloadList" >
|
||||||
<property name="minimumSize" >
|
<property name="minimumSize" >
|
||||||
@@ -63,14 +242,6 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="log_tab" >
|
<widget class="QWidget" name="log_tab" >
|
||||||
<property name="geometry" >
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>765</width>
|
|
||||||
<height>138</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<attribute name="title" >
|
<attribute name="title" >
|
||||||
<string>Log</string>
|
<string>Log</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
@@ -84,7 +255,9 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTextBrowser" name="infoBar" >
|
<widget class="QTextBrowser" name="infoBar" >
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy" >
|
||||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
<sizepolicy>
|
||||||
|
<hsizetype>7</hsizetype>
|
||||||
|
<vsizetype>7</vsizetype>
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
@@ -103,14 +276,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="filter_tab" >
|
<widget class="QWidget" name="filter_tab" >
|
||||||
<property name="geometry" >
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>765</width>
|
|
||||||
<height>138</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<attribute name="title" >
|
<attribute name="title" >
|
||||||
<string>IP filter</string>
|
<string>IP filter</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
@@ -181,69 +346,7 @@
|
|||||||
<string>Torrent Properties</string>
|
<string>Torrent Properties</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</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>
|
|
||||||
<zorder>tabBottom</zorder>
|
|
||||||
<zorder></zorder>
|
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources/>
|
||||||
<include location="icons.qrc" />
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
@@ -21,48 +21,43 @@
|
|||||||
|
|
||||||
#include "downloadThread.h"
|
#include "downloadThread.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QSettings>
|
#include <cc++/common.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
|
QString subDownloadThread::errorCodeToString(int status) {
|
||||||
QString subDownloadThread::errorCodeToString(CURLcode status) {
|
|
||||||
switch(status){
|
switch(status){
|
||||||
case CURLE_FTP_CANT_GET_HOST:
|
case 1://ost::URLStream::errUnreachable:
|
||||||
case CURLE_COULDNT_RESOLVE_HOST:
|
|
||||||
return tr("Host is unreachable");
|
return tr("Host is unreachable");
|
||||||
case CURLE_READ_ERROR:
|
case 2://ost::URLStream::errMissing:
|
||||||
case CURLE_FILE_COULDNT_READ_FILE:
|
|
||||||
return tr("File was not found (404)");
|
return tr("File was not found (404)");
|
||||||
case CURLE_FTP_ACCESS_DENIED:
|
case 3://ost::URLStream::errDenied:
|
||||||
case CURLE_LOGIN_DENIED:
|
|
||||||
case CURLE_FTP_USER_PASSWORD_INCORRECT:
|
|
||||||
return tr("Connection was denied");
|
return tr("Connection was denied");
|
||||||
case CURLE_URL_MALFORMAT:
|
case 4://ost::URLStream::errInvalid:
|
||||||
return tr("Url is invalid");
|
return tr("Url is invalid");
|
||||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
case 5://ost::URLStream::errForbidden:
|
||||||
return tr("Could not resolve proxy");
|
return tr("Connection forbidden (403)");
|
||||||
//case 5:
|
case 6://ost::URLStream::errUnauthorized:
|
||||||
// return tr("Connection forbidden (403)");
|
return tr("Connection was not authorized (401)");
|
||||||
//case 6:
|
case 7://ost::URLStream::errRelocated:
|
||||||
// return tr("Connection was not authorized (401)");
|
return tr("Content has moved (301)");
|
||||||
//case 7:
|
case 8://ost::URLStream::errFailure:
|
||||||
// return tr("Content has moved (301)");
|
|
||||||
case CURLE_COULDNT_CONNECT:
|
|
||||||
return tr("Connection failure");
|
return tr("Connection failure");
|
||||||
case CURLE_OPERATION_TIMEOUTED:
|
case 9://ost::URLStream::errTimeout:
|
||||||
return tr("Connection was timed out");
|
return tr("Connection was timed out");
|
||||||
case CURLE_INTERFACE_FAILED:
|
case 10://ost::URLStream::errInterface:
|
||||||
return tr("Incorrect network interface");
|
return tr("Incorrect network interface");
|
||||||
default:
|
default:
|
||||||
return tr("Unknown error");
|
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(){
|
subDownloadThread::~subDownloadThread(){
|
||||||
abort = true;
|
abort = true;
|
||||||
wait();
|
wait();
|
||||||
|
delete url_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void subDownloadThread::run(){
|
void subDownloadThread::run(){
|
||||||
@@ -73,66 +68,38 @@ void subDownloadThread::run(){
|
|||||||
filePath = tmpfile->fileName();
|
filePath = tmpfile->fileName();
|
||||||
}
|
}
|
||||||
delete tmpfile;
|
delete tmpfile;
|
||||||
FILE *f = fopen(filePath.toUtf8().data(), "wb");
|
QFile dest_file(filePath);
|
||||||
if(!f) {
|
if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){
|
||||||
std::cerr << "couldn't open destination file" << "\n";
|
std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CURL *curl;
|
ost::URLStream::Error status = url_stream->get((const char*)url.toUtf8());
|
||||||
CURLcode res;
|
if(status){
|
||||||
curl = curl_easy_init();
|
// Failure
|
||||||
if(curl) {
|
QString error_msg = errorCodeToString((int)status);
|
||||||
std::string c_url = url.toUtf8().data();
|
qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8());
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, c_url.c_str());
|
url_stream->close();
|
||||||
// SSL support
|
emit downloadFailureST(this, url, error_msg);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
return;
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
|
||||||
// PROXY SUPPORT
|
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
|
||||||
int intValue = settings.value(QString::fromUtf8("Preferences/Connection/ProxyType"), 0).toInt();
|
|
||||||
if(intValue > 0) {
|
|
||||||
// Proxy enabled
|
|
||||||
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/IP"), "0.0.0.0").toString();
|
|
||||||
QString port = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Port"), 8080).toString();
|
|
||||||
qDebug("Using proxy: %s", (IP+QString(":")+port).toUtf8().data());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toUtf8().data());
|
|
||||||
// Default proxy type is HTTP, we must change if it is SOCKS5
|
|
||||||
if(intValue%2==0) {
|
|
||||||
qDebug("Proxy is SOCKS5, not HTTP");
|
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
|
||||||
}
|
}
|
||||||
// Authentication?
|
qDebug("Downloading %s...", (const char*)url.toUtf8());
|
||||||
if(intValue > 2) {
|
char cbuf[1024];
|
||||||
qDebug("Proxy requires authentication, authenticating");
|
int len;
|
||||||
QString username = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Username"), QString()).toString();
|
while(!url_stream->eof()) {
|
||||||
QString password = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Password"), QString()).toString();
|
url_stream->read(cbuf, sizeof(cbuf));
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toUtf8().data());
|
len = url_stream->gcount();
|
||||||
|
if(len > 0)
|
||||||
|
dest_file.write(cbuf, len);
|
||||||
|
if(abort){
|
||||||
|
dest_file.close();
|
||||||
|
url_stream->close();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We have to define CURLOPT_WRITEFUNCTION or it will crash on windows
|
dest_file.close();
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
url_stream->close();
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
|
|
||||||
// Verbose
|
|
||||||
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
|
||||||
// No progress info (we don't use it)
|
|
||||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
|
||||||
// Redirections
|
|
||||||
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1);
|
|
||||||
qDebug("Downloading %s", url.toUtf8().data());
|
|
||||||
res = curl_easy_perform(curl);
|
|
||||||
/* always cleanup */
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
fclose(f);
|
|
||||||
if(res) {
|
|
||||||
emit downloadFailureST(this, url, errorCodeToString(res));
|
|
||||||
} else {
|
|
||||||
emit downloadFinishedST(this, url, filePath);
|
emit downloadFinishedST(this, url, filePath);
|
||||||
}
|
qDebug("download completed here: %s", (const char*)filePath.toUtf8());
|
||||||
} else {
|
|
||||||
std::cerr << "Could not initialize CURL" << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Download Thread **/
|
/** Download Thread **/
|
||||||
|
|||||||
@@ -29,18 +29,22 @@
|
|||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <curl/curl.h>
|
|
||||||
|
namespace ost {
|
||||||
|
class URLStream;
|
||||||
|
}
|
||||||
|
|
||||||
class subDownloadThread : public QThread {
|
class subDownloadThread : public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QString url;
|
QString url;
|
||||||
|
ost::URLStream *url_stream;
|
||||||
bool abort;
|
bool abort;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
subDownloadThread(QObject *parent, QString url);
|
subDownloadThread(QObject *parent, QString url);
|
||||||
~subDownloadThread();
|
~subDownloadThread();
|
||||||
QString errorCodeToString(CURLcode status);
|
QString errorCodeToString(int status);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// For subthreads
|
// For subthreads
|
||||||
@@ -72,13 +76,13 @@ class downloadThread : public QThread {
|
|||||||
~downloadThread();
|
~downloadThread();
|
||||||
|
|
||||||
void downloadUrl(QString url);
|
void downloadUrl(QString url);
|
||||||
void setProxy(QString IP, int port, QString username, QString password);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void propagateDownloadedFile(subDownloadThread* st, QString url, QString path);
|
void propagateDownloadedFile(subDownloadThread* st, QString url, QString path);
|
||||||
|
|
||||||
void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason);
|
void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
|||||||
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
|
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
|
||||||
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
|
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
|
||||||
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.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
|
// Set Download list model
|
||||||
DLListModel = new QStandardItemModel(0,9);
|
DLListModel = new QStandardItemModel(0,9);
|
||||||
@@ -63,7 +65,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
|||||||
downloadList->setItemDelegate(DLDelegate);
|
downloadList->setItemDelegate(DLDelegate);
|
||||||
// Hide hash column
|
// Hide hash column
|
||||||
downloadList->hideColumn(HASH);
|
downloadList->hideColumn(HASH);
|
||||||
loadHiddenColumns();
|
|
||||||
|
|
||||||
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool)));
|
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(duplicateTorrent(QString)), this, SLOT(torrentDuplicate(QString)));
|
||||||
@@ -73,8 +74,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
|||||||
connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString)));
|
connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString)));
|
||||||
connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString)));
|
connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString)));
|
||||||
connect(BTSession, SIGNAL(urlSeedProblem(QString, QString)), this, SLOT(addUrlSeedError(QString, QString)));
|
connect(BTSession, SIGNAL(urlSeedProblem(QString, QString)), this, SLOT(addUrlSeedError(QString, QString)));
|
||||||
connect(BTSession, SIGNAL(UPnPError(QString)), this, SLOT(displayUPnPError(QString)));
|
|
||||||
connect(BTSession, SIGNAL(UPnPSuccess(QString)), this, SLOT(displayUPnPSuccess(QString)));
|
|
||||||
|
|
||||||
// Load last columns width for download list
|
// Load last columns width for download list
|
||||||
if(!loadColWidthDLList()) {
|
if(!loadColWidthDLList()) {
|
||||||
@@ -87,8 +86,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
|||||||
connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
|
connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
|
||||||
connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortDownloadList(int)));
|
connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortDownloadList(int)));
|
||||||
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&)));
|
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&)));
|
||||||
downloadList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
connect(downloadList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLHoSMenu(const QPoint&)));
|
|
||||||
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&)));
|
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&)));
|
||||||
// Actions
|
// Actions
|
||||||
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
|
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
|
||||||
@@ -96,27 +93,15 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
|
|||||||
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
|
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
|
||||||
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered()));
|
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered()));
|
||||||
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
|
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
|
||||||
connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
|
|
||||||
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
|
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
|
||||||
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()));
|
|
||||||
|
|
||||||
// Set info Bar infos
|
// Set info Bar infos
|
||||||
setInfoBar(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");
|
qDebug("Download tab built");
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadingTorrents::~DownloadingTorrents() {
|
DownloadingTorrents::~DownloadingTorrents() {
|
||||||
saveColWidthDLList();
|
saveColWidthDLList();
|
||||||
saveHiddenColumns();
|
|
||||||
delete DLDelegate;
|
delete DLDelegate;
|
||||||
delete DLListModel;
|
delete DLListModel;
|
||||||
}
|
}
|
||||||
@@ -125,7 +110,7 @@ DownloadingTorrents::~DownloadingTorrents() {
|
|||||||
void DownloadingTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
|
void DownloadingTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
|
||||||
unsigned int row = index.row();
|
unsigned int row = index.row();
|
||||||
QString hash = getHashFromRow(row);
|
QString hash = getHashFromRow(row);
|
||||||
emit torrentDoubleClicked(hash, false);
|
emit torrentDoubleClicked(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadingTorrents::addLogPeerBlocked(QString ip) {
|
void DownloadingTorrents::addLogPeerBlocked(QString ip) {
|
||||||
@@ -145,8 +130,7 @@ unsigned int DownloadingTorrents::getNbTorrentsInList() const {
|
|||||||
// Note: do not actually pause the torrent in BT session
|
// Note: do not actually pause the torrent in BT session
|
||||||
void DownloadingTorrents::pauseTorrent(QString hash) {
|
void DownloadingTorrents::pauseTorrent(QString hash) {
|
||||||
int row = getRowFromHash(hash);
|
int row = getRowFromHash(hash);
|
||||||
if(row == -1)
|
Q_ASSERT(row != -1);
|
||||||
return;
|
|
||||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0));
|
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, UPSPEED), QVariant((double)0.0));
|
||||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||||
@@ -170,14 +154,11 @@ void DownloadingTorrents::setBottomTabEnabled(unsigned int index, bool b){
|
|||||||
|
|
||||||
// Show torrent properties dialog
|
// Show torrent properties dialog
|
||||||
void DownloadingTorrents::showProperties(const QModelIndex &index) {
|
void DownloadingTorrents::showProperties(const QModelIndex &index) {
|
||||||
showPropertiesFromHash(DLListModel->data(DLListModel->index(index.row(), HASH)).toString());
|
int row = index.row();
|
||||||
}
|
QString hash = DLListModel->data(DLListModel->index(row, HASH)).toString();
|
||||||
|
|
||||||
void DownloadingTorrents::showPropertiesFromHash(QString hash) {
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
properties *prop = new properties(this, BTSession, h);
|
properties *prop = new properties(this, BTSession, h);
|
||||||
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSizeAndProgress(QString)));
|
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSizeAndProgress(QString)));
|
||||||
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
|
|
||||||
prop->show();
|
prop->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,14 +181,6 @@ void DownloadingTorrents::deleteTorrent(QString hash) {
|
|||||||
emit unfinishedTorrentsNumberChanged(nbTorrents);
|
emit unfinishedTorrentsNumberChanged(nbTorrents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadingTorrents::displayUPnPError(QString msg) {
|
|
||||||
setInfoBar(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(msg), QColor("red"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DownloadingTorrents::displayUPnPSuccess(QString msg) {
|
|
||||||
DownloadingTorrents::setInfoBar(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(msg), QColor("blue"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update Info Bar information
|
// Update Info Bar information
|
||||||
void DownloadingTorrents::setInfoBar(QString info, QColor color) {
|
void DownloadingTorrents::setInfoBar(QString info, QColor color) {
|
||||||
static unsigned int nbLines = 0;
|
static unsigned int nbLines = 0;
|
||||||
@@ -217,6 +190,7 @@ void DownloadingTorrents::setInfoBar(QString info, QColor color) {
|
|||||||
infoBar->clear();
|
infoBar->clear();
|
||||||
nbLines = 1;
|
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>"));
|
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>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,6 +246,8 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
|
|||||||
QModelIndex index;
|
QModelIndex index;
|
||||||
// Enable/disable pause/start action given the DL state
|
// Enable/disable pause/start action given the DL state
|
||||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
|
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
|
||||||
|
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;
|
bool has_pause = false, has_start = false, has_preview = false;
|
||||||
foreach(index, selectedIndexes) {
|
foreach(index, selectedIndexes) {
|
||||||
if(index.column() == NAME) {
|
if(index.column() == NAME) {
|
||||||
@@ -291,7 +267,7 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
|
|||||||
has_pause = true;
|
has_pause = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||||
myDLLlistMenu.addAction(actionPreview_file);
|
myDLLlistMenu.addAction(actionPreview_file);
|
||||||
has_preview = true;
|
has_preview = true;
|
||||||
}
|
}
|
||||||
@@ -305,174 +281,16 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
|
|||||||
myDLLlistMenu.addAction(actionSet_download_limit);
|
myDLLlistMenu.addAction(actionSet_download_limit);
|
||||||
myDLLlistMenu.addAction(actionSet_upload_limit);
|
myDLLlistMenu.addAction(actionSet_upload_limit);
|
||||||
myDLLlistMenu.addSeparator();
|
myDLLlistMenu.addSeparator();
|
||||||
myDLLlistMenu.addAction(actionOpen_destination_folder);
|
|
||||||
myDLLlistMenu.addAction(actionTorrent_Properties);
|
myDLLlistMenu.addAction(actionTorrent_Properties);
|
||||||
myDLLlistMenu.addSeparator();
|
|
||||||
myDLLlistMenu.addAction(actionBuy_it);
|
|
||||||
// Call menu
|
// Call menu
|
||||||
// XXX: why mapToGlobal() is not enough?
|
// XXX: why mapToGlobal() is not enough?
|
||||||
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,60));
|
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"));
|
|
||||||
for(int i=0; i<=ETA; i++) {
|
|
||||||
hideshowColumn.addAction(getActionHoSCol(i));
|
|
||||||
}
|
|
||||||
// Call menu
|
|
||||||
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,55));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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::on_actionClearLog_triggered() {
|
void DownloadingTorrents::on_actionClearLog_triggered() {
|
||||||
infoBar->clear();
|
infoBar->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
|
||||||
default :
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
|
QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
|
||||||
QStringList res;
|
QStringList res;
|
||||||
QModelIndex index;
|
QModelIndex index;
|
||||||
@@ -488,6 +306,32 @@ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
|
|||||||
return res;
|
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) {
|
void DownloadingTorrents::displayInfoBarMenu(const QPoint& pos) {
|
||||||
// Log Menu
|
// Log Menu
|
||||||
QMenu myLogMenu(this);
|
QMenu myLogMenu(this);
|
||||||
@@ -506,6 +350,9 @@ void DownloadingTorrents::sortProgressColumnDelayed() {
|
|||||||
// get information from torrent handles and
|
// get information from torrent handles and
|
||||||
// update download list accordingly
|
// update download list accordingly
|
||||||
void DownloadingTorrents::updateDlList() {
|
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
|
// browse handles
|
||||||
QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents();
|
QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents();
|
||||||
QString hash;
|
QString hash;
|
||||||
@@ -527,9 +374,7 @@ void DownloadingTorrents::updateDlList() {
|
|||||||
// No need to update a paused torrent
|
// No need to update a paused torrent
|
||||||
if(h.is_paused()) continue;
|
if(h.is_paused()) continue;
|
||||||
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
|
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
|
||||||
if(!downloadList->isColumnHidden(PROGRESS)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Parse download state
|
// Parse download state
|
||||||
@@ -546,71 +391,43 @@ void DownloadingTorrents::updateDlList() {
|
|||||||
case torrent_status::queued_for_checking:
|
case torrent_status::queued_for_checking:
|
||||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
|
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
|
||||||
setRowColor(row, QString::fromUtf8("grey"));
|
setRowColor(row, QString::fromUtf8("grey"));
|
||||||
if(!downloadList->isColumnHidden(PROGRESS)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case torrent_status::connecting_to_tracker:
|
case torrent_status::connecting_to_tracker:
|
||||||
if(h.download_payload_rate() > 0) {
|
if(h.download_payload_rate() > 0) {
|
||||||
// Display "Downloading" status when connecting if download speed > 0
|
// Display "Downloading" status when connecting if download speed > 0
|
||||||
if(!downloadList->isColumnHidden(ETA)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
|
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
|
||||||
}
|
|
||||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
|
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
|
||||||
setRowColor(row, QString::fromUtf8("green"));
|
setRowColor(row, QString::fromUtf8("green"));
|
||||||
}else{
|
}else{
|
||||||
if(!downloadList->isColumnHidden(ETA)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
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);
|
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
|
||||||
setRowColor(row, QString::fromUtf8("grey"));
|
setRowColor(row, QString::fromUtf8("grey"));
|
||||||
}
|
}
|
||||||
if(!downloadList->isColumnHidden(PROGRESS)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||||
}
|
|
||||||
if(!downloadList->isColumnHidden(DLSPEED)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
|
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, UPSPEED), QVariant((double)h.upload_payload_rate()));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case torrent_status::downloading:
|
case torrent_status::downloading:
|
||||||
case torrent_status::downloading_metadata:
|
case torrent_status::downloading_metadata:
|
||||||
if(h.download_payload_rate() > 0) {
|
if(h.download_payload_rate() > 0) {
|
||||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
|
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"));
|
setRowColor(row, QString::fromUtf8("green"));
|
||||||
}else{
|
}else{
|
||||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole);
|
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole);
|
||||||
if(!downloadList->isColumnHidden(ETA)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||||
|
setRowColor(row, QPalette::WindowText);
|
||||||
}
|
}
|
||||||
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
|
|
||||||
}
|
|
||||||
if(!downloadList->isColumnHidden(PROGRESS)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
|
||||||
}
|
|
||||||
if(!downloadList->isColumnHidden(DLSPEED)) {
|
|
||||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
|
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, UPSPEED), QVariant((double)h.upload_payload_rate()));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
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)));
|
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))));
|
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
|
||||||
}
|
|
||||||
}catch(invalid_handle e) {
|
}catch(invalid_handle e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -746,26 +563,11 @@ void DownloadingTorrents::saveColWidthDLList() const{
|
|||||||
qDebug("Saving columns width in download list");
|
qDebug("Saving columns width in download list");
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
QStringList width_list;
|
QStringList width_list;
|
||||||
QStringList new_width_list;
|
unsigned int nbColumns = DLListModel->columnCount()-1;
|
||||||
short nbColumns = DLListModel->columnCount()-1;
|
for(unsigned int i=0; i<nbColumns; ++i) {
|
||||||
QString line = settings.value("DownloadListColsWidth", QString()).toString();
|
width_list << misc::toQString(downloadList->columnWidth(i));
|
||||||
if(!line.isEmpty()) {
|
|
||||||
width_list = line.split(' ');
|
|
||||||
}
|
}
|
||||||
for(short i=0; i<nbColumns; ++i){
|
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), width_list.join(QString::fromUtf8(" ")));
|
||||||
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(" ")));
|
|
||||||
qDebug("Download list columns width saved");
|
qDebug("Download list columns width saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,10 +41,6 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
|||||||
bool delayedSorting;
|
bool delayedSorting;
|
||||||
unsigned int nbTorrents;
|
unsigned int nbTorrents;
|
||||||
Qt::SortOrder delayedSortingOrder;
|
Qt::SortOrder delayedSortingOrder;
|
||||||
void hideOrShowColumn(int index);
|
|
||||||
bool loadHiddenColumns();
|
|
||||||
void saveHiddenColumns();
|
|
||||||
QAction* getActionHoSCol(int index);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DownloadingTorrents(QObject *parent, bittorrent *BTSession);
|
DownloadingTorrents(QObject *parent, bittorrent *BTSession);
|
||||||
@@ -58,7 +54,7 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void unfinishedTorrentsNumberChanged(unsigned int);
|
void unfinishedTorrentsNumberChanged(unsigned int);
|
||||||
void torrentDoubleClicked(QString hash, bool finished);
|
void torrentDoubleClicked(QString hash);
|
||||||
void torrentFinished(QString hash);
|
void torrentFinished(QString hash);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
@@ -69,7 +65,6 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
|||||||
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
||||||
void on_actionSet_upload_limit_triggered();
|
void on_actionSet_upload_limit_triggered();
|
||||||
void displayDLListMenu(const QPoint& pos);
|
void displayDLListMenu(const QPoint& pos);
|
||||||
void displayDLHoSMenu(const QPoint&);
|
|
||||||
void on_actionClearLog_triggered();
|
void on_actionClearLog_triggered();
|
||||||
void displayInfoBarMenu(const QPoint& pos);
|
void displayInfoBarMenu(const QPoint& pos);
|
||||||
void addTorrent(QString hash);
|
void addTorrent(QString hash);
|
||||||
@@ -84,28 +79,18 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
|
|||||||
void setRowColor(int row, QColor color);
|
void setRowColor(int row, QColor color);
|
||||||
void displayDownloadingUrlInfos(QString url);
|
void displayDownloadingUrlInfos(QString url);
|
||||||
void showProperties(const QModelIndex &index);
|
void showProperties(const QModelIndex &index);
|
||||||
void hideOrShowColumnName();
|
|
||||||
void hideOrShowColumnSize();
|
|
||||||
void hideOrShowColumnProgress();
|
|
||||||
void hideOrShowColumnDownSpeed();
|
|
||||||
void hideOrShowColumnUpSpeed();
|
|
||||||
void hideOrShowColumnSeedersLeechers();
|
|
||||||
void hideOrShowColumnRatio();
|
|
||||||
void hideOrShowColumnEta();
|
|
||||||
void displayUPnPError(QString msg);
|
|
||||||
void displayUPnPSuccess(QString msg);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateDlList();
|
void updateDlList();
|
||||||
void setInfoBar(QString info, QColor color=QApplication::palette().color(QPalette::WindowText));
|
void setInfoBar(QString info, QColor color=QPalette::WindowText);
|
||||||
void pauseTorrent(QString hash);
|
void pauseTorrent(QString hash);
|
||||||
void resumeTorrent(QString hash);
|
void resumeTorrent(QString hash);
|
||||||
|
void updateRatio();
|
||||||
void deleteTorrent(QString hash);
|
void deleteTorrent(QString hash);
|
||||||
void setBottomTabEnabled(unsigned int index, bool b);
|
void setBottomTabEnabled(unsigned int index, bool b);
|
||||||
void propertiesSelection();
|
void propertiesSelection();
|
||||||
void sortProgressColumnDelayed();
|
void sortProgressColumnDelayed();
|
||||||
void updateFileSizeAndProgress(QString hash);
|
void updateFileSizeAndProgress(QString hash);
|
||||||
void showPropertiesFromHash(QString hash);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -250,13 +250,11 @@ void engineSelectDlg::setRowColor(int row, QString color){
|
|||||||
bool engineSelectDlg::checkInstalled(QString plugin_name) const {
|
bool engineSelectDlg::checkInstalled(QString plugin_name) const {
|
||||||
QProcess nova;
|
QProcess nova;
|
||||||
QStringList params;
|
QStringList params;
|
||||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
|
||||||
params << "--supported_engines";
|
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.waitForStarted();
|
||||||
nova.waitForFinished();
|
nova.waitForFinished();
|
||||||
QByteArray result = nova.readAll();
|
QByteArray result = nova.readAll();
|
||||||
result = result.replace("\r", "");
|
|
||||||
result = result.replace("\n", "");
|
result = result.replace("\n", "");
|
||||||
QList<QByteArray> plugins_list = result.split(',');
|
QList<QByteArray> plugins_list = result.split(',');
|
||||||
return plugins_list.contains(plugin_name.toUtf8());
|
return plugins_list.contains(plugin_name.toUtf8());
|
||||||
@@ -282,13 +280,11 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
|
|||||||
QStringList params;
|
QStringList params;
|
||||||
// Ask nova core for the supported search engines
|
// Ask nova core for the supported search engines
|
||||||
QProcess nova;
|
QProcess nova;
|
||||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
|
||||||
params << "--supported_engines";
|
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.waitForStarted();
|
||||||
nova.waitForFinished();
|
nova.waitForFinished();
|
||||||
QByteArray result = nova.readAll();
|
QByteArray result = nova.readAll();
|
||||||
result = result.replace("\r", "");
|
|
||||||
result = result.replace("\n", "");
|
result = result.replace("\n", "");
|
||||||
qDebug("read: %s", result.data());
|
qDebug("read: %s", result.data());
|
||||||
QByteArray e;
|
QByteArray e;
|
||||||
@@ -299,13 +295,11 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
|
|||||||
installed_engines[en] = old_engines.value(en, true);
|
installed_engines[en] = old_engines.value(en, true);
|
||||||
}
|
}
|
||||||
params.clear();
|
params.clear();
|
||||||
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
|
|
||||||
params << "--supported_engines_infos";
|
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.waitForStarted();
|
||||||
nova.waitForFinished();
|
nova.waitForFinished();
|
||||||
result = nova.readAll();
|
result = nova.readAll();
|
||||||
result = result.replace("\r", "");
|
|
||||||
result = result.replace("\n", "");
|
result = result.replace("\n", "");
|
||||||
qDebug("read: %s", result.data());
|
qDebug("read: %s", result.data());
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|||||||
@@ -1,186 +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 "eventmanager.h"
|
|
||||||
#include "json.h"
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
EventManager::EventManager(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
revision = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::update(QVariantMap event)
|
|
||||||
{
|
|
||||||
revision++;
|
|
||||||
events << QPair<ulong, QVariantMap>(revision, event);
|
|
||||||
emit updated();
|
|
||||||
qDebug("Added the following event");
|
|
||||||
qDebug() << event;
|
|
||||||
/* QLinkedList<QPair<ulong, QVariantMap> >::iterator i;
|
|
||||||
for (i = events.begin(); i != events.end(); i++)
|
|
||||||
qDebug() << *i;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant EventManager::querySince(ulong r) const
|
|
||||||
{
|
|
||||||
QVariantList list;
|
|
||||||
QLinkedListIterator<QPair<ulong, QVariantMap> > i(events);
|
|
||||||
i.toBack();
|
|
||||||
while (i.hasPrevious())
|
|
||||||
{
|
|
||||||
QPair<ulong, QVariantMap> pair = i.previous();
|
|
||||||
if (pair.first <= r)
|
|
||||||
break;
|
|
||||||
list.prepend(QVariant(pair.second));
|
|
||||||
}
|
|
||||||
QVariantMap map;
|
|
||||||
map["events"] = QVariant(list);
|
|
||||||
map["revision"] = QVariant((qulonglong) revision);
|
|
||||||
return QVariant(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EventManager::isUpdated(ulong r) const
|
|
||||||
{
|
|
||||||
return (r < revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::addedTorrent(QString, QTorrentHandle& h)
|
|
||||||
{
|
|
||||||
QVariantMap event;
|
|
||||||
event["type"] = QVariant("add");
|
|
||||||
event["hash"] = QVariant(h.hash());
|
|
||||||
event["name"] = QVariant(h.name());
|
|
||||||
update(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::deletedTorrent(QString hash)
|
|
||||||
{
|
|
||||||
QVariantMap event;
|
|
||||||
event["type"] = QVariant("delete");
|
|
||||||
event["hash"] = QVariant(hash);
|
|
||||||
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
|
|
||||||
bool loop = true;
|
|
||||||
while (loop && i != events.begin()) {
|
|
||||||
--i;
|
|
||||||
QVariantMap oldevent = i->second;
|
|
||||||
if(oldevent["hash"] == QVariant(hash))
|
|
||||||
{
|
|
||||||
if(oldevent["type"] == QVariant("add"))
|
|
||||||
loop = false;
|
|
||||||
i = events.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::modifiedTorrent(QTorrentHandle h)
|
|
||||||
{
|
|
||||||
QString hash = h.hash();
|
|
||||||
QVariantMap event;
|
|
||||||
QVariant v;
|
|
||||||
|
|
||||||
if(h.is_paused())
|
|
||||||
v = QVariant("paused");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(h.state())
|
|
||||||
{
|
|
||||||
case torrent_status::finished:
|
|
||||||
case torrent_status::seeding:
|
|
||||||
v = QVariant("seeding");
|
|
||||||
break;
|
|
||||||
case torrent_status::checking_files:
|
|
||||||
case torrent_status::queued_for_checking:
|
|
||||||
v = QVariant("checking");
|
|
||||||
break;
|
|
||||||
case torrent_status::connecting_to_tracker:
|
|
||||||
if(h.download_payload_rate() > 0)
|
|
||||||
v = QVariant("downloading");
|
|
||||||
else
|
|
||||||
v = QVariant("connecting");
|
|
||||||
break;
|
|
||||||
case torrent_status::downloading:
|
|
||||||
case torrent_status::downloading_metadata:
|
|
||||||
if(h.download_payload_rate() > 0)
|
|
||||||
v = QVariant("downloading");
|
|
||||||
else
|
|
||||||
v = QVariant("stalled");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
v = QVariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(modify(hash, "state", v))
|
|
||||||
event["state"] = v;
|
|
||||||
|
|
||||||
v = QVariant((qlonglong)h.actual_size());
|
|
||||||
if(modify(hash, "size", v))
|
|
||||||
event["size"] = v;
|
|
||||||
|
|
||||||
v = QVariant(h.progress());
|
|
||||||
if(modify(hash, "progress", v))
|
|
||||||
event["progress"] = v;
|
|
||||||
|
|
||||||
v = QVariant(h.download_payload_rate());
|
|
||||||
if(modify(hash, "dlspeed", v))
|
|
||||||
event["dlspeed"] = v;
|
|
||||||
|
|
||||||
v = QVariant(h.upload_payload_rate());
|
|
||||||
if(modify(hash, "upspeed", v))
|
|
||||||
event["upspeed"] = v;
|
|
||||||
|
|
||||||
if(event.size() > 0)
|
|
||||||
{
|
|
||||||
event["type"] = QVariant("modify");
|
|
||||||
event["hash"] = QVariant(hash);
|
|
||||||
update(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EventManager::modify(QString hash, QString key, QVariant value)
|
|
||||||
{
|
|
||||||
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
|
|
||||||
while (i != events.begin()) {
|
|
||||||
--i;
|
|
||||||
QVariantMap event = i->second;
|
|
||||||
if(event["hash"] == QVariant(hash))
|
|
||||||
{
|
|
||||||
if(event["type"] == QVariant("add"))
|
|
||||||
return true;
|
|
||||||
if(event.contains(key))
|
|
||||||
{
|
|
||||||
if(event[key] == value)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(event.size() <= 3)
|
|
||||||
i = events.erase(i);
|
|
||||||
else
|
|
||||||
i->second.remove(key);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,55 +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 EVENTMANAGER_H
|
|
||||||
#define EVENTMANAGER_H
|
|
||||||
|
|
||||||
#include "qtorrenthandle.h"
|
|
||||||
#include <QLinkedList>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QVariant>
|
|
||||||
|
|
||||||
class EventManager : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private:
|
|
||||||
ulong revision;
|
|
||||||
QLinkedList<QPair <ulong, QVariantMap> > events;
|
|
||||||
bool modify(QString hash, QString key, QVariant value);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void update(QVariantMap event);
|
|
||||||
|
|
||||||
public:
|
|
||||||
EventManager(QObject *parent = 0);
|
|
||||||
QVariant querySince(ulong r) const;
|
|
||||||
bool isUpdated(ulong r) const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void updated();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void addedTorrent(QString path, QTorrentHandle& h);
|
|
||||||
void deletedTorrent(QString hash);
|
|
||||||
void modifiedTorrent(QTorrentHandle h);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,383 +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>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
// 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;
|
|
||||||
do {
|
|
||||||
int 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,204 +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>
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpConnection::read()
|
|
||||||
{
|
|
||||||
QString input = socket->readAll();
|
|
||||||
qDebug(" -------");
|
|
||||||
qDebug("|REQUEST|");
|
|
||||||
qDebug(" -------");
|
|
||||||
qDebug("%s", input.toAscii().constData());
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
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")
|
|
||||||
{
|
|
||||||
EventManager* manager = parent->eventManager();
|
|
||||||
uint r = parser.get("r").toUInt();
|
|
||||||
if(manager->isUpdated(r))
|
|
||||||
respondJson();
|
|
||||||
else
|
|
||||||
connect(manager, SIGNAL(updated()), this, SLOT(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 temp = parser.get("r");
|
|
||||||
uint r = parser.get("r").toUInt();
|
|
||||||
QVariant data = manager->querySince(r);
|
|
||||||
QString string = toJson(data);
|
|
||||||
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');
|
|
||||||
QStringList url_list_cleaned;
|
|
||||||
foreach(QString url, list){
|
|
||||||
url = url.trimmed();
|
|
||||||
if(!url.isEmpty()){
|
|
||||||
if(url_list_cleaned.indexOf(QRegExp(url, Qt::CaseInsensitive, QRegExp::FixedString)) < 0){
|
|
||||||
url_list_cleaned << url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit urlsReadyToBeDownloaded(url_list_cleaned);
|
|
||||||
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"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +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();
|
|
||||||
|
|
||||||
public:
|
|
||||||
HttpConnection(QTcpSocket *socket, HttpServer *parent);
|
|
||||||
~HttpConnection();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void read();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void urlsReadyToBeDownloaded(const QStringList&);
|
|
||||||
void deleteTorrent(QString hash);
|
|
||||||
void resumeTorrent(QString hash);
|
|
||||||
void pauseTorrent(QString hash);
|
|
||||||
void resumeAllTorrents();
|
|
||||||
void pauseAllTorrents();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,128 +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;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString HttpRequestParser::message() const
|
|
||||||
{
|
|
||||||
if(isParsable())
|
|
||||||
return data;
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString HttpRequestParser::get(const QString key) const
|
|
||||||
{
|
|
||||||
return getMap[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
QString HttpRequestParser::post(const QString key) const
|
|
||||||
{
|
|
||||||
return postMap[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpRequestParser::write(QString 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();
|
|
||||||
qDebug() << 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.toAscii());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +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;
|
|
||||||
QString data;
|
|
||||||
QString path;
|
|
||||||
QMap<QString, QString> postMap;
|
|
||||||
QMap<QString, QString> getMap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HttpRequestParser();
|
|
||||||
~HttpRequestParser();
|
|
||||||
bool isParsable() const;
|
|
||||||
bool isError() const;
|
|
||||||
QString url() const;
|
|
||||||
QString message() const;
|
|
||||||
QString get(const QString key) const;
|
|
||||||
QString post(const QString key) const;
|
|
||||||
void write(QString str);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,73 +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"
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +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 HTTPRESPONSEGENERATOR_H
|
|
||||||
#define HTTPRESPONSEGENERATOR_H
|
|
||||||
|
|
||||||
#include<QHttpResponseHeader>
|
|
||||||
|
|
||||||
class HttpResponseGenerator : public QHttpResponseHeader
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
QByteArray message;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void setMessage(const QByteArray message);
|
|
||||||
void setMessage(const QString message);
|
|
||||||
void stripMessage();
|
|
||||||
void setContentTypeByExt(const QString ext);
|
|
||||||
virtual QByteArray toByteArray() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,98 +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 "httpserver.h"
|
|
||||||
#include "httpconnection.h"
|
|
||||||
#include "eventmanager.h"
|
|
||||||
#include "bittorrent.h"
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
HttpServer::HttpServer(bittorrent *BTSession, int msec, QObject* parent) : QTcpServer(parent)
|
|
||||||
{
|
|
||||||
base64 = QByteArray(":").toBase64();
|
|
||||||
connect(this, SIGNAL(newConnection()), this, SLOT(newHttpConnection()));
|
|
||||||
HttpServer::BTSession = BTSession;
|
|
||||||
manager = new EventManager(this);
|
|
||||||
//add torrents
|
|
||||||
QStringList list = BTSession->getUnfinishedTorrents() + BTSession->getFinishedTorrents();
|
|
||||||
QString hash;
|
|
||||||
foreach(hash, list)
|
|
||||||
{
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
|
||||||
if(h.is_valid())
|
|
||||||
manager->addedTorrent(QString(), h);
|
|
||||||
}
|
|
||||||
//connect BTSession to manager
|
|
||||||
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), manager, SLOT(addedTorrent(QString, QTorrentHandle&)));
|
|
||||||
connect(BTSession, SIGNAL(deletedTorrent(QString)), manager, SLOT(deletedTorrent(QString)));
|
|
||||||
//set timer
|
|
||||||
QTimer *timer = new QTimer(this);
|
|
||||||
connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
|
|
||||||
timer->start(msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpServer::~HttpServer()
|
|
||||||
{
|
|
||||||
delete manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpServer::newHttpConnection()
|
|
||||||
{
|
|
||||||
QTcpSocket *socket;
|
|
||||||
while((socket = nextPendingConnection()))
|
|
||||||
{
|
|
||||||
HttpConnection *connection = new HttpConnection(socket, this);
|
|
||||||
//connect connection to BTSession
|
|
||||||
connect(connection, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&)));
|
|
||||||
connect(connection, SIGNAL(deleteTorrent(QString)), BTSession, SLOT(deleteTorrent(QString)));
|
|
||||||
connect(connection, SIGNAL(pauseTorrent(QString)), BTSession, SLOT(pauseTorrent(QString)));
|
|
||||||
connect(connection, SIGNAL(resumeTorrent(QString)), BTSession, SLOT(resumeTorrent(QString)));
|
|
||||||
connect(connection, SIGNAL(pauseAllTorrents()), BTSession, SLOT(pauseAllTorrents()));
|
|
||||||
connect(connection, SIGNAL(resumeAllTorrents()), BTSession, SLOT(resumeAllTorrents()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpServer::onTimer()
|
|
||||||
{
|
|
||||||
QStringList list = BTSession->getUnfinishedTorrents() + BTSession->getFinishedTorrents();
|
|
||||||
foreach(QString hash, list)
|
|
||||||
{
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
|
||||||
if(h.is_valid())
|
|
||||||
manager->modifiedTorrent(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpServer::setAuthorization(QString username, QString password)
|
|
||||||
{
|
|
||||||
QString cat = username + ":" + password;
|
|
||||||
base64 = QByteArray(cat.toUtf8()).toBase64();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HttpServer::isAuthorized(QByteArray auth) const
|
|
||||||
{
|
|
||||||
return (auth == base64);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventManager *HttpServer::eventManager() const
|
|
||||||
{
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
@@ -1,53 +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 HTTPSERVER_H
|
|
||||||
#define HTTPSERVER_H
|
|
||||||
|
|
||||||
#include <QTcpServer>
|
|
||||||
#include <QByteArray>
|
|
||||||
|
|
||||||
class bittorrent;
|
|
||||||
|
|
||||||
class EventManager;
|
|
||||||
|
|
||||||
class HttpServer : public QTcpServer
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray base64;
|
|
||||||
bittorrent *BTSession;
|
|
||||||
EventManager *manager;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HttpServer(bittorrent *BTSession, int msec, QObject* parent = 0);
|
|
||||||
~HttpServer();
|
|
||||||
void setAuthorization(QString username, QString password);
|
|
||||||
bool isAuthorized(QByteArray auth) const;
|
|
||||||
EventManager *eventManager() const;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void newHttpConnection();
|
|
||||||
void onTimer();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
183
src/icons.qrc
183
src/icons.qrc
@@ -1,106 +1,103 @@
|
|||||||
<!DOCTYPE RCC><RCC version="1.0">
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
<qresource>
|
<qresource>
|
||||||
<file>Icons/folder.png</file>
|
|
||||||
<file>Icons/qbittorrent32.png</file>
|
|
||||||
<file>Icons/file.png</file>
|
|
||||||
<file>Icons/smile.png</file>
|
|
||||||
<file>Icons/qbittorrent22.png</file>
|
|
||||||
<file>Icons/mascot.png</file>
|
|
||||||
<file>Icons/downarrow.png</file>
|
|
||||||
<file>Icons/unavailable.png</file>
|
|
||||||
<file>Icons/proxy.png</file>
|
|
||||||
<file>Icons/description.png</file>
|
|
||||||
<file>Icons/log.png</file>
|
|
||||||
<file>Icons/uparrow.png</file>
|
|
||||||
<file>Icons/home.png</file>
|
|
||||||
<file>Icons/unsubscribe.png</file>
|
|
||||||
<file>Icons/url.png</file>
|
|
||||||
<file>Icons/unsubscribe16.png</file>
|
|
||||||
<file>Icons/stare.png</file>
|
|
||||||
<file>Icons/qbittorrent16.png</file>
|
|
||||||
<file>Icons/locale.png</file>
|
|
||||||
<file>Icons/splash.png</file>
|
|
||||||
<file>Icons/subscribe16.png</file>
|
|
||||||
<file>Icons/loading.png</file>
|
|
||||||
<file>Icons/star.png</file>
|
|
||||||
<file>Icons/gnome-shutdown.png</file>
|
|
||||||
<file>Icons/style.png</file>
|
|
||||||
<file>Icons/rss16.png</file>
|
|
||||||
<file>Icons/configure.png</file>
|
|
||||||
<file>Icons/connection.png</file>
|
|
||||||
<file>Icons/systemtray.png</file>
|
|
||||||
<file>Icons/sphere.png</file>
|
|
||||||
<file>Icons/add_folder.png</file>
|
|
||||||
<file>Icons/button_cancel.png</file>
|
|
||||||
<file>Icons/encrypted.png</file>
|
|
||||||
<file>Icons/wizard.png</file>
|
|
||||||
<file>Icons/edit_clear.png</file>
|
|
||||||
<file>Icons/rss32.png</file>
|
|
||||||
<file>Icons/subscribe.png</file>
|
|
||||||
<file>Icons/bt_settings.png</file>
|
|
||||||
<file>Icons/password.png</file>
|
|
||||||
<file>Icons/newmsg.png</file>
|
|
||||||
<file>Icons/sphere2.png</file>
|
|
||||||
<file>Icons/button_ok.png</file>
|
|
||||||
<file>Icons/unhappy.png</file>
|
|
||||||
<file>Icons/add_file.png</file>
|
|
||||||
<file>Icons/filter.png</file>
|
|
||||||
<file>Icons/money.png</file>
|
|
||||||
<file>Icons/download.png</file>
|
|
||||||
<file>Icons/time.png</file>
|
<file>Icons/time.png</file>
|
||||||
|
<file>Icons/connection.png</file>
|
||||||
|
<file>Icons/locale.png</file>
|
||||||
|
<file>Icons/newmsg.png</file>
|
||||||
|
<file>Icons/url.png</file>
|
||||||
|
<file>Icons/button_ok.png</file>
|
||||||
|
<file>Icons/stare.png</file>
|
||||||
|
<file>Icons/log.png</file>
|
||||||
|
<file>Icons/qbittorrent32.png</file>
|
||||||
|
<file>Icons/downarrow.png</file>
|
||||||
|
<file>Icons/description.png</file>
|
||||||
|
<file>Icons/qbittorrent16.png</file>
|
||||||
|
<file>Icons/file.png</file>
|
||||||
|
<file>Icons/systemtray.png</file>
|
||||||
|
<file>Icons/unhappy.png</file>
|
||||||
|
<file>Icons/filter.png</file>
|
||||||
|
<file>Icons/sphere.png</file>
|
||||||
|
<file>Icons/mascot.png</file>
|
||||||
|
<file>Icons/encrypted.png</file>
|
||||||
<file>Icons/refresh.png</file>
|
<file>Icons/refresh.png</file>
|
||||||
|
<file>Icons/uparrow.png</file>
|
||||||
|
<file>Icons/style.png</file>
|
||||||
|
<file>Icons/wizard.png</file>
|
||||||
|
<file>Icons/password.png</file>
|
||||||
<file>Icons/gear.png</file>
|
<file>Icons/gear.png</file>
|
||||||
<file>Icons/skin/new.png</file>
|
<file>Icons/sphere2.png</file>
|
||||||
<file>Icons/skin/qb_question.png</file>
|
<file>Icons/smile.png</file>
|
||||||
<file>Icons/skin/play.png</file>
|
<file>Icons/loading.png</file>
|
||||||
<file>Icons/skin/connecting.png</file>
|
<file>Icons/button_cancel.png</file>
|
||||||
<file>Icons/skin/settings.png</file>
|
<file>Icons/qbittorrent22.png</file>
|
||||||
<file>Icons/skin/add.png</file>
|
<file>Icons/proxy.png</file>
|
||||||
<file>Icons/skin/open.png</file>
|
<file>Icons/add_folder.png</file>
|
||||||
<file>Icons/skin/play_all.png</file>
|
<file>Icons/unavailable.png</file>
|
||||||
<file>Icons/skin/info.png</file>
|
<file>Icons/add_file.png</file>
|
||||||
<file>Icons/skin/connected.png</file>
|
<file>Icons/home.png</file>
|
||||||
<file>Icons/skin/search.png</file>
|
<file>Icons/splash.png</file>
|
||||||
<file>Icons/skin/url.png</file>
|
<file>Icons/rss32.png</file>
|
||||||
<file>Icons/skin/firewalled.png</file>
|
<file>Icons/rss16.png</file>
|
||||||
<file>Icons/skin/properties.png</file>
|
<file>Icons/unsubscribe.png</file>
|
||||||
<file>Icons/skin/preview.png</file>
|
<file>Icons/subscribe.png</file>
|
||||||
<file>Icons/skin/remove.png</file>
|
<file>Icons/unsubscribe16.png</file>
|
||||||
<file>Icons/skin/delete_perm.png</file>
|
<file>Icons/subscribe16.png</file>
|
||||||
<file>Icons/skin/pause_all.png</file>
|
<file>Icons/bt_settings.png</file>
|
||||||
<file>Icons/skin/delete_all.png</file>
|
<file>Icons/star.png</file>
|
||||||
<file>Icons/skin/stalled.png</file>
|
<file>Icons/configure.png</file>
|
||||||
<file>Icons/skin/downloading.png</file>
|
<file>Icons/download.png</file>
|
||||||
<file>Icons/skin/delete.png</file>
|
<file>Icons/folder.png</file>
|
||||||
<file>Icons/skin/exit.png</file>
|
|
||||||
<file>Icons/skin/seeding.png</file>
|
|
||||||
<file>Icons/skin/paused.png</file>
|
|
||||||
<file>Icons/skin/disconnected.png</file>
|
|
||||||
<file>Icons/skin/pause.png</file>
|
|
||||||
<file>Icons/flags/turkey.png</file>
|
|
||||||
<file>Icons/flags/portugal.png</file>
|
<file>Icons/flags/portugal.png</file>
|
||||||
<file>Icons/flags/finland.png</file>
|
<file>Icons/flags/france.png</file>
|
||||||
<file>Icons/flags/ukraine.png</file>
|
<file>Icons/flags/ukraine.png</file>
|
||||||
<file>Icons/flags/bulgaria.png</file>
|
|
||||||
<file>Icons/flags/spain_catalunya.png</file>
|
|
||||||
<file>Icons/flags/brazil.png</file>
|
|
||||||
<file>Icons/flags/norway.png</file>
|
|
||||||
<file>Icons/flags/slovakia.png</file>
|
|
||||||
<file>Icons/flags/romania.png</file>
|
|
||||||
<file>Icons/flags/united_kingdom.png</file>
|
<file>Icons/flags/united_kingdom.png</file>
|
||||||
<file>Icons/flags/netherlands.png</file>
|
|
||||||
<file>Icons/flags/china.png</file>
|
|
||||||
<file>Icons/flags/denmark.png</file>
|
|
||||||
<file>Icons/flags/hungary.png</file>
|
|
||||||
<file>Icons/flags/greece.png</file>
|
|
||||||
<file>Icons/flags/spain.png</file>
|
|
||||||
<file>Icons/flags/italy.png</file>
|
|
||||||
<file>Icons/flags/germany.png</file>
|
<file>Icons/flags/germany.png</file>
|
||||||
<file>Icons/flags/russia.png</file>
|
<file>Icons/flags/russia.png</file>
|
||||||
<file>Icons/flags/japan.png</file>
|
<file>Icons/flags/netherlands.png</file>
|
||||||
<file>Icons/flags/south_korea.png</file>
|
<file>Icons/flags/slovakia.png</file>
|
||||||
<file>Icons/flags/france.png</file>
|
<file>Icons/flags/spain.png</file>
|
||||||
<file>Icons/flags/sweden.png</file>
|
<file>Icons/flags/finland.png</file>
|
||||||
|
<file>Icons/flags/spain_catalunya.png</file>
|
||||||
<file>Icons/flags/poland.png</file>
|
<file>Icons/flags/poland.png</file>
|
||||||
|
<file>Icons/flags/hungary.png</file>
|
||||||
|
<file>Icons/flags/norway.png</file>
|
||||||
|
<file>Icons/flags/denmark.png</file>
|
||||||
|
<file>Icons/flags/italy.png</file>
|
||||||
|
<file>Icons/flags/china.png</file>
|
||||||
|
<file>Icons/flags/brazil.png</file>
|
||||||
|
<file>Icons/flags/south_korea.png</file>
|
||||||
|
<file>Icons/flags/turkey.png</file>
|
||||||
|
<file>Icons/flags/sweden.png</file>
|
||||||
|
<file>Icons/flags/bulgaria.png</file>
|
||||||
|
<file>Icons/flags/romania.png</file>
|
||||||
|
<file>Icons/flags/japan.png</file>
|
||||||
|
<file>Icons/flags/greece.png</file>
|
||||||
|
<file>Icons/skin/properties.png</file>
|
||||||
|
<file>Icons/skin/play_all.png</file>
|
||||||
|
<file>Icons/skin/remove.png</file>
|
||||||
|
<file>Icons/skin/settings.png</file>
|
||||||
|
<file>Icons/skin/open.png</file>
|
||||||
|
<file>Icons/skin/disconnected.png</file>
|
||||||
|
<file>Icons/skin/delete.png</file>
|
||||||
|
<file>Icons/skin/connected.png</file>
|
||||||
|
<file>Icons/skin/url.png</file>
|
||||||
|
<file>Icons/skin/pause_all.png</file>
|
||||||
|
<file>Icons/skin/downloading.png</file>
|
||||||
|
<file>Icons/skin/play.png</file>
|
||||||
|
<file>Icons/skin/search.png</file>
|
||||||
|
<file>Icons/skin/exit.png</file>
|
||||||
|
<file>Icons/skin/pause.png</file>
|
||||||
|
<file>Icons/skin/firewalled.png</file>
|
||||||
|
<file>Icons/skin/seeding.png</file>
|
||||||
|
<file>Icons/skin/paused.png</file>
|
||||||
|
<file>Icons/skin/preview.png</file>
|
||||||
|
<file>Icons/skin/delete_perm.png</file>
|
||||||
|
<file>Icons/skin/connecting.png</file>
|
||||||
|
<file>Icons/skin/add.png</file>
|
||||||
|
<file>Icons/skin/stalled.png</file>
|
||||||
|
<file>Icons/skin/new.png</file>
|
||||||
|
<file>Icons/skin/qb_question.png</file>
|
||||||
|
<file>Icons/skin/delete_all.png</file>
|
||||||
|
<file>Icons/skin/info.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
103
src/json.cpp
103
src/json.cpp
@@ -1,103 +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 "json.h"
|
|
||||||
|
|
||||||
QString toJson(QVariant v)
|
|
||||||
{
|
|
||||||
if (v.isNull())
|
|
||||||
return "null";
|
|
||||||
QString result;
|
|
||||||
switch(v.type())
|
|
||||||
{
|
|
||||||
case QVariant::Bool:
|
|
||||||
case QVariant::Double:
|
|
||||||
case QVariant::Int:
|
|
||||||
case QVariant::LongLong:
|
|
||||||
case QVariant::UInt:
|
|
||||||
case QVariant::ULongLong:
|
|
||||||
return v.value<QString>();
|
|
||||||
case QVariant::String:
|
|
||||||
{
|
|
||||||
QString s = v.value<QString>();
|
|
||||||
result = "\"";
|
|
||||||
for(int i=0; i<s.size(); i++)
|
|
||||||
{
|
|
||||||
QChar ch = s[i];
|
|
||||||
switch(ch.toAscii())
|
|
||||||
{
|
|
||||||
case '\b':
|
|
||||||
result += "\\b";
|
|
||||||
break;
|
|
||||||
case '\f':
|
|
||||||
result += "\\f";
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
result += "\\n";
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
result += "\\r";
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
result += "\\t";
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
case '\'':
|
|
||||||
case '\\':
|
|
||||||
case '&':
|
|
||||||
result += '\\';
|
|
||||||
case '\0':
|
|
||||||
default:
|
|
||||||
result += ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result += "\"";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
case QVariant::List:
|
|
||||||
{
|
|
||||||
result = "[";
|
|
||||||
QListIterator<QVariant> it(v.value<QVariantList>());
|
|
||||||
while (it.hasNext())
|
|
||||||
result += toJson(it.next()) + ",";
|
|
||||||
if(result.size() > 1)
|
|
||||||
result.chop(1);
|
|
||||||
result += "]";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
case QVariant::Map:
|
|
||||||
{
|
|
||||||
result = "{";
|
|
||||||
QMapIterator<QString, QVariant> it(v.value<QVariantMap>());
|
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
if(it.value().isValid())
|
|
||||||
result += toJson(QVariant(it.key())) + ":" + toJson(it.value()) + ",";
|
|
||||||
}
|
|
||||||
if(result.size() > 1)
|
|
||||||
result.chop(1);
|
|
||||||
result += "}";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return "undefined";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
29
src/json.h
29
src/json.h
@@ -1,29 +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 JSON_H
|
|
||||||
#define JSON_H
|
|
||||||
|
|
||||||
#include <QVariant>
|
|
||||||
|
|
||||||
QString toJson(QVariant v);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
40
src/lang.qrc
40
src/lang.qrc
@@ -1,29 +1,29 @@
|
|||||||
<!DOCTYPE RCC><RCC version="1.0">
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
<qresource>
|
<qresource>
|
||||||
<file>lang/qbittorrent_uk.qm</file>
|
<file>lang/qbittorrent_es.qm</file>
|
||||||
<file>lang/qbittorrent_tr.qm</file>
|
|
||||||
<file>lang/qbittorrent_nl.qm</file>
|
|
||||||
<file>lang/qbittorrent_de.qm</file>
|
|
||||||
<file>lang/qbittorrent_ru.qm</file>
|
|
||||||
<file>lang/qbittorrent_fr.qm</file>
|
|
||||||
<file>lang/qbittorrent_da.qm</file>
|
|
||||||
<file>lang/qbittorrent_fi.qm</file>
|
|
||||||
<file>lang/qbittorrent_pl.qm</file>
|
|
||||||
<file>lang/qbittorrent_ko.qm</file>
|
<file>lang/qbittorrent_ko.qm</file>
|
||||||
<file>lang/qbittorrent_nb.qm</file>
|
|
||||||
<file>lang/qbittorrent_sv.qm</file>
|
|
||||||
<file>lang/qbittorrent_zh.qm</file>
|
|
||||||
<file>lang/qbittorrent_el.qm</file>
|
|
||||||
<file>lang/qbittorrent_sk.qm</file>
|
|
||||||
<file>lang/qbittorrent_ca.qm</file>
|
|
||||||
<file>lang/qbittorrent_hu.qm</file>
|
<file>lang/qbittorrent_hu.qm</file>
|
||||||
<file>lang/qbittorrent_bg.qm</file>
|
<file>lang/qbittorrent_sk.qm</file>
|
||||||
<file>lang/qbittorrent_it.qm</file>
|
<file>lang/qbittorrent_uk.qm</file>
|
||||||
<file>lang/qbittorrent_pt.qm</file>
|
<file>lang/qbittorrent_ro.qm</file>
|
||||||
|
<file>lang/qbittorrent_ru.qm</file>
|
||||||
|
<file>lang/qbittorrent_nb.qm</file>
|
||||||
|
<file>lang/qbittorrent_el.qm</file>
|
||||||
<file>lang/qbittorrent_en.qm</file>
|
<file>lang/qbittorrent_en.qm</file>
|
||||||
<file>lang/qbittorrent_pt_BR.qm</file>
|
<file>lang/qbittorrent_pt_BR.qm</file>
|
||||||
|
<file>lang/qbittorrent_fr.qm</file>
|
||||||
|
<file>lang/qbittorrent_nl.qm</file>
|
||||||
|
<file>lang/qbittorrent_pl.qm</file>
|
||||||
|
<file>lang/qbittorrent_it.qm</file>
|
||||||
|
<file>lang/qbittorrent_zh.qm</file>
|
||||||
|
<file>lang/qbittorrent_ca.qm</file>
|
||||||
|
<file>lang/qbittorrent_pt.qm</file>
|
||||||
|
<file>lang/qbittorrent_da.qm</file>
|
||||||
|
<file>lang/qbittorrent_tr.qm</file>
|
||||||
|
<file>lang/qbittorrent_bg.qm</file>
|
||||||
|
<file>lang/qbittorrent_de.qm</file>
|
||||||
|
<file>lang/qbittorrent_sv.qm</file>
|
||||||
<file>lang/qbittorrent_ja.qm</file>
|
<file>lang/qbittorrent_ja.qm</file>
|
||||||
<file>lang/qbittorrent_ro.qm</file>
|
<file>lang/qbittorrent_fi.qm</file>
|
||||||
<file>lang/qbittorrent_es.qm</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user