You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-12 03:12:18 +02:00
Compare commits
44 Commits
v4_0_x
...
release-0.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ff277fe5bb | ||
![]() |
7140a532ed | ||
![]() |
db4f3ab08a | ||
![]() |
1deb7b88bc | ||
![]() |
0d40bb0d68 | ||
![]() |
b033893d39 | ||
![]() |
e9693d3829 | ||
![]() |
bc7d9d00ab | ||
![]() |
0c05c893a0 | ||
![]() |
8b3c4f8143 | ||
![]() |
90bc79d4e1 | ||
![]() |
676d6764b9 | ||
![]() |
cb08280180 | ||
![]() |
ecede8b53e | ||
![]() |
f6a54f6fcf | ||
![]() |
6039851f13 | ||
![]() |
f1decc5432 | ||
![]() |
12629a9e38 | ||
![]() |
14f13d0406 | ||
![]() |
e0213dc6c3 | ||
![]() |
2f065bd9ea | ||
![]() |
b87882dd59 | ||
![]() |
df06fcac03 | ||
![]() |
3de95cdb04 | ||
![]() |
062fd6d81c | ||
![]() |
82d9e19e96 | ||
![]() |
22eead5f9a | ||
![]() |
f5627e4345 | ||
![]() |
da867a767b | ||
![]() |
b751954566 | ||
![]() |
f774228529 | ||
![]() |
4d6aad8cab | ||
![]() |
188e3956d8 | ||
![]() |
88d7400644 | ||
![]() |
41254bcdf4 | ||
![]() |
067aa010b6 | ||
![]() |
f94197816c | ||
![]() |
78e976e97e | ||
![]() |
225d8bcc5b | ||
![]() |
9bd29ebdb0 | ||
![]() |
7565902fc1 | ||
![]() |
0b8a1f8c1f | ||
![]() |
8800614077 | ||
![]() |
156001f51d |
17
Changelog
17
Changelog
@@ -1,4 +1,15 @@
|
|||||||
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v0.9.0
|
* Tue Apr 10 2007 - Christophe Dumez <chris@qbittorrent.org> - v0.9.2
|
||||||
|
- BUGFIX: Window can now stay maximized on exit
|
||||||
|
- BUGFIX: Use PKGCONFIG again for configuring libtorrent
|
||||||
|
- BUGFIX: Allow to compile with libtorrent v0.11
|
||||||
|
- BUGFIX: Disabled main window context menu (annoying)
|
||||||
|
- I18N: Added Japanese translation
|
||||||
|
- I18N: Updated Turkish translation
|
||||||
|
|
||||||
|
* Wed Apr 04 2007 - Christophe Dumez <chris@qbittorrent.org> - v0.9.1
|
||||||
|
- BUGFIX: A lot of fixes in configure file
|
||||||
|
|
||||||
|
* Sun Apr 01 2007 - Christophe Dumez <chris@qbittorrent.org> - v0.9.0
|
||||||
- FEATURE: Based on libtorrent v0.12
|
- FEATURE: Based on libtorrent v0.12
|
||||||
- FEATURE: Based on Qt4.2
|
- FEATURE: Based on Qt4.2
|
||||||
- FEATURE: Brand new trayicon from Qt4.2
|
- FEATURE: Brand new trayicon from Qt4.2
|
||||||
@@ -12,6 +23,7 @@
|
|||||||
- FEATURE: Added Autocompletion to search engine
|
- FEATURE: Added Autocompletion to search engine
|
||||||
- FEATURE: Splitted BT & GUI parts (huge code rewriting & optimization)
|
- FEATURE: Splitted BT & GUI parts (huge code rewriting & optimization)
|
||||||
- FEATURE: New parameters for configure file to point to custom locations for libtorrent/libcurl
|
- FEATURE: New parameters for configure file to point to custom locations for libtorrent/libcurl
|
||||||
|
- FEATURE: Update application style according to the system (WindowsXP, MacOS, X11)
|
||||||
- BUGFIX: Two torrents can now have the same name although they are different (use their hash)
|
- BUGFIX: Two torrents can now have the same name although they are different (use their hash)
|
||||||
- BUGFIX: Fixed download from url that would fail sometimes
|
- BUGFIX: Fixed download from url that would fail sometimes
|
||||||
- BUGFIX: Save directory was reset to default when filtering files in torrent
|
- BUGFIX: Save directory was reset to default when filtering files in torrent
|
||||||
@@ -25,6 +37,9 @@
|
|||||||
- BUGFIX: Create Options object only when necessary (to save memory)
|
- BUGFIX: Create Options object only when necessary (to save memory)
|
||||||
- BUGFIX: Let libtorrent store the torrent handles (save memory)
|
- BUGFIX: Let libtorrent store the torrent handles (save memory)
|
||||||
- BUGFIX: Set DHT Port only when DHT is enabled
|
- BUGFIX: Set DHT Port only when DHT is enabled
|
||||||
|
- BUGFIX: Made ipfilter.dat parser less sensitive to errors
|
||||||
|
- BUGFIX: Bring main window to foreground when asking for exit confirmation
|
||||||
|
- I18N: Added Danish translation
|
||||||
- I18N: Better internationalization thanks to dynamic text support
|
- I18N: Better internationalization thanks to dynamic text support
|
||||||
- COSMETIC: Replaced OSD messages by Qt4.2 systray messages
|
- COSMETIC: Replaced OSD messages by Qt4.2 systray messages
|
||||||
|
|
||||||
|
2
INSTALL
2
INSTALL
@@ -16,7 +16,7 @@ will install and execute qBittorrent hopefully without any problems.
|
|||||||
Dependencies:
|
Dependencies:
|
||||||
- Qt >= 4.2 (libqt-devel, libqtgui, libqtcore, libqtnetwork)
|
- Qt >= 4.2 (libqt-devel, libqtgui, libqtcore, libqtnetwork)
|
||||||
|
|
||||||
- libtorrent by Arvid Norberg (>= v0.12 REQUIRED)
|
- libtorrent by Arvid Norberg (>= v0.11 REQUIRED, >= 0.12 ADVISED)
|
||||||
-> http://libtorrent.sf.net
|
-> http://libtorrent.sf.net
|
||||||
Be carefull: another library (the one used by rtorrent) use the same name.
|
Be carefull: 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
|
These are TWO different libraries and qBittorrent will only work with the one provided
|
||||||
|
5
TODO
5
TODO
@@ -37,6 +37,5 @@
|
|||||||
- UPnP support?
|
- UPnP support?
|
||||||
|
|
||||||
// In v0.9.0
|
// In v0.9.0
|
||||||
- Update translations (FR, SV, NB, PL, RU, DE done)
|
- Update translations (FR, SV, NB, PL, RU, DE, SK, KO, ZH_CN, EL, BG, ES, DA, UK, PT, IT, NL done)
|
||||||
- Bug squashing
|
- Wait for libtorrent v0.12 official release
|
||||||
- Wait for libtorrent v0.12 official release
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: libboost
|
name: libboost
|
||||||
|
arg: with-libboost-inc=[path], Path to libboost include files
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_libboost : public ConfObj
|
class qc_libboost : public ConfObj
|
||||||
@@ -10,31 +11,46 @@ public:
|
|||||||
QString name() const { return "libboost"; }
|
QString name() const { return "libboost"; }
|
||||||
QString shortname() const { return "libboost"; }
|
QString shortname() const { return "libboost"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
QString s;
|
QString s;
|
||||||
QStringList sl;
|
s = conf->getenv("QC_WITH_LIBBOOST_INC");
|
||||||
sl += "/usr/include";
|
if(!s.isEmpty()) {
|
||||||
sl += "/usr/local/include";
|
if(!conf->checkHeader(s, "boost/format.hpp")) {
|
||||||
sl += "/sw/include";
|
return false;
|
||||||
if(!conf->findHeader("boost/format.hpp", sl, &s)) {
|
}
|
||||||
qWarning("libboost includes not found!");
|
if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
conf->addIncludePath(s);
|
if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) {
|
||||||
if(!conf->findHeader("boost/date_time/posix_time/posix_time.hpp", sl, &s)) {
|
return false;
|
||||||
qWarning("libboost-date-time includes not found!");
|
}
|
||||||
return false;
|
if(!conf->checkHeader(s, "boost/thread.hpp")) {
|
||||||
}
|
return false;
|
||||||
conf->addIncludePath(s);
|
}
|
||||||
if(!conf->findHeader("boost/filesystem/path.hpp", sl, &s)) {
|
}else{
|
||||||
qWarning("libboost-filesystem includes not found!");
|
QStringList sl;
|
||||||
return false;
|
sl << "/usr/include";
|
||||||
}
|
sl << "/usr/local/include";
|
||||||
if(!conf->findHeader("boost/thread.hpp", sl, &s)) {
|
bool found = false;
|
||||||
qWarning("libboost-thread includes not found!");
|
foreach(s, sl){
|
||||||
return false;
|
if(conf->checkHeader(s, "boost/format.hpp")){
|
||||||
}
|
found = true;
|
||||||
conf->addIncludePath(s);
|
break;
|
||||||
|
}
|
||||||
return true;
|
}
|
||||||
|
if(!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!conf->checkHeader(s, "boost/thread.hpp")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conf->addIncludePath(s);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -12,43 +12,50 @@ public:
|
|||||||
QString name() const { return "libcurl"; }
|
QString name() const { return "libcurl"; }
|
||||||
QString shortname() const { return "libcurl"; }
|
QString shortname() const { return "libcurl"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
QString s;
|
QString s;
|
||||||
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkHeader(s, "curl/curl.h")) {
|
if(!conf->checkHeader(s, "curl/curl.h")) {
|
||||||
qWarning("libcurl includes not found!");
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
conf->addIncludePath(s);
|
}else{
|
||||||
}else{
|
QStringList sl;
|
||||||
QStringList sl;
|
sl << "/usr/include";
|
||||||
sl += "/usr/include";
|
sl << "/usr/local/include";
|
||||||
sl += "/usr/local/include";
|
bool found = false;
|
||||||
if(!conf->findHeader("curl/curl.h", sl, &s)) {
|
foreach(s, sl){
|
||||||
qWarning("libcurl includes not found!");
|
if(conf->checkHeader(s, "curl/curl.h")){
|
||||||
return false;
|
found = true;
|
||||||
}
|
break;
|
||||||
conf->addIncludePath(s);
|
}
|
||||||
}
|
}
|
||||||
|
if(!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conf->addIncludePath(s);
|
||||||
|
|
||||||
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkLibrary(s, "curl")) {
|
if(!conf->checkLibrary(s, "curl")) {
|
||||||
qWarning("libcurl library not found!");
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
conf->addLib(QString("-L") + s);
|
||||||
conf->addLib(QString("-L") + s);
|
}else{
|
||||||
}else{
|
QStringList sl;
|
||||||
if(!conf->findLibrary("curl", &s)) {
|
sl << "/usr/lib/";
|
||||||
qWarning("libcurl library not found!");
|
sl << "/usr/local/lib/";
|
||||||
return false;
|
bool found = false;
|
||||||
}
|
foreach(s, sl){
|
||||||
if (!s.isEmpty())
|
if(conf->checkLibrary(s, "curl")){
|
||||||
conf->addLib(QString("-L") + s);
|
found = true;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
conf->addLib("-lcurl");
|
}
|
||||||
|
if(!found) return false;
|
||||||
return true;
|
conf->addLib(QString("-L") + s);
|
||||||
|
}
|
||||||
|
conf->addLib("-lcurl");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -9,46 +9,60 @@ class qc_libtorrent : public ConfObj
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libtorrent(Conf *c) : ConfObj(c) {}
|
qc_libtorrent(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libtorrent >= 0.12"; }
|
QString name() const { return "libtorrent >= 0.11 (>= 0.12 ADVISED)"; }
|
||||||
QString shortname() const { return "libtorrent"; }
|
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");
|
||||||
if(!s.isEmpty()) {
|
if(!s.isEmpty()) {
|
||||||
if(!conf->checkHeader(s, "libtorrent/extensions/ut_pex.hpp")) {
|
if(!conf->checkHeader(s, "libtorrent/kademlia/node.hpp")){
|
||||||
qWarning("libtorrent v0.12 includes not found!\nYou can download it at http://www.libtorrent.net");
|
return false;
|
||||||
return false;
|
}
|
||||||
|
if(!conf->checkHeader(s, "libtorrent/extensions/ut_pex.hpp")) {
|
||||||
|
qWarning("Libtorrent >= v0.12 was not detected, PeX will be disabled.");
|
||||||
|
conf->addDefine("NO_PEX");
|
||||||
}
|
}
|
||||||
conf->addIncludePath(s);
|
}else{
|
||||||
}else{
|
QStringList sl;
|
||||||
QStringList sl;
|
sl << "/usr/include";
|
||||||
sl << "/usr/include/";
|
sl << "/usr/local/include";
|
||||||
sl << "/usr/local/include";
|
bool found = false;
|
||||||
if(!conf->findHeader("libtorrent/extensions/ut_pex.hpp", sl, &s)) {
|
foreach(s, sl){
|
||||||
qWarning("libtorrent v0.12 includes not found!\nYou can download it at http://www.libtorrent.net");
|
if(conf->checkHeader(s, "libtorrent/kademlia/node.hpp")){
|
||||||
return false;
|
found = true;
|
||||||
}
|
break;
|
||||||
conf->addIncludePath(s);
|
}
|
||||||
}
|
}
|
||||||
|
if(!found) return false;
|
||||||
|
if(!conf->checkHeader(s, "libtorrent/extensions/ut_pex.hpp")){
|
||||||
|
qWarning("Libtorrent >= v0.12 was not detected, PeX will be disabled.");
|
||||||
|
conf->addDefine("NO_PEX");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conf->addIncludePath(s);
|
||||||
|
conf->addIncludePath(s+QDir::separator()+"libtorrent");
|
||||||
|
|
||||||
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")) {
|
if(!conf->checkLibrary(s, "torrent")) {
|
||||||
qWarning("libtorrent library not found!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
conf->addLib(QString("-L") + s);
|
conf->addLib(QString("-L") + s);
|
||||||
}else{
|
}else{
|
||||||
if(!conf->findLibrary("torrent", &s)) {
|
QStringList sl;
|
||||||
qWarning("libtorrent library not found!");
|
sl << "/usr/lib/";
|
||||||
return false;
|
sl << "/usr/local/lib/";
|
||||||
}
|
bool found = false;
|
||||||
if (!s.isEmpty())
|
foreach(s, sl){
|
||||||
conf->addLib(QString("-L") + s);
|
if(conf->checkLibrary(s, "torrent")){
|
||||||
}
|
found = true;
|
||||||
|
break;
|
||||||
conf->addLib("-ltorrent");
|
}
|
||||||
|
}
|
||||||
return true;
|
if(!found) return false;
|
||||||
|
conf->addLib(QString("-L") + s);
|
||||||
|
}
|
||||||
|
//conf->addLib("-ltorrent");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
46
src/GUI.cpp
46
src/GUI.cpp
@@ -22,27 +22,22 @@
|
|||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QTemporaryFile>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QPainter>
|
//#include <QSettings>
|
||||||
#include <QToolTip>
|
|
||||||
#include <QStandardItemModel>
|
|
||||||
#include <QModelIndex>
|
|
||||||
#include <QHeaderView>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QCloseEvent>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <boost/filesystem/exception.hpp>
|
#include <boost/filesystem/exception.hpp>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#ifndef NO_PEX
|
||||||
#include <libtorrent/extensions/metadata_transfer.hpp>
|
#include <libtorrent/extensions/metadata_transfer.hpp>
|
||||||
#include <libtorrent/extensions/ut_pex.hpp>
|
#include <libtorrent/extensions/ut_pex.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "GUI.h"
|
#include "GUI.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
@@ -136,6 +131,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){
|
|||||||
connect(options, SIGNAL(status_changed(const QString&, bool)), this, SLOT(OptionsSaved(const QString&, bool)));
|
connect(options, SIGNAL(status_changed(const QString&, bool)), this, SLOT(OptionsSaved(const QString&, bool)));
|
||||||
// Configure BT session according to options
|
// Configure BT session according to options
|
||||||
configureSession(true);
|
configureSession(true);
|
||||||
|
force_exit = false;
|
||||||
// Resume unfinished torrents
|
// Resume unfinished torrents
|
||||||
BTSession.resumeUnfinishedTorrents();
|
BTSession.resumeUnfinishedTorrents();
|
||||||
// Add torrent given on command line
|
// Add torrent given on command line
|
||||||
@@ -163,7 +159,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){
|
|||||||
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&)));
|
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&)));
|
||||||
connect(actionWebsite, SIGNAL(triggered()), this, SLOT(openqBTHomepage()));
|
connect(actionWebsite, SIGNAL(triggered()), this, SLOT(openqBTHomepage()));
|
||||||
connect(actionBugReport, SIGNAL(triggered()), this, SLOT(openqBTBugTracker()));
|
connect(actionBugReport, SIGNAL(triggered()), this, SLOT(openqBTBugTracker()));
|
||||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayGUIMenu(const QPoint&)));
|
//connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayGUIMenu(const QPoint&)));
|
||||||
connect(actionPreview_file, SIGNAL(triggered()), this, SLOT(previewFileSelection()));
|
connect(actionPreview_file, SIGNAL(triggered()), this, SLOT(previewFileSelection()));
|
||||||
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&)));
|
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&)));
|
||||||
// Create tray icon
|
// Create tray icon
|
||||||
@@ -408,7 +404,7 @@ void GUI::displayDLListMenu(const QPoint& pos){
|
|||||||
// Necessary if we want to close the window
|
// Necessary if we want to close the window
|
||||||
// in one time if "close to systray" is enabled
|
// in one time if "close to systray" is enabled
|
||||||
void GUI::forceExit(){
|
void GUI::forceExit(){
|
||||||
hide();
|
force_exit = true;
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,8 +472,13 @@ void GUI::updateDlList(bool force){
|
|||||||
LCD_UpSpeed->display(tmp); // UP LCD
|
LCD_UpSpeed->display(tmp); // UP LCD
|
||||||
LCD_DownSpeed->display(tmp2); // DL LCD
|
LCD_DownSpeed->display(tmp2); // DL LCD
|
||||||
// browse handles
|
// browse handles
|
||||||
|
#ifndef NO_PEX
|
||||||
std::vector<torrent_handle> handles = BTSession.getTorrentHandles();
|
std::vector<torrent_handle> handles = BTSession.getTorrentHandles();
|
||||||
for(unsigned int i=0; i<handles.size(); ++i){
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QList<torrent_handle> handles = BTSession.getTorrentHandles();
|
||||||
|
#endif
|
||||||
|
for(unsigned int i=0; i<(unsigned int)handles.size(); ++i){
|
||||||
torrent_handle h = handles[i];
|
torrent_handle h = handles[i];
|
||||||
try{
|
try{
|
||||||
torrent_status torrentStatus = h.status();
|
torrent_status torrentStatus = h.status();
|
||||||
@@ -815,12 +816,15 @@ void GUI::showAbout(){
|
|||||||
void GUI::closeEvent(QCloseEvent *e){
|
void GUI::closeEvent(QCloseEvent *e){
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
bool goToSystrayOnExit = settings.value("Options/Misc/Behaviour/GoToSystrayOnExit", false).toBool();
|
bool goToSystrayOnExit = settings.value("Options/Misc/Behaviour/GoToSystrayOnExit", false).toBool();
|
||||||
if(goToSystrayOnExit && !this->isHidden()){
|
if(!force_exit && goToSystrayOnExit && !this->isHidden()){
|
||||||
hide();
|
hide();
|
||||||
e->ignore();
|
e->ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(settings.value("Options/Misc/Behaviour/ConfirmOnExit", true).toBool()){
|
if(settings.value("Options/Misc/Behaviour/ConfirmOnExit", true).toBool()){
|
||||||
|
show();
|
||||||
|
if(!isMaximized())
|
||||||
|
showNormal();
|
||||||
if(QMessageBox::question(this,
|
if(QMessageBox::question(this,
|
||||||
tr("Are you sure you want to quit?")+" -- "+tr("qBittorrent"),
|
tr("Are you sure you want to quit?")+" -- "+tr("qBittorrent"),
|
||||||
tr("Are you sure you want to quit qBittorrent?"),
|
tr("Are you sure you want to quit qBittorrent?"),
|
||||||
@@ -1028,7 +1032,7 @@ void GUI::torrentAdded(const QString& path, torrent_handle& h, bool fastResume){
|
|||||||
QString hash = QString(misc::toString(h.info_hash()).c_str());
|
QString hash = QString(misc::toString(h.info_hash()).c_str());
|
||||||
// Adding torrent to download list
|
// Adding torrent to download list
|
||||||
DLListModel->insertRow(row);
|
DLListModel->insertRow(row);
|
||||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.name().c_str()));
|
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.get_torrent_info().name().c_str()));
|
||||||
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.get_torrent_info().total_size()));
|
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.get_torrent_info().total_size()));
|
||||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
|
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
|
||||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
|
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
|
||||||
@@ -1172,12 +1176,14 @@ void GUI::configureSession(bool deleteOptions){
|
|||||||
}else{
|
}else{
|
||||||
BTSession.disableDHT();
|
BTSession.disableDHT();
|
||||||
}
|
}
|
||||||
|
#ifndef NO_PEX
|
||||||
if(!options->isPeXDisabled()){
|
if(!options->isPeXDisabled()){
|
||||||
qDebug("Enabling Peer eXchange (PeX)");
|
qDebug("Enabling Peer eXchange (PeX)");
|
||||||
BTSession.enablePeerExchange();
|
BTSession.enablePeerExchange();
|
||||||
}else{
|
}else{
|
||||||
qDebug("Peer eXchange (PeX) disabled");
|
qDebug("Peer eXchange (PeX) disabled");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Apply filtering settings
|
// Apply filtering settings
|
||||||
if(options->isFilteringEnabled()){
|
if(options->isFilteringEnabled()){
|
||||||
BTSession.enableIPFilter(options->getFilter());
|
BTSession.enableIPFilter(options->getFilter());
|
||||||
@@ -1248,7 +1254,7 @@ void GUI::pauseSelection(){
|
|||||||
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, STATUS), QVariant(tr("Paused")));
|
DLListModel->setData(DLListModel->index(row, STATUS), QVariant(tr("Paused")));
|
||||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
|
||||||
setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(QString(BTSession.getTorrentHandle(fileHash).name().c_str())));
|
setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(QString(BTSession.getTorrentHandle(fileHash).get_torrent_info().name().c_str())));
|
||||||
DLListModel->setData(DLListModel->index(row, NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
|
DLListModel->setData(DLListModel->index(row, NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
|
||||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant("0/0"));
|
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant("0/0"));
|
||||||
setRowColor(row, "red");
|
setRowColor(row, "red");
|
||||||
@@ -1291,7 +1297,7 @@ void GUI::startSelection(){
|
|||||||
// Update DL status
|
// Update DL status
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
DLListModel->setData(DLListModel->index(row, STATUS), QVariant(tr("Connecting...")));
|
DLListModel->setData(DLListModel->index(row, STATUS), QVariant(tr("Connecting...")));
|
||||||
setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(QString(BTSession.getTorrentHandle(fileHash).name().c_str())));
|
setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(QString(BTSession.getTorrentHandle(fileHash).get_torrent_info().name().c_str())));
|
||||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(":/Icons/skin/connecting.png")), Qt::DecorationRole);
|
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(":/Icons/skin/connecting.png")), Qt::DecorationRole);
|
||||||
setRowColor(row, "grey");
|
setRowColor(row, "grey");
|
||||||
}
|
}
|
||||||
@@ -1320,7 +1326,7 @@ void GUI::propertiesSelection(){
|
|||||||
// called when a torrent has finished
|
// called when a torrent has finished
|
||||||
void GUI::finishedTorrent(torrent_handle& h){
|
void GUI::finishedTorrent(torrent_handle& h){
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
QString fileName = QString(h.name().c_str());
|
QString fileName = QString(h.get_torrent_info().name().c_str());
|
||||||
setInfoBar(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName));
|
setInfoBar(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName));
|
||||||
int useOSD = settings.value("Options/OSDEnabled", 1).toInt();
|
int useOSD = settings.value("Options/OSDEnabled", 1).toInt();
|
||||||
if(useOSD == 1 || (useOSD == 2 && (isMinimized() || isHidden()))) {
|
if(useOSD == 1 || (useOSD == 2 && (isMinimized() || isHidden()))) {
|
||||||
@@ -1333,7 +1339,7 @@ void GUI::fullDiskError(torrent_handle& h){
|
|||||||
QSettings settings("qBittorrent", "qBittorrent");
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
int useOSD = settings.value("Options/OSDEnabled", 1).toInt();
|
int useOSD = settings.value("Options/OSDEnabled", 1).toInt();
|
||||||
if(useOSD == 1 || (useOSD == 2 && (isMinimized() || isHidden()))) {
|
if(useOSD == 1 || (useOSD == 2 && (isMinimized() || isHidden()))) {
|
||||||
myTrayIcon->showMessage(tr("I/O Error", "i.e: Input/Output Error"), tr("An error occured when trying to read or write %1. The disk is probably full, download has been paused", "e.g: An error occured when trying to read or write xxx.avi. The disk is probably full, download has been paused").arg(QString(h.name().c_str())), QSystemTrayIcon::Critical, TIME_TRAY_BALLOON);
|
myTrayIcon->showMessage(tr("I/O Error", "i.e: Input/Output Error"), tr("An error occured when trying to read or write %1. The disk is probably full, download has been paused", "e.g: An error occured when trying to read or write xxx.avi. The disk is probably full, download has been paused").arg(QString(h.get_torrent_info().name().c_str())), QSystemTrayIcon::Critical, TIME_TRAY_BALLOON);
|
||||||
}
|
}
|
||||||
// Download will be paused by libtorrent. Updating GUI information accordingly
|
// Download will be paused by libtorrent. Updating GUI information accordingly
|
||||||
int row = getRowFromHash(QString(misc::toString(h.info_hash()).c_str()));
|
int row = getRowFromHash(QString(misc::toString(h.info_hash()).c_str()));
|
||||||
|
@@ -23,11 +23,8 @@
|
|||||||
#define GUI_H
|
#define GUI_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QHash>
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
#include <QTcpSocket>
|
|
||||||
#include <QCloseEvent>
|
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
|
|
||||||
#include <libtorrent/entry.hpp>
|
#include <libtorrent/entry.hpp>
|
||||||
@@ -55,6 +52,8 @@ class DLListDelegate;
|
|||||||
class SearchListDelegate;
|
class SearchListDelegate;
|
||||||
class downloadThread;
|
class downloadThread;
|
||||||
class downloadFromURL;
|
class downloadFromURL;
|
||||||
|
class QTcpSocket;
|
||||||
|
class QCloseEvent;
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
@@ -82,6 +81,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
|
|||||||
SearchListDelegate *SearchDelegate;
|
SearchListDelegate *SearchDelegate;
|
||||||
unsigned int nbTorrents;
|
unsigned int nbTorrents;
|
||||||
QLabel *connecStatusLblIcon;
|
QLabel *connecStatusLblIcon;
|
||||||
|
bool force_exit;
|
||||||
// Preview
|
// Preview
|
||||||
previewSelect *previewSelection;
|
previewSelect *previewSelection;
|
||||||
QProcess *previewProcess;
|
QProcess *previewProcess;
|
||||||
|
BIN
src/Icons/flags/denmark.png
Normal file
BIN
src/Icons/flags/denmark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 270 B |
BIN
src/Icons/flags/japan.png
Normal file
BIN
src/Icons/flags/japan.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 324 B |
@@ -1,6 +1,6 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Categories=Qt;Application;Network;P2P
|
Categories=Qt;Application;Network;P2P
|
||||||
Comment=V0.9.0
|
Comment=V0.9.2
|
||||||
Encoding=UTF-8
|
Encoding=UTF-8
|
||||||
Exec=qbittorrent
|
Exec=qbittorrent
|
||||||
GenericName=Bittorrent client
|
GenericName=Bittorrent client
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 49 KiB |
@@ -782,6 +782,9 @@
|
|||||||
<property name="enabled" >
|
<property name="enabled" >
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="contextMenuPolicy" >
|
||||||
|
<enum>Qt::NoContextMenu</enum>
|
||||||
|
</property>
|
||||||
<property name="movable" >
|
<property name="movable" >
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@@ -45,17 +45,19 @@ class about : public QDialog, private Ui::AboutDlg{
|
|||||||
te_translation->append(QString::fromUtf8(
|
te_translation->append(QString::fromUtf8(
|
||||||
"<i>- <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\
|
"<i>- <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\
|
||||||
- <u>Catalan:</u> Gekko Dam Beer (gekko04@users.sourceforge.net)<br>\
|
- <u>Catalan:</u> Gekko Dam Beer (gekko04@users.sourceforge.net)<br>\
|
||||||
- <u>Chinese (Simplified):</u> Chen Wuyang (wuyang@gmail.com)<br>\
|
- <u>Chinese (Simplified):</u> Guo Yue (guoyue0418@hotmail.com)<br>\
|
||||||
- <u>Chinese (Traditional):</u> Jeff Chen (jeff.cn.chen@gmail.com)<br>\
|
- <u>Chinese (Traditional):</u> Jeff Chen (jeff.cn.chen@gmail.com)<br>\
|
||||||
|
- <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\
|
||||||
- <u>Dutch:</u> Luke Niesink (luke@lukeniesink.net)<br>\
|
- <u>Dutch:</u> Luke Niesink (luke@lukeniesink.net)<br>\
|
||||||
- <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>Italian:</u> Ferraro Luciano (luciano.ferraro@gmail.com)<br>\
|
- <u>Italian:</u> Ferraro Luciano (luciano.ferraro@gmail.com)<br>\
|
||||||
|
- <u>Japanese:</u> Nardog (nardog@e2umail.com)<br>\
|
||||||
- <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\
|
- <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\
|
||||||
- <u>Norwegian:</u> Lars-Erik Labori (hamil@users.sourceforge.net)<br>\
|
- <u>Norwegian:</u> Lars-Erik Labori (hamil@users.sourceforge.net)<br>\
|
||||||
- <u>Polish:</u> Adam Babol (a-b@users.sourceforge.net)<br>\
|
- <u>Polish:</u> Adam Babol (a-b@users.sourceforge.net)<br>\
|
||||||
- <u>Portuguese:</u> Bruno Nunes (brunopatriarca@users.sourceforge.net)<br>\
|
- <u>Portuguese:</u> Nick Marinho (nickmarinho@gmail.com)<br>\
|
||||||
- <u>Romanian:</u> Obada Denis (obadadenis@users.sourceforge.net)<br>\
|
- <u>Romanian:</u> Obada Denis (obadadenis@users.sourceforge.net)<br>\
|
||||||
- <u>Russian:</u> Nick Khazov (m2k3d0n at users.sourceforge.net)<br>\
|
- <u>Russian:</u> Nick Khazov (m2k3d0n at users.sourceforge.net)<br>\
|
||||||
- <u>Slovak:</u> helix84<br>\
|
- <u>Slovak:</u> helix84<br>\
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
// Main constructor
|
// Main constructor
|
||||||
bittorrent::bittorrent(){
|
bittorrent::bittorrent(){
|
||||||
|
// To avoid some exceptions
|
||||||
|
fs::path::default_name_check(fs::no_check);
|
||||||
// Supported preview extensions
|
// Supported preview extensions
|
||||||
// XXX: might be incomplete
|
// XXX: might be incomplete
|
||||||
supported_preview_extensions << "AVI" << "DIVX" << "MPG" << "MPEG" << "MP3" << "OGG" << "WMV" << "WMA" << "RMV" << "RMVB" << "ASF" << "MOV" << "WAV" << "MP2" << "SWF" << "AC3";
|
supported_preview_extensions << "AVI" << "DIVX" << "MPG" << "MPEG" << "MP3" << "OGG" << "WMV" << "WMA" << "RMV" << "RMVB" << "ASF" << "MOV" << "WAV" << "MP2" << "SWF" << "AC3";
|
||||||
@@ -36,8 +38,10 @@ bittorrent::bittorrent(){
|
|||||||
s->set_severity_level(alert::info);
|
s->set_severity_level(alert::info);
|
||||||
// DHT (Trackerless), disabled until told otherwise
|
// DHT (Trackerless), disabled until told otherwise
|
||||||
DHTEnabled = false;
|
DHTEnabled = false;
|
||||||
|
#ifndef NO_PEX
|
||||||
// Enabling metadata plugin
|
// Enabling metadata plugin
|
||||||
s->add_extension(&create_metadata_plugin);
|
s->add_extension(&create_metadata_plugin);
|
||||||
|
#endif
|
||||||
timerAlerts = new QTimer(this);
|
timerAlerts = new QTimer(this);
|
||||||
connect(timerAlerts, SIGNAL(timeout()), this, SLOT(readAlerts()));
|
connect(timerAlerts, SIGNAL(timeout()), this, SLOT(readAlerts()));
|
||||||
timerAlerts->start(3000);
|
timerAlerts->start(3000);
|
||||||
@@ -61,13 +65,23 @@ bittorrent::~bittorrent(){
|
|||||||
|
|
||||||
// Return the torrent handle, given its hash
|
// Return the torrent handle, given its hash
|
||||||
torrent_handle bittorrent::getTorrentHandle(const QString& hash) const{
|
torrent_handle bittorrent::getTorrentHandle(const QString& hash) const{
|
||||||
|
#ifndef NO_PEX
|
||||||
return s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
return s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
return torrent_list.value(hash);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the torrent corresponding to the
|
// Return true if the torrent corresponding to the
|
||||||
// hash is paused
|
// hash is paused
|
||||||
bool bittorrent::isPaused(const QString& hash) const{
|
bool bittorrent::isPaused(const QString& hash) const{
|
||||||
|
#ifndef NO_PEX
|
||||||
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
torrent_handle h = torrent_list.value(hash);
|
||||||
|
#endif
|
||||||
if(!h.is_valid()){
|
if(!h.is_valid()){
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
return true;
|
return true;
|
||||||
@@ -78,13 +92,18 @@ bool bittorrent::isPaused(const QString& hash) const{
|
|||||||
// 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(const QString& hash, bool permanent){
|
void bittorrent::deleteTorrent(const QString& hash, bool permanent){
|
||||||
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
#ifndef NO_PEX
|
||||||
if(!h.is_valid()){
|
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
torrent_handle h = torrent_list.value(hash);
|
||||||
|
#endif
|
||||||
|
if(!h.is_valid()){
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString savePath = QString::fromUtf8(h.save_path().string().c_str());
|
QString savePath = QString::fromUtf8(h.save_path().string().c_str());
|
||||||
QString fileName = QString(h.name().c_str());
|
QString fileName = QString(h.get_torrent_info().name().c_str());
|
||||||
// Remove it from session
|
// Remove it from session
|
||||||
s->remove_torrent(h);
|
s->remove_torrent(h);
|
||||||
// Remove it from torrent backup directory
|
// Remove it from torrent backup directory
|
||||||
@@ -112,7 +131,12 @@ void bittorrent::cleanDeleter(deleteThread* deleter){
|
|||||||
|
|
||||||
// Pause a running torrent
|
// Pause a running torrent
|
||||||
void bittorrent::pauseTorrent(const QString& hash){
|
void bittorrent::pauseTorrent(const QString& hash){
|
||||||
|
#ifndef NO_PEX
|
||||||
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
torrent_handle h = torrent_list.value(hash);
|
||||||
|
#endif
|
||||||
if(h.is_valid() && !h.is_paused()){
|
if(h.is_valid() && !h.is_paused()){
|
||||||
h.pause();
|
h.pause();
|
||||||
// Create .paused file
|
// Create .paused file
|
||||||
@@ -124,7 +148,12 @@ void bittorrent::pauseTorrent(const QString& hash){
|
|||||||
|
|
||||||
// Resume a torrent in paused state
|
// Resume a torrent in paused state
|
||||||
void bittorrent::resumeTorrent(const QString& hash){
|
void bittorrent::resumeTorrent(const QString& hash){
|
||||||
|
#ifndef NO_PEX
|
||||||
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
torrent_handle h = torrent_list.value(hash);
|
||||||
|
#endif
|
||||||
if(h.is_valid() && h.is_paused()){
|
if(h.is_valid() && h.is_paused()){
|
||||||
h.resume();
|
h.resume();
|
||||||
// Delete .paused file
|
// Delete .paused file
|
||||||
@@ -162,7 +191,12 @@ void bittorrent::addTorrent(const QString& path, bool fromScanDir, const QString
|
|||||||
// Getting torrent file informations
|
// Getting torrent file informations
|
||||||
torrent_info t(e);
|
torrent_info t(e);
|
||||||
QString hash = QString(misc::toString(t.info_hash()).c_str());
|
QString hash = QString(misc::toString(t.info_hash()).c_str());
|
||||||
|
#ifndef NO_PEX
|
||||||
if(s->find_torrent(t.info_hash()).is_valid()){
|
if(s->find_torrent(t.info_hash()).is_valid()){
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
if(torrent_list.value(hash, torrent_handle()).is_valid()){
|
||||||
|
#endif
|
||||||
// Update info Bar
|
// Update info Bar
|
||||||
if(!fromScanDir){
|
if(!fromScanDir){
|
||||||
if(!from_url.isNull()){
|
if(!from_url.isNull()){
|
||||||
@@ -212,6 +246,9 @@ void bittorrent::addTorrent(const QString& path, bool fromScanDir, const QString
|
|||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef NO_PEX
|
||||||
|
torrent_list.insert(QString(misc::toString(h.info_hash()).c_str()), h);
|
||||||
|
#endif
|
||||||
// Is this really useful and appropriate ?
|
// Is this really useful and appropriate ?
|
||||||
//h.set_max_connections(60);
|
//h.set_max_connections(60);
|
||||||
h.set_max_uploads(-1);
|
h.set_max_uploads(-1);
|
||||||
@@ -320,12 +357,12 @@ bool bittorrent::isDHTEnabled() const{
|
|||||||
// Enable DHT
|
// Enable DHT
|
||||||
void bittorrent::enableDHT(){
|
void bittorrent::enableDHT(){
|
||||||
if(!DHTEnabled){
|
if(!DHTEnabled){
|
||||||
boost::filesystem::ifstream dht_state_file((const char*)(misc::qBittorrentPath()+QString("dht_state")).toUtf8(), std::ios_base::binary);
|
entry dht_state;
|
||||||
dht_state_file.unsetf(std::ios_base::skipws);
|
try{
|
||||||
entry dht_state;
|
boost::filesystem::ifstream dht_state_file((const char*)(misc::qBittorrentPath()+QString("dht_state")).toUtf8(), std::ios_base::binary);
|
||||||
try{
|
dht_state_file.unsetf(std::ios_base::skipws);
|
||||||
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&) { }
|
||||||
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));
|
||||||
@@ -388,8 +425,13 @@ void bittorrent::saveFastResumeData(){
|
|||||||
torrentBackup.mkpath(torrentBackup.path());
|
torrentBackup.mkpath(torrentBackup.path());
|
||||||
}
|
}
|
||||||
// Write fast resume data
|
// Write fast resume data
|
||||||
|
#ifndef NO_PEX
|
||||||
std::vector<torrent_handle> handles = s->get_torrents();
|
std::vector<torrent_handle> handles = s->get_torrents();
|
||||||
for(unsigned int i=0; i<handles.size(); ++i){
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QList<torrent_handle> handles = torrent_list.values();
|
||||||
|
#endif
|
||||||
|
for(unsigned int i=0; i<(unsigned int)handles.size(); ++i){
|
||||||
torrent_handle &h = handles[i];
|
torrent_handle &h = handles[i];
|
||||||
if(!h.is_valid()){
|
if(!h.is_valid()){
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
@@ -402,7 +444,7 @@ void bittorrent::saveFastResumeData(){
|
|||||||
QString fileHash = QString(misc::toString(h.info_hash()).c_str());
|
QString fileHash = QString(misc::toString(h.info_hash()).c_str());
|
||||||
if(QFile::exists(torrentBackup.path()+QDir::separator()+fileHash+".torrent")){
|
if(QFile::exists(torrentBackup.path()+QDir::separator()+fileHash+".torrent")){
|
||||||
// Remove old .fastresume data in case it exists
|
// Remove old .fastresume data in case it exists
|
||||||
QFile::remove(fileHash + ".fastresume");
|
QFile::remove(torrentBackup.path()+QDir::separator()+fileHash + ".fastresume");
|
||||||
// Write fast resume data
|
// Write fast resume data
|
||||||
entry resumeData = h.write_resume_data();
|
entry resumeData = h.write_resume_data();
|
||||||
file = fileHash + ".fastresume";
|
file = fileHash + ".fastresume";
|
||||||
@@ -419,7 +461,12 @@ void bittorrent::saveFastResumeData(){
|
|||||||
|
|
||||||
bool bittorrent::isFilePreviewPossible(const QString& hash) const{
|
bool bittorrent::isFilePreviewPossible(const QString& hash) const{
|
||||||
// See if there are supported files in the torrent
|
// See if there are supported files in the torrent
|
||||||
|
#ifndef NO_PEX
|
||||||
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
torrent_handle h = s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())));
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
torrent_handle h = torrent_list.value(hash);
|
||||||
|
#endif
|
||||||
if(!h.is_valid()){
|
if(!h.is_valid()){
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
return false;
|
return false;
|
||||||
@@ -500,8 +547,13 @@ void bittorrent::setUploadRateLimit(int rate){
|
|||||||
// libtorrent allow to adjust ratio for each torrent
|
// libtorrent allow to adjust ratio for each torrent
|
||||||
// This function will apply to same ratio to all torrents
|
// This function will apply to same ratio to all torrents
|
||||||
void bittorrent::setGlobalRatio(float ratio){
|
void bittorrent::setGlobalRatio(float ratio){
|
||||||
|
#ifndef NO_PEX
|
||||||
std::vector<torrent_handle> handles = s->get_torrents();
|
std::vector<torrent_handle> handles = s->get_torrents();
|
||||||
for(unsigned int i=0; i<handles.size(); ++i){
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QList<torrent_handle> handles = torrent_list.values();
|
||||||
|
#endif
|
||||||
|
for(unsigned int i=0; i<(unsigned int)handles.size(); ++i){
|
||||||
torrent_handle h = handles[i];
|
torrent_handle h = handles[i];
|
||||||
if(!h.is_valid()){
|
if(!h.is_valid()){
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
@@ -513,8 +565,13 @@ void bittorrent::setGlobalRatio(float ratio){
|
|||||||
|
|
||||||
// Pause all torrents in session
|
// Pause all torrents in session
|
||||||
void bittorrent::pauseAllTorrents(){
|
void bittorrent::pauseAllTorrents(){
|
||||||
|
#ifndef NO_PEX
|
||||||
std::vector<torrent_handle> handles = s->get_torrents();
|
std::vector<torrent_handle> handles = s->get_torrents();
|
||||||
for(unsigned int i=0; i<handles.size(); ++i){
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QList<torrent_handle> handles = torrent_list.values();
|
||||||
|
#endif
|
||||||
|
for(unsigned int i=0; i<(unsigned int)handles.size(); ++i){
|
||||||
torrent_handle h = handles[i];
|
torrent_handle h = handles[i];
|
||||||
if(h.is_valid() && !h.is_paused()){
|
if(h.is_valid() && !h.is_paused()){
|
||||||
h.pause();
|
h.pause();
|
||||||
@@ -524,8 +581,13 @@ void bittorrent::pauseAllTorrents(){
|
|||||||
|
|
||||||
// Resume all torrents in session
|
// Resume all torrents in session
|
||||||
void bittorrent::resumeAllTorrents(){
|
void bittorrent::resumeAllTorrents(){
|
||||||
|
#ifndef NO_PEX
|
||||||
std::vector<torrent_handle> handles = s->get_torrents();
|
std::vector<torrent_handle> handles = s->get_torrents();
|
||||||
for(unsigned int i=0; i<handles.size(); ++i){
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QList<torrent_handle> handles = torrent_list.values();
|
||||||
|
#endif
|
||||||
|
for(unsigned int i=0; i<(unsigned int)handles.size(); ++i){
|
||||||
torrent_handle h = handles[i];
|
torrent_handle h = handles[i];
|
||||||
if(h.is_valid() && h.is_paused()){
|
if(h.is_valid() && h.is_paused()){
|
||||||
h.resume();
|
h.resume();
|
||||||
@@ -533,10 +595,12 @@ void bittorrent::resumeAllTorrents(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_PEX
|
||||||
// Add uT PeX extension to bittorrent session
|
// Add uT PeX extension to bittorrent session
|
||||||
void bittorrent::enablePeerExchange(){
|
void bittorrent::enablePeerExchange(){
|
||||||
s->add_extension(&create_ut_pex_plugin);
|
s->add_extension(&create_ut_pex_plugin);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set DHT port (>= 1000)
|
// Set DHT port (>= 1000)
|
||||||
void bittorrent::setDHTPort(int dht_port){
|
void bittorrent::setDHTPort(int dht_port){
|
||||||
@@ -598,7 +662,7 @@ void bittorrent::reloadTorrent(const torrent_handle &h, bool compact_mode){
|
|||||||
}
|
}
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||||
fs::path saveDir = h.save_path();
|
fs::path saveDir = h.save_path();
|
||||||
QString fileName = QString(h.name().c_str());
|
QString fileName = QString(h.get_torrent_info().name().c_str());
|
||||||
QString fileHash = QString(misc::toString(h.info_hash()).c_str());
|
QString fileHash = QString(misc::toString(h.info_hash()).c_str());
|
||||||
qDebug("Reloading torrent: %s", (const char*)fileName.toUtf8());
|
qDebug("Reloading torrent: %s", (const char*)fileName.toUtf8());
|
||||||
torrent_handle new_h;
|
torrent_handle new_h;
|
||||||
@@ -731,9 +795,16 @@ float bittorrent::getPayloadUploadRate() const{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return a vector with all torrent handles in it
|
// Return a vector with all torrent handles in it
|
||||||
|
#ifndef NO_PEX
|
||||||
std::vector<torrent_handle> bittorrent::getTorrentHandles() const{
|
std::vector<torrent_handle> bittorrent::getTorrentHandles() const{
|
||||||
return s->get_torrents();
|
return s->get_torrents();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QList<torrent_handle> bittorrent::getTorrentHandles() const {
|
||||||
|
return torrent_list.values();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Return a vector with all finished torrent handles in it
|
// Return a vector with all finished torrent handles in it
|
||||||
QList<torrent_handle> bittorrent::getFinishedTorrentHandles() const{
|
QList<torrent_handle> bittorrent::getFinishedTorrentHandles() const{
|
||||||
|
@@ -21,9 +21,6 @@
|
|||||||
#ifndef __BITTORRENT_H__
|
#ifndef __BITTORRENT_H__
|
||||||
#define __BITTORRENT_H__
|
#define __BITTORRENT_H__
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
#include <QString>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include <libtorrent/entry.hpp>
|
#include <libtorrent/entry.hpp>
|
||||||
@@ -33,9 +30,15 @@
|
|||||||
#include <libtorrent/session_settings.hpp>
|
#include <libtorrent/session_settings.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>
|
||||||
|
|
||||||
|
#ifndef NO_PEX
|
||||||
#include <libtorrent/extensions/metadata_transfer.hpp>
|
#include <libtorrent/extensions/metadata_transfer.hpp>
|
||||||
#include <libtorrent/extensions/ut_pex.hpp>
|
#include <libtorrent/extensions/ut_pex.hpp>
|
||||||
#include <libtorrent/ip_filter.hpp>
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
#include <QHash>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
@@ -60,6 +63,9 @@ class bittorrent : public QObject{
|
|||||||
downloadThread *downloader;
|
downloadThread *downloader;
|
||||||
QStringList supported_preview_extensions;
|
QStringList supported_preview_extensions;
|
||||||
QString defaultSavePath;
|
QString defaultSavePath;
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QHash<QString, torrent_handle> torrent_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString getSavePath(const QString& hash);
|
QString getSavePath(const QString& hash);
|
||||||
@@ -69,7 +75,12 @@ class bittorrent : public QObject{
|
|||||||
bittorrent();
|
bittorrent();
|
||||||
~bittorrent();
|
~bittorrent();
|
||||||
torrent_handle getTorrentHandle(const QString& hash) const;
|
torrent_handle getTorrentHandle(const QString& hash) const;
|
||||||
|
#ifndef NO_PEX
|
||||||
std::vector<torrent_handle> getTorrentHandles() const;
|
std::vector<torrent_handle> getTorrentHandles() const;
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
QList<torrent_handle> getTorrentHandles() const;
|
||||||
|
#endif
|
||||||
bool isPaused(const QString& hash) const;
|
bool isPaused(const QString& hash) const;
|
||||||
bool hasFilteredFiles(const QString& fileHash) const;
|
bool hasFilteredFiles(const QString& fileHash) const;
|
||||||
bool isFilePreviewPossible(const QString& fileHash) const;
|
bool isFilePreviewPossible(const QString& fileHash) const;
|
||||||
@@ -95,7 +106,9 @@ class bittorrent : public QObject{
|
|||||||
void saveFastResumeData();
|
void saveFastResumeData();
|
||||||
void enableDirectoryScanning(const QString& scan_dir);
|
void enableDirectoryScanning(const QString& scan_dir);
|
||||||
void disableDirectoryScanning();
|
void disableDirectoryScanning();
|
||||||
|
#ifndef NO_PEX
|
||||||
void enablePeerExchange();
|
void enablePeerExchange();
|
||||||
|
#endif
|
||||||
void enableIPFilter(ip_filter filter);
|
void enableIPFilter(ip_filter filter);
|
||||||
void disableIPFilter();
|
void disableIPFilter();
|
||||||
void reloadTorrent(const torrent_handle &h, bool compact_mode = true);
|
void reloadTorrent(const torrent_handle &h, bool compact_mode = true);
|
||||||
|
@@ -32,7 +32,10 @@
|
|||||||
#include <libtorrent/file.hpp>
|
#include <libtorrent/file.hpp>
|
||||||
#include <libtorrent/storage.hpp>
|
#include <libtorrent/storage.hpp>
|
||||||
#include <libtorrent/hasher.hpp>
|
#include <libtorrent/hasher.hpp>
|
||||||
|
|
||||||
|
#ifndef NO_PEX
|
||||||
#include <libtorrent/file_pool.hpp>
|
#include <libtorrent/file_pool.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "createtorrent_imp.h"
|
#include "createtorrent_imp.h"
|
||||||
|
|
||||||
@@ -105,9 +108,13 @@ void createtorrent::on_createButton_clicked(){
|
|||||||
|
|
||||||
add_files(t, full_path.branch_path(), full_path.leaf());
|
add_files(t, full_path.branch_path(), full_path.leaf());
|
||||||
t.set_piece_size(piece_size);
|
t.set_piece_size(piece_size);
|
||||||
|
#ifndef NO_PEX
|
||||||
file_pool fp;
|
file_pool fp;
|
||||||
storage st(t, full_path.branch_path(), fp);
|
storage st(t, full_path.branch_path(), fp);
|
||||||
|
#endif
|
||||||
|
#ifdef NO_PEX
|
||||||
|
storage st(t, full_path.branch_path());
|
||||||
|
#endif
|
||||||
QStringList trackers = txt_announce->toPlainText().split('\n');
|
QStringList trackers = txt_announce->toPlainText().split('\n');
|
||||||
for(int i=0; i<trackers.size(); ++i){
|
for(int i=0; i<trackers.size(); ++i){
|
||||||
t.add_tracker((const char*)trackers.at(i).toUtf8());
|
t.add_tracker((const char*)trackers.at(i).toUtf8());
|
||||||
|
@@ -2,13 +2,13 @@
|
|||||||
<qresource>
|
<qresource>
|
||||||
<file>Icons/encrypted.png</file>
|
<file>Icons/encrypted.png</file>
|
||||||
<file>Icons/locale.png</file>
|
<file>Icons/locale.png</file>
|
||||||
|
<file>Icons/newmsg.png</file>
|
||||||
<file>Icons/style.png</file>
|
<file>Icons/style.png</file>
|
||||||
<file>Icons/wizard.png</file>
|
<file>Icons/wizard.png</file>
|
||||||
<file>Icons/button_cancel.png</file>
|
<file>Icons/button_cancel.png</file>
|
||||||
<file>Icons/button_ok.png</file>
|
<file>Icons/button_ok.png</file>
|
||||||
<file>Icons/smile.png</file>
|
<file>Icons/smile.png</file>
|
||||||
<file>Icons/stare.png</file>
|
<file>Icons/stare.png</file>
|
||||||
<file>Icons/newmsg.png</file>
|
|
||||||
<file>Icons/qbittorrent22.png</file>
|
<file>Icons/qbittorrent22.png</file>
|
||||||
<file>Icons/proxy.png</file>
|
<file>Icons/proxy.png</file>
|
||||||
<file>Icons/log.png</file>
|
<file>Icons/log.png</file>
|
||||||
@@ -29,19 +29,20 @@
|
|||||||
<file>Icons/flags/south_korea.png</file>
|
<file>Icons/flags/south_korea.png</file>
|
||||||
<file>Icons/flags/slovakia.png</file>
|
<file>Icons/flags/slovakia.png</file>
|
||||||
<file>Icons/flags/spain.png</file>
|
<file>Icons/flags/spain.png</file>
|
||||||
|
<file>Icons/flags/finland.png</file>
|
||||||
<file>Icons/flags/poland.png</file>
|
<file>Icons/flags/poland.png</file>
|
||||||
<file>Icons/flags/spain_catalunya.png</file>
|
|
||||||
<file>Icons/flags/china_hong_kong.png</file>
|
<file>Icons/flags/china_hong_kong.png</file>
|
||||||
|
<file>Icons/flags/spain_catalunya.png</file>
|
||||||
|
<file>Icons/flags/norway.png</file>
|
||||||
<file>Icons/flags/italy.png</file>
|
<file>Icons/flags/italy.png</file>
|
||||||
<file>Icons/flags/china.png</file>
|
<file>Icons/flags/china.png</file>
|
||||||
<file>Icons/flags/norway.png</file>
|
<file>Icons/flags/denmark.png</file>
|
||||||
<file>Icons/flags/turkey.png</file>
|
<file>Icons/flags/turkey.png</file>
|
||||||
<file>Icons/flags/sweden.png</file>
|
<file>Icons/flags/sweden.png</file>
|
||||||
<file>Icons/flags/romania.png</file>
|
<file>Icons/flags/romania.png</file>
|
||||||
<file>Icons/flags/bulgaria.png</file>
|
<file>Icons/flags/bulgaria.png</file>
|
||||||
<file>Icons/flags/greece.png</file>
|
<file>Icons/flags/greece.png</file>
|
||||||
<file>Icons/flags/finland.png</file>
|
<file>Icons/flags/japan.png</file>
|
||||||
<file>Icons/skin/delete_perm.png</file>
|
|
||||||
<file>Icons/skin/properties.png</file>
|
<file>Icons/skin/properties.png</file>
|
||||||
<file>Icons/skin/play_all.png</file>
|
<file>Icons/skin/play_all.png</file>
|
||||||
<file>Icons/skin/remove.png</file>
|
<file>Icons/skin/remove.png</file>
|
||||||
@@ -51,9 +52,9 @@
|
|||||||
<file>Icons/skin/delete.png</file>
|
<file>Icons/skin/delete.png</file>
|
||||||
<file>Icons/skin/connected.png</file>
|
<file>Icons/skin/connected.png</file>
|
||||||
<file>Icons/skin/url.png</file>
|
<file>Icons/skin/url.png</file>
|
||||||
<file>Icons/skin/play.png</file>
|
|
||||||
<file>Icons/skin/pause_all.png</file>
|
<file>Icons/skin/pause_all.png</file>
|
||||||
<file>Icons/skin/downloading.png</file>
|
<file>Icons/skin/downloading.png</file>
|
||||||
|
<file>Icons/skin/play.png</file>
|
||||||
<file>Icons/skin/search.png</file>
|
<file>Icons/skin/search.png</file>
|
||||||
<file>Icons/skin/exit.png</file>
|
<file>Icons/skin/exit.png</file>
|
||||||
<file>Icons/skin/pause.png</file>
|
<file>Icons/skin/pause.png</file>
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
<file>Icons/skin/seeding.png</file>
|
<file>Icons/skin/seeding.png</file>
|
||||||
<file>Icons/skin/paused.png</file>
|
<file>Icons/skin/paused.png</file>
|
||||||
<file>Icons/skin/preview.png</file>
|
<file>Icons/skin/preview.png</file>
|
||||||
|
<file>Icons/skin/delete_perm.png</file>
|
||||||
<file>Icons/skin/connecting.png</file>
|
<file>Icons/skin/connecting.png</file>
|
||||||
<file>Icons/skin/add.png</file>
|
<file>Icons/skin/add.png</file>
|
||||||
<file>Icons/skin/stalled.png</file>
|
<file>Icons/skin/stalled.png</file>
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
<file>lang/qbittorrent_uk.qm</file>
|
<file>lang/qbittorrent_uk.qm</file>
|
||||||
<file>lang/qbittorrent_ro.qm</file>
|
<file>lang/qbittorrent_ro.qm</file>
|
||||||
<file>lang/qbittorrent_ru.qm</file>
|
<file>lang/qbittorrent_ru.qm</file>
|
||||||
|
<file>lang/qbittorrent_nb.qm</file>
|
||||||
<file>lang/qbittorrent_el.qm</file>
|
<file>lang/qbittorrent_el.qm</file>
|
||||||
<file>lang/qbittorrent_en.qm</file>
|
<file>lang/qbittorrent_en.qm</file>
|
||||||
<file>lang/qbittorrent_fr.qm</file>
|
<file>lang/qbittorrent_fr.qm</file>
|
||||||
@@ -16,11 +17,12 @@
|
|||||||
<file>lang/qbittorrent_pt.qm</file>
|
<file>lang/qbittorrent_pt.qm</file>
|
||||||
<file>lang/qbittorrent_ca.qm</file>
|
<file>lang/qbittorrent_ca.qm</file>
|
||||||
<file>lang/qbittorrent_tr.qm</file>
|
<file>lang/qbittorrent_tr.qm</file>
|
||||||
<file>lang/qbittorrent_sv.qm</file>
|
|
||||||
<file>lang/qbittorrent_bg.qm</file>
|
<file>lang/qbittorrent_bg.qm</file>
|
||||||
<file>lang/qbittorrent_de.qm</file>
|
<file>lang/qbittorrent_de.qm</file>
|
||||||
<file>lang/qbittorrent_zh_HK.qm</file>
|
<file>lang/qbittorrent_sv.qm</file>
|
||||||
<file>lang/qbittorrent_nb.qm</file>
|
|
||||||
<file>lang/qbittorrent_fi.qm</file>
|
<file>lang/qbittorrent_fi.qm</file>
|
||||||
|
<file>lang/qbittorrent_zh_HK.qm</file>
|
||||||
|
<file>lang/qbittorrent_da.qm</file>
|
||||||
|
<file>lang/qbittorrent_ja.qm</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
src/lang/qbittorrent_da.qm
Normal file
BIN
src/lang/qbittorrent_da.qm
Normal file
Binary file not shown.
1740
src/lang/qbittorrent_da.ts
Normal file
1740
src/lang/qbittorrent_da.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
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