Compare commits

..

1 Commits

Author SHA1 Message Date
Christophe Dumez
0b0d473a53 tagged v1.3.0 release 2009-01-14 12:37:31 +00:00
219 changed files with 32241 additions and 31763 deletions

View File

@@ -17,11 +17,6 @@ Images Authors:
license: GPLv2
url: http://ftp.acc.umu.se/pub/GNOME/sources/gnome-icon-theme
* files: src/oxygen/*.png
copyright: Oxygen Icon Theme (KDE)
license: LGPL
url: http://www.oxygen-icons.org
* files: src/Icons/flags/*.png
copyright: Open Clip Art Library
license: Creative Commons Public Domain Dedication

14
COPYING
View File

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

View File

@@ -1,72 +1,3 @@
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.5.0
- FEATURE: Added Magnet URI support
- FEATURE: Make use of torrent enclosure in RSS feeds for direct download
- FEATURE: Implemented a RSS feed downloader with filter support
- FEATURE: Save old RSS item to hard disk to remember them on start up
- FEATURE: Display free disk space in torrent addition dialog
- FEATURE: In torrent addition from URL, paste clipboard content if it contains an URL
- FEATURE: RSS Feeds URLs can now be copied to clipboard
- FEATURE: If a torrent contains a torrent file, process downloaded torrent file too
- BUGFIX: torrent resume code rewrited
* Thu Aug 13 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.4.0
- FEATURE: Display swarm information in lists
- FEATURE: Allow to define temporary download folder
- FEATURE: Display total amount of uploaded data in finished list
- FEATURE: Resizing a column in a search results tab affects all tabs
- FEATURE: Search results tab columns are now remembered upon startup
- FEATURE: Added right click menu in search engine to clear completion history
- FEATURE: Allow to set a different port for DHT (UDP) than the one used for Bittorrent
- FEATURE: Updated spoofing code to avoid trackers ban
- BUGFIX: Provide more helpful explanation when an I/O error occured
- BUGFIX: Stop enforcing UTF-8 and use system locale instead
- COSMETIC: Redesigned program preferences
- COSMETIC: Updated icons set
* Fri Jul 24 2009 - Christophe DUMEZ <chris@qbittorrent.org> - 1.3.5
- BUGFIX: Made IP filter parser more robust
- BUGFIX: Fixed torrent creation tool
- BUGFIX: Fixed possible overflow in progress calculation in arborescence.h
- BUGFIX: Save properties window size, position, columns width and restore them
- BUGFIX: Set a minimum default width for NAME column in properties
- BUGFIX: Remember visual indexes of columns in transfer lists
* Sun Jul 12 2009 - Christophe DUMEZ <chris@qbittorrent.org> - v1.3.4
- BUGFIX: Fixed IP filter file parsing on 64bits
- BUGFIX: Suppressed QLayout: Attempting to add QLayout "" to properties "properties" warning message when opening a properties dialog
- BUGFIX: Fixed a little bug in search engine plugins helper file
- BUGFIX: Fixed compilation problems with Qt 4.3
- BUGFIX: Percentages no longer disapear with default cleanlooks style
- BUGFIX: Cleanly fixed popup menus position in lists (no more workarounds)
- BUGFIX: Fixed memory leak in search engine
- BUGFIX: Torrents with an infinite ratio are no longer affected by ratio_limit set in program preferences
- BUGFIX: Display a ratio of 0.0 if total_upload and total_download are both 0
- BUGFIX: Remove last separator in top tool bar
- BUGFIX: Tuned lists properties to make sure display is correct
- COSMETIC: Display date as well as time in log window
* Sun Apr 5 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.3
- BUGFIX: Fixed Web UI torrent upload form
- BUGFIX: Fixed unicode support in search engine
- BUGFIX: Fixed search engine bug that prevented a torrent from appearing more than once among all tabs
- LICENSE: Added an exception to the license regarding OpenSSL.
- I18N: Updated Finnish translation
* Sat Mar 7 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.2
- BUGFIX: Fix top toolbar disabling
- BUGFIX: Fix building with Qt 4.5
- BUGFIX: RSS items read status is now remembered upon restart
* Mon Jan 26 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.1
- BUGFIX: Torrents paused due to an I/O error were displayed as queued
- BUGFIX: qBittorrent now prints backtrace in terminal when segfaulting
- BUGFIX: Fixed files progress display in torrent properties
- BUGFIX: Improved torrent ratio calculation
- BUGFIX: Fixed possible crash when parsing filter file
- BUGFIX: Made some code optimization
- BUGFIX: Fixed download/upload speed decrease problems
- I18N: Updated Finnish, Bulgarian and Greek translations
* Fri Jan 9 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.0
- FEATURE: Based on libtorrent-rasterbar v0.14.2
- FEATURE: Improved ratio calculation system

16
TODO
View File

@@ -1,2 +1,18 @@
See https://blueprints.launchpad.net/qbittorrent/
// translations done in v1.3.0
- Romanian
- Russian
- Hungarian
- German
- Chinese (traditional)
- Chinese (simplified)
- Italian
- Swedish
- Turkish
- French
- Slovak
- Czech
- Korean
- Portuguese
- Brazilian

95
configure vendored
View File

@@ -18,6 +18,11 @@ Main options:
--help This help text.
Dependency options:
--with-libtorrent-inc=[path] Path to libtorrent-rasterbar include
files
--with-libtorrent-lib=[path] Path to libtorrent-rasterbar library
files
--with-libtorrent-static-lib=[path] Path to libtorrent-rasterbar .a file
--with-libboost-inc=[path] Path to libboost include files
--with-libcurl-inc=[path] Path to libcurl include files
--with-libcurl-lib=[path] Path to libcurl library files
@@ -140,6 +145,21 @@ while [ $# -gt 0 ]; do
shift
;;
--with-libtorrent-inc=*)
QC_WITH_LIBTORRENT_INC=$optarg
shift
;;
--with-libtorrent-lib=*)
QC_WITH_LIBTORRENT_LIB=$optarg
shift
;;
--with-libtorrent-static-lib=*)
QC_WITH_LIBTORRENT_STATIC_LIB=$optarg
shift
;;
--with-libboost-inc=*)
QC_WITH_LIBBOOST_INC=$optarg
shift
@@ -191,6 +211,9 @@ echo PREFIX=$PREFIX
echo BINDIR=$BINDIR
echo DATADIR=$DATADIR
echo EX_QTDIR=$EX_QTDIR
echo QC_WITH_LIBTORRENT_INC=$QC_WITH_LIBTORRENT_INC
echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB
echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
@@ -323,29 +346,70 @@ public:
/*
-----BEGIN QCMOD-----
name: libtorrent-rasterbar
arg: with-libtorrent-inc=[path], Path to libtorrent-rasterbar include files
arg: with-libtorrent-lib=[path], Path to libtorrent-rasterbar library files
arg: with-libtorrent-static-lib=[path], Path to libtorrent-rasterbar .a file
-----END QCMOD-----
*/
// see Conf::findPkgConfig
class qc_libtorrent_rasterbar : public ConfObj
{
public:
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent-rasterbar >= 0.14.0 (>= 0.14.4 advised)"; }
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
QString shortname() const { return "libtorrent-rasterbar"; }
bool exec(){
QStringList incs;
QString req_ver = "0.14.0";
QString adv_ver = "0.14.4";
QString version, libs, other;
VersionMode mode = VersionMin;
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other))
QString s;
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
return false;
for(int n = 0; n < incs.count(); ++n)
conf->addIncludePath(incs[n]);
if(!libs.isEmpty())
conf->addLib(libs);
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, adv_ver, &version, &incs, &libs, &other))
printf("\nWarning: libtorrent-rasterbar v%s was detected. Although it will compile and run, you will probably experience some bugs. Please consider updating to v%s!\n", version.toUtf8().data(), adv_ver.toUtf8().data());
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
conf->addIncludePath(s+QDir::separator()+"libtorrent");
s = conf->getenv("QC_WITH_LIBTORRENT_STATIC_LIB");
if(!s.isEmpty() && QFile::exists(s) && s.endsWith(".a")){
conf->addLib(s);
return true;
}
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
if(!s.isEmpty()) {
if(!conf->checkLibrary(s, "torrent-rasterbar")) {
return false;
}
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(conf->checkLibrary(s, "torrent-rasterbar")){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true;
}
};
@@ -1503,6 +1567,9 @@ export PREFIX
export BINDIR
export DATADIR
export EX_QTDIR
export QC_WITH_LIBTORRENT_INC
export QC_WITH_LIBTORRENT_LIB
export QC_WITH_LIBTORRENT_STATIC_LIB
export QC_WITH_LIBBOOST_INC
export QC_WITH_LIBCURL_INC
export QC_WITH_LIBCURL_LIB

65
qcm/libcommoncpp2.qcm Normal file
View File

@@ -0,0 +1,65 @@
/*
-----BEGIN QCMOD-----
name: libcommoncpp2
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files
-----END QCMOD-----
*/
class qc_libcommoncpp2 : public ConfObj
{
public:
qc_libcommoncpp2(Conf *c) : ConfObj(c) {}
QString name() const { return "GNU Common C++ library (libcommoncpp2)"; }
QString shortname() const { return "libcommoncpp2"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "cc++/url.h")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "cc++/url.h")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
if(!s.isEmpty()) {
if(!QFile::exists(s+QString("/libccext2.so")))
return false;
if(!QFile::exists(s+QString("/libccgnu2.so")))
return false;
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(QFile::exists(s+QString("libccext2.so"))){
if(QFile::exists(s+QString("libccgnu2.so"))){
found = true;
break;
}
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true;
}
};

View File

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

View File

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

View File

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

View File

@@ -1,480 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef FEEDDOWNLOADER_H
#define FEEDDOWNLOADER_H
#include <QString>
#include <QHash>
#include <QSettings>
#include <QListWidget>
#include <QListWidgetItem>
#include <QInputDialog>
#include <QMessageBox>
#include <QRegExp>
#include <QMenu>
#include <QFile>
#include <QDataStream>
#include <QFileDialog>
#include "bittorrent.h"
#include "ui_FeedDownloader.h"
class FeedFilter: public QHash<QString, QVariant> {
private:
bool valid;
public:
FeedFilter():valid(true) {}
FeedFilter(bool valid): valid(valid) {}
FeedFilter(QHash<QString, QVariant> filter): QHash<QString, QVariant>(filter), valid(true) {}
bool matches(QString s) {
QStringList match_tokens = getMatchingTokens();
foreach(const QString& token, match_tokens) {
if(token.isEmpty() || token == "")
continue;
QRegExp reg(token, Qt::CaseInsensitive);
if(reg.indexIn(s) < 0) return false;
}
// Checking not matching
QStringList notmatch_tokens = getNotMatchingTokens();
foreach(const QString& token, notmatch_tokens) {
if(token.isEmpty()) continue;
QRegExp reg(token, Qt::CaseInsensitive);
if(reg.indexIn(s) > -1) return false;
}
return true;
}
bool isValid() const {
return valid;
}
QStringList getMatchingTokens() const {
QString matches = this->value("matches", "").toString();
return matches.split(" ");
}
QString getMatchingTokens_str() const {
return this->value("matches", "*").toString();
}
void setMatchingTokens(QString tokens) {
tokens = tokens.trimmed();
if(tokens.isEmpty())
(*this)["matches"] = "";
else
(*this)["matches"] = tokens;
}
QStringList getNotMatchingTokens() const {
QString notmatching = this->value("not", "").toString();
return notmatching.split(" ");
}
QString getNotMatchingTokens_str() const {
return this->value("not", "").toString();
}
void setNotMatchingTokens(QString tokens) {
(*this)["not"] = tokens.trimmed();
}
QString getSavePath() const {
return this->value("save_path", "").toString();
}
void setSavePath(QString save_path) {
(*this)["save_path"] = save_path;
}
};
class FeedFilters : public QHash<QString, QVariant> {
private:
QString feed_url;
public:
FeedFilters() {}
FeedFilters(QString feed_url, QHash<QString, QVariant> filters): QHash<QString, QVariant>(filters), feed_url(feed_url) {}
bool hasFilter(QString name) const {
return this->contains(name);
}
FeedFilter* matches(QString s) {
if(!isDownloadingEnabled()) return 0;
if(this->size() == 0) return new FeedFilter(false);
foreach(QVariant var_hash_filter, this->values()) {
QHash<QString, QVariant> hash_filter = var_hash_filter.toHash();
FeedFilter *filter = new FeedFilter(hash_filter);
if(filter->matches(s))
return filter;
else
delete filter;
}
return 0;
}
QStringList names() const {
return this->keys();
}
FeedFilter getFilter(QString name) const {
if(this->contains(name))
return FeedFilter(this->value(name).toHash());
return FeedFilter();
}
void setFilter(QString name, FeedFilter f) {
(*this)[name] = f;
}
bool isDownloadingEnabled() const {
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QHash<QString, QVariant> feeds_w_downloader = qBTRSS.value("downloader_on", QHash<QString, QVariant>()).toHash();
return feeds_w_downloader.value(feed_url, false).toBool();
}
void setDownloadingEnabled(bool enabled) {
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QHash<QString, QVariant> feeds_w_downloader = qBTRSS.value("downloader_on", QHash<QString, QVariant>()).toHash();
feeds_w_downloader[feed_url] = enabled;
qBTRSS.setValue("downloader_on", feeds_w_downloader);
}
static FeedFilters getFeedFilters(QString url) {
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QHash<QString, QVariant> all_feeds_filters = qBTRSS.value("feed_filters", QHash<QString, QVariant>()).toHash();
return FeedFilters(url, all_feeds_filters.value(url, QHash<QString, QVariant>()).toHash());
}
void rename(QString old_name, QString new_name) {
Q_ASSERT(this->contains(old_name));
(*this)[new_name] = this->take(old_name);
}
bool serialize(QString path) {
QFile f(path);
if(f.open(QIODevice::WriteOnly)) {
QDataStream out(&f);
out.setVersion(QDataStream::Qt_4_3);
out << (QHash<QString, QVariant>)(*this);
f.close();
return true;
} else {
return false;
}
}
bool unserialize(QString path) {
QFile f(path);
if(f.open(QIODevice::ReadOnly)) {
QDataStream in(&f);
in.setVersion(QDataStream::Qt_4_3);
QHash<QString, QVariant> tmp;
in >> tmp;
qDebug("Unserialized %d filters", tmp.size());
foreach(const QString& key, tmp.keys()) {
(*this)[key] = tmp[key];
}
return true;
} else {
return false;
}
}
void save() {
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QHash<QString, QVariant> all_feeds_filters = qBTRSS.value("feed_filters", QHash<QString, QVariant>()).toHash();
qDebug("Saving filters for feed: %s (%d filters)", feed_url.toLocal8Bit().data(), (*this).size());
all_feeds_filters[feed_url] = *this;
qBTRSS.setValue("feed_filters", all_feeds_filters);
}
};
class FeedDownloaderDlg : public QDialog, private Ui_FeedDownloader{
Q_OBJECT
private:
QString feed_url;
QString feed_name;
FeedFilters filters;
bittorrent *BTSession;
QString selected_filter; // name
public:
FeedDownloaderDlg(QWidget *parent, QString feed_url, QString feed_name, bittorrent* BTSession): QDialog(parent), feed_url(feed_url), feed_name(feed_name), BTSession(BTSession), selected_filter(QString::null){
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
Q_ASSERT(!feed_name.isEmpty());
rssfeed_lbl->setText(feed_name);
filters = FeedFilters::getFeedFilters(feed_url);
// Connect Signals/Slots
connect(filtersList, SIGNAL(currentItemChanged(QListWidgetItem* , QListWidgetItem *)), this, SLOT(showFilterSettings(QListWidgetItem *)));
connect(filtersList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFiltersListMenu(const QPoint&)));
connect(actionAdd_filter, SIGNAL(triggered()), this, SLOT(addFilter()));
connect(actionRemove_filter, SIGNAL(triggered()), this, SLOT(deleteFilter()));
connect(actionRename_filter, SIGNAL(triggered()), this, SLOT(renameFilter()));
connect(del_button, SIGNAL(clicked(bool)), this, SLOT(deleteFilter()));
connect(add_button, SIGNAL(clicked(bool)), this, SLOT(addFilter()));
connect(enableDl_cb, SIGNAL(stateChanged(int)), this, SLOT(enableFilterBox(int)));
// Restore saved info
enableDl_cb->setChecked(filters.isDownloadingEnabled());
fillFiltersList();
if(filters.size() > 0) {
// Select first filter
filtersList->setCurrentItem(filtersList->item(0));
//showFilterSettings(filtersList->item(0));
}
// Show
show();
}
~FeedDownloaderDlg() {
// Make sure we save everything
saveCurrentFilterSettings();
filters.save();
}
protected slots:
void saveCurrentFilterSettings() {
if(!selected_filter.isEmpty()) {
FeedFilter filter = filters.getFilter(selected_filter);
filter.setMatchingTokens(match_line->text());
filter.setNotMatchingTokens(notmatch_line->text());
QString save_path = savepath_line->text().trimmed();
if(save_path.isEmpty())
save_path = BTSession->getDefaultSavePath();
filter.setSavePath(save_path);
// Save updated filter
filters.setFilter(selected_filter, filter);
}
}
void fillFiltersList() {
// Fill filter list
foreach(QString filter_name, filters.names()) {
new QListWidgetItem(filter_name, filtersList);
}
}
void displayFiltersListMenu(const QPoint&) {
QMenu myFiltersListMenu(this);
if(filtersList->selectedItems().size() > 0) {
myFiltersListMenu.addAction(actionRename_filter);
myFiltersListMenu.addAction(actionRemove_filter);
} else {
myFiltersListMenu.addAction(actionAdd_filter);
}
// Call menu
myFiltersListMenu.exec(QCursor::pos());
}
void showFilterSettings(QListWidgetItem *item) {
// First, save current filter settings
saveCurrentFilterSettings();
// Clear all fields
clearFields();
if(!item) {
qDebug("No new selected item");
return;
}
// Actually show filter settings
QString filter_name = item->text();
FeedFilter filter = filters.getFilter(filter_name);
filterSettingsBox->setEnabled(true);
match_line->setText(filter.getMatchingTokens_str());
if(match_line->text().trimmed().isEmpty()) {
match_line->setText(filter_name);
}
notmatch_line->setText(filter.getNotMatchingTokens_str());
QString save_path = filter.getSavePath();
if(save_path.isEmpty())
save_path = BTSession->getDefaultSavePath();
savepath_line->setText(save_path);
// Update selected filter
selected_filter = filter_name;
}
void deleteFilter() {
QList<QListWidgetItem *> items = filtersList->selectedItems();
if(items.size() == 1) {
QListWidgetItem * item = items.first();
filters.remove(item->text());
selected_filter = QString::null;
delete item;
// Reset Filter settings view
if(filters.size() == 0) {
clearFields();
filterSettingsBox->setEnabled(false);
}
}
}
void renameFilter() {
QList<QListWidgetItem *> items = filtersList->selectedItems();
if(items.size() == 1) {
QListWidgetItem *item = items.first();
QString current_name = item->text();
QString new_name;
bool validated = false;
do {
new_name = askFilterName(current_name);
if(new_name.isNull() || new_name == current_name) return;
if(!filters.hasFilter(new_name)) {
validated = true;
} else {
QMessageBox::critical(0, tr("Invalid filter name"), tr("This filter name is already in use."));
}
}while(!validated);
// Rename the filter
filters.rename(current_name, new_name);
if(selected_filter == current_name)
selected_filter = new_name;
item->setText(new_name);
}
}
void enableFilterBox(int state) {
if(state == Qt::Checked) {
filtersBox->setEnabled(true);
filters.setDownloadingEnabled(true);
} else {
filtersBox->setEnabled(false);
filters.setDownloadingEnabled(false);
}
}
QString askFilterName(QString name=QString::null) {
QString name_prop;
if(name.isEmpty())
name_prop = tr("New filter");
else
name_prop = name;
QString new_name;
bool validated = false;
do {
bool ok;
new_name = QInputDialog::getText(this, tr("Please choose a name for this filter"), tr("Filter name:"), QLineEdit::Normal, name_prop, &ok);
if(!ok) {
return QString::null;
}
// Validate filter name
new_name = new_name.trimmed();
if(new_name.isEmpty()) {
// Cannot be left empty
QMessageBox::critical(0, tr("Invalid filter name"), tr("The filter name cannot be left empty."));
} else {
validated = true;
}
} while(!validated);
return new_name;
}
void addFilter() {
QString filter_name = QString::null;
bool validated = false;
do {
filter_name = askFilterName();
if(filter_name.isNull()) return;
if(filters.hasFilter(filter_name)) {
// Filter alread exists
QMessageBox::critical(0, tr("Invalid filter name"), tr("This filter name is already in use."));
} else {
validated = true;
}
}while(!validated);
QListWidgetItem *it = new QListWidgetItem(filter_name, filtersList);
filtersList->setCurrentItem(it);
//showFilterSettings(it);
}
void clearFields() {
match_line->clear();
notmatch_line->clear();
savepath_line->clear();
test_res_lbl->setText("");
test_line->clear();
}
void on_testButton_clicked(bool) {
if(selected_filter.isEmpty()) return;
QString s = test_line->text().trimmed();
if(s.isEmpty()) {
QMessageBox::critical(0, tr("Filter testing error"), tr("Please specify a test torrent name."));
return;
}
// Get current filter
saveCurrentFilterSettings();
FeedFilter f = filters.getFilter(selected_filter);
if(f.matches(s))
test_res_lbl->setText("<b><font color=\"green\">"+tr("matches")+"</font></b>");
else
test_res_lbl->setText("<b><font color=\"red\">"+tr("does not match")+"</font></b>");
}
void on_importButton_clicked(bool) {
QString source = QFileDialog::getOpenFileName(0, tr("Select file to import"), QDir::homePath(), tr("Filters Files")+QString::fromUtf8(" (*.filters)"));
if(source.isEmpty()) return;
if(filters.unserialize(source)) {
// Clean up first
clearFields();
filtersList->clear();
selected_filter = QString::null;
fillFiltersList();
if(filters.size() > 0)
filtersList->setCurrentItem(filtersList->item(0));
QMessageBox::information(0, tr("Import successful"), tr("Filters import was successful."));
} else {
QMessageBox::critical(0, tr("Import failure"), tr("Filters could not be imported due to an I/O error."));
}
}
void on_exportButton_clicked(bool) {
QString destination = QFileDialog::getSaveFileName(this, tr("Select destination file"), QDir::homePath(), tr("Filters Files")+QString::fromUtf8(" (*.filters)"));
if(destination.isEmpty()) return;
// Append file extension
if(!destination.endsWith(".filters"))
destination += ".filters";
if(QFile::exists(destination)) {
int ret = QMessageBox::question(0, tr("Overwriting confirmation"), tr("Are you sure you want to overwrite existing file?"));
if(ret != QMessageBox::Yes) return;
}
if(filters.serialize(destination))
QMessageBox::information(0, tr("Export successful"), tr("Filters export was successful."));
else
QMessageBox::critical(0, tr("Export failure"), tr("Filters could not be exported due to an I/O error."));
}
};
#endif // FEEDDOWNLOADER_H

View File

@@ -1,546 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FeedDownloader</class>
<widget class="QDialog" name="FeedDownloader">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>737</width>
<height>415</height>
</rect>
</property>
<property name="windowTitle">
<string>RSS Feed downloader</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>RSS feed:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rssfeed_lbl">
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Feed name</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<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>
<item>
<widget class="QCheckBox" name="enableDl_cb">
<property name="text">
<string>Automatically download torrents from this feed</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="filtersBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="title">
<string>Download filters</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Filters:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<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>
<item>
<widget class="QListWidget" name="filtersList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer_2">
<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="QPushButton" name="del_button">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-remove.png</normaloff>:/Icons/oxygen/list-remove.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="add_button">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-add.png</normaloff>:/Icons/oxygen/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<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>
</item>
<item>
<widget class="QGroupBox" name="filterSettingsBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string/>
</property>
<property name="title">
<string>Filter settings</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Matches:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Does not match:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Destination folder:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLineEdit" name="match_line">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="notmatch_line"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="savepath_line">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="browse_button">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="testerBox">
<property name="title">
<string>Filter testing</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>0</width>
<height>28</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Torrent title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Result:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLineEdit" name="test_line"/>
</item>
<item>
<widget class="QPushButton" name="testButton">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Test</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="test_res_lbl">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string> </string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<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>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>9</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QPushButton" name="importButton">
<property name="text">
<string>Import...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export...</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<action name="actionRename_filter">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/edit_clear.png</normaloff>:/Icons/oxygen/edit_clear.png</iconset>
</property>
<property name="text">
<string>Rename filter</string>
</property>
<property name="toolTip">
<string>Rename filter</string>
</property>
</action>
<action name="actionRemove_filter">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-remove.png</normaloff>:/Icons/oxygen/list-remove.png</iconset>
</property>
<property name="text">
<string>Remove filter</string>
</property>
<property name="toolTip">
<string>Remove filter</string>
</property>
</action>
<action name="actionAdd_filter">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-add.png</normaloff>:/Icons/oxygen/list-add.png</iconset>
</property>
<property name="text">
<string>Add filter</string>
</property>
</action>
</widget>
<resources>
<include location="icons.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>FeedDownloader</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>FeedDownloader</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

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

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include "FinishedTorrents.h"
@@ -46,17 +37,13 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
setupUi(this);
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
finishedListModel = new QStandardItemModel(0,8);
finishedListModel = new QStandardItemModel(0,6);
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_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed"));
finishedListModel->setHeaderData(F_SWARM, Qt::Horizontal, tr("Seeds / Leechers"));
finishedListModel->setHeaderData(F_PEERS, Qt::Horizontal, tr("Connected peers"));
finishedListModel->setHeaderData(F_UPLOAD, Qt::Horizontal, tr("Total uploaded", "i.e: Total amount of uploaded data"));
finishedListModel->setHeaderData(F_LEECH, Qt::Horizontal, tr("Leechers", "i.e: full/partial sources"));
finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio"));
finishedList->setModel(finishedListModel);
finishedList->setRootIsDecorated(false);
finishedList->setAllColumnsShowFocus(true);
loadHiddenColumns();
// Hide hash column
finishedList->hideColumn(F_HASH);
@@ -64,8 +51,6 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
if(!loadColWidthFinishedList()){
finishedList->header()->resizeSection(0, 200);
}
// Connect BTSession signals
connect(BTSession, SIGNAL(metadataReceived(QTorrentHandle&)), this, SLOT(updateMetadata(QTorrentHandle&)));
// Make download list header clickable for sorting
finishedList->header()->setClickable(true);
finishedList->header()->setSortIndicatorShown(true);
@@ -81,8 +66,6 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
actionCopy_magnet_link->setIcon(QIcon(QString::fromUtf8(":/Icons/magnet.png")));
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered()));
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
@@ -92,14 +75,11 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
connect(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
connect(actionCopy_magnet_link, SIGNAL(triggered()), (GUI*)parent, SLOT(copyMagnetURI()));
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed()));
connect(actionHOSColSwarm, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSwarm()));
connect(actionHOSColPeers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPeers()));
connect(actionHOSColUpload, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpload()));
connect(actionHOSColLeechers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnLeechers()));
connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio()));
}
@@ -126,9 +106,7 @@ void FinishedTorrents::addTorrent(QString hash){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name()));
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.));
finishedListModel->setData(finishedListModel->index(row, F_SWARM), QVariant("-1/-1"));
finishedListModel->setData(finishedListModel->index(row, F_PEERS), QVariant("0"));
finishedListModel->setData(finishedListModel->index(row, F_UPLOAD), QVariant((qlonglong)h.all_time_upload()));
finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant("0"));
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString::fromUtf8(misc::toString(BTSession->getRealRatio(hash)).c_str())));
finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash));
if(h.is_paused()) {
@@ -155,8 +133,9 @@ void FinishedTorrents::setRowColor(int row, QString color){
QStringList FinishedTorrents::getSelectedTorrents(bool only_one) const{
QStringList res;
QModelIndex index;
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes) {
foreach(index, selectedIndexes) {
if(index.column() == F_NAME) {
// Get the file hash
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
@@ -187,23 +166,6 @@ bool FinishedTorrents::loadColWidthFinishedList(){
finishedList->header()->resizeSection(i, width_list.at(i).toInt());
}
loadLastSortedColumn();
QVariantList visualIndexes = settings.value(QString::fromUtf8("FinishedListVisualIndexes"), QVariantList()).toList();
if(visualIndexes.size() != finishedListModel->columnCount()-1) {
qDebug("Corrupted values for download list columns sizes");
return false;
}
bool change = false;
do {
change = false;
for(int i=0;i<visualIndexes.size(); ++i) {
int new_visual_index = visualIndexes.at(finishedList->header()->logicalIndex(i)).toInt();
if(i != new_visual_index) {
qDebug("Moving column from %d to %d", finishedList->header()->logicalIndex(i), new_visual_index);
finishedList->header()->moveSection(i, new_visual_index);
change = true;
}
}
}while(change);
qDebug("Finished list columns width loaded");
return true;
}
@@ -238,7 +200,7 @@ void FinishedTorrents::saveColWidthFinishedList() const{
width_list = line.split(' ');
}
for(short i=0; i<nbColumns; ++i){
if(finishedList->columnWidth(i)<1 && width_list.size() == nbColumns && width_list.at(i).toInt()>=1) {
if(finishedList->columnWidth(i)<1 && width_list.size() == finishedListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
// load the former width
new_width_list << width_list.at(i);
} else if(finishedList->columnWidth(i)>=1) {
@@ -251,18 +213,14 @@ void FinishedTorrents::saveColWidthFinishedList() const{
}
}
settings.setValue("FinishedListColsWidth", new_width_list.join(" "));
QVariantList visualIndexes;
for(int i=0; i<nbColumns; ++i) {
visualIndexes.append(finishedList->header()->visualIndex(i));
}
settings.setValue(QString::fromUtf8("FinishedListVisualIndexes"), visualIndexes);
qDebug("Finished list columns width saved");
}
void FinishedTorrents::on_actionSet_upload_limit_triggered(){
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
QModelIndex index;
QStringList hashes;
foreach(const QModelIndex &index, selectedIndexes){
foreach(index, selectedIndexes){
if(index.column() == F_NAME){
// Get the file hash
hashes << finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
@@ -271,18 +229,7 @@ void FinishedTorrents::on_actionSet_upload_limit_triggered(){
new BandwidthAllocationDialog(this, true, BTSession, hashes);
}
void FinishedTorrents::updateMetadata(QTorrentHandle &h) {
QString hash = h.hash();
int row = getRowFromHash(hash);
if(row != -1) {
qDebug("Updating torrent metadata in download list");
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name()));
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
}
}
void FinishedTorrents::updateTorrent(QTorrentHandle h) {
if(!h.is_valid()) return;
QString hash = h.hash();
int row = getRowFromHash(hash);
if(row == -1){
@@ -291,25 +238,22 @@ void FinishedTorrents::updateTorrent(QTorrentHandle h) {
row = getRowFromHash(hash);
}
Q_ASSERT(row != -1);
if(!finishedList->isColumnHidden(F_SWARM)) {
finishedListModel->setData(finishedListModel->index(row, F_SWARM), misc::toQString(h.num_complete())+QString("/")+misc::toQString(h.num_incomplete()));
}
if(h.is_paused()) return;
// Update queued torrent
if(BTSession->isQueueingEnabled() && h.is_queued()) {
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
} else {
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole);
}
// Reset upload speed and seeds/leech
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), 0.);
finishedListModel->setData(finishedListModel->index(row, F_PEERS), "0");
finishedListModel->setData(finishedListModel->index(row, F_LEECH), "0");
setRowColor(row, QString::fromUtf8("grey"));
return;
}
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
return;
}
@@ -318,11 +262,8 @@ void FinishedTorrents::updateTorrent(QTorrentHandle h) {
if(!finishedList->isColumnHidden(F_UPSPEED)) {
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
}
if(!finishedList->isColumnHidden(F_PEERS)) {
finishedListModel->setData(finishedListModel->index(row, F_PEERS), misc::toQString(h.num_peers() - h.num_seeds(), true));
}
if(!finishedList->isColumnHidden(F_UPLOAD)) {
finishedListModel->setData(finishedListModel->index(row, F_UPLOAD), QVariant((double)h.all_time_upload()));
if(!finishedList->isColumnHidden(F_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))));
@@ -346,7 +287,7 @@ void FinishedTorrents::pauseTorrent(QString hash) {
return;
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_PEERS), QVariant(QString::fromUtf8("0")));
finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant(QString::fromUtf8("0")));
setRowColor(row, QString::fromUtf8("red"));
}
@@ -389,7 +330,8 @@ void FinishedTorrents::updateFileSize(QString hash){
// display properties of selected items
void FinishedTorrents::propertiesSelection(){
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){
QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == F_NAME){
showProperties(index);
}
@@ -398,22 +340,23 @@ void FinishedTorrents::propertiesSelection(){
void FinishedTorrents::forceRecheck(){
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){
QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == F_NAME){
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
QTorrentHandle h = BTSession->getTorrentHandle(hash);
qDebug("Forcing recheck for torrent %s", hash.toLocal8Bit().data());
h.force_recheck();
}
}
}
void FinishedTorrents::displayFinishedListMenu(const QPoint&){
void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
QMenu myFinishedListMenu(this);
QModelIndex index;
// Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
bool has_pause = false, has_start = false, has_preview = false;
foreach(const QModelIndex &index, selectedIndexes) {
foreach(index, selectedIndexes) {
if(index.column() == F_NAME) {
// Get the file name
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
@@ -449,11 +392,11 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint&){
myFinishedListMenu.addAction(actionOpen_destination_folder);
myFinishedListMenu.addAction(actionTorrent_Properties);
myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionCopy_magnet_link);
myFinishedListMenu.addAction(actionBuy_it);
// Call menu
myFinishedListMenu.exec(QCursor::pos());
// XXX: why mapToGlobal() is not enough?
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,58));
}
@@ -488,12 +431,12 @@ void FinishedTorrents::hideOrShowColumn(int index) {
if(nbVisibleColumns <= 1) return;
// User can hide the column, do it.
finishedList->setColumnHidden(index, true);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png")));
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
--nbVisibleColumns;
} else {
// User want to display the column
finishedList->setColumnHidden(index, false);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png")));
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
++nbVisibleColumns;
}
//resize all others non-hidden columns
@@ -516,16 +459,8 @@ void FinishedTorrents::hideOrShowColumnUpSpeed() {
hideOrShowColumn(F_UPSPEED);
}
void FinishedTorrents::hideOrShowColumnSwarm() {
hideOrShowColumn(F_SWARM);
}
void FinishedTorrents::hideOrShowColumnPeers() {
hideOrShowColumn(F_PEERS);
}
void FinishedTorrents::hideOrShowColumnUpload() {
hideOrShowColumn(F_UPLOAD);
void FinishedTorrents::hideOrShowColumnLeechers() {
hideOrShowColumn(F_LEECH);
}
void FinishedTorrents::hideOrShowColumnRatio() {
@@ -551,9 +486,9 @@ bool FinishedTorrents::loadHiddenColumns() {
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/oxygen/button_cancel.png")));
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
} else {
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png")));
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
}
}
return loaded;
@@ -587,14 +522,8 @@ QAction* FinishedTorrents::getActionHoSCol(int index) {
case F_UPSPEED :
return actionHOSColUpSpeed;
break;
case F_SWARM :
return actionHOSColSwarm;
break;
case F_PEERS :
return actionHOSColPeers;
break;
case F_UPLOAD :
return actionHOSColUpload;
case F_LEECH :
return actionHOSColLeechers;
break;
case F_RATIO :
return actionHOSColRatio;
@@ -618,7 +547,6 @@ void FinishedTorrents::toggleFinishedListSortOrder(int index) {
case F_SIZE:
case F_UPSPEED:
case F_RATIO:
case F_UPLOAD:
sortFinishedListFloat(index, sortOrder);
break;
default:
@@ -643,8 +571,6 @@ void FinishedTorrents::sortFinishedList(int index, Qt::SortOrder sortOrder){
switch(index) {
case F_SIZE:
case F_UPSPEED:
case F_UPLOAD:
case F_RATIO:
sortFinishedListFloat(index, sortOrder);
break;
default:

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
@@ -79,9 +70,7 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
void hideOrShowColumnName();
void hideOrShowColumnSize();
void hideOrShowColumnUpSpeed();
void hideOrShowColumnSwarm();
void hideOrShowColumnPeers();
void hideOrShowColumnUpload();
void hideOrShowColumnLeechers();
void hideOrShowColumnRatio();
void forceRecheck();
@@ -93,7 +82,6 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
void deleteTorrent(QString hash);
void showPropertiesFromHash(QString hash);
void loadLastSortedColumn();
void updateMetadata(QTorrentHandle &h);
signals:
void torrentMovedFromFinishedList(QString);

File diff suppressed because it is too large Load Diff

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
@@ -70,7 +61,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
// Bittorrent
bittorrent *BTSession;
QTimer *checkConnect;
QTimer *scrapeTimer;
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers;
// GUI related
QTabWidget *tabs;
@@ -140,10 +130,9 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void createTrayIcon();
void updateUnfinishedTorrentNumber(unsigned int nb);
void updateFinishedTorrentNumber(unsigned int nb);
void fullDiskError(QTorrentHandle& h, QString msg) const;
void fullDiskError(QTorrentHandle& h) const;
void handleDownloadFromUrlFailure(QString, QString) const;
void createSystrayDelayed();
void setPaused(QTorrentHandle &h) const;
// Keyboard shortcuts
void createKeyboardShortcuts();
void displayDownTab() const;
@@ -179,7 +168,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
bool initWebUi(QString username, QString password, int port);
void on_actionIncreasePriority_triggered();
void on_actionDecreasePriority_triggered();
void scrapeTrackers();
// Options slots
void on_actionOptions_triggered();
void OptionsSaved(bool deleteOptions);
@@ -192,7 +180,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void setTabText(int index, QString text) const;
void openDestinationFolder() const;
void goBuyPage() const;
void copyMagnetURI() const;
void updateRatio();
protected:

BIN
src/Icons/bt_settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/Icons/button_cancel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/Icons/button_ok.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/Icons/configure.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/Icons/connection.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

BIN
src/Icons/description.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

BIN
src/Icons/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 575 B

View File

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 750 B

View File

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 704 B

BIN
src/Icons/filter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

View File

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 449 B

BIN
src/Icons/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/Icons/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/Icons/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
src/Icons/newmsg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/Icons/password.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
src/Icons/proxy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

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

View File

Before

Width:  |  Height:  |  Size: 965 B

After

Width:  |  Height:  |  Size: 965 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
src/Icons/skin/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

BIN
src/Icons/skin/remove.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

BIN
src/Icons/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/Icons/style.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/Icons/subscribe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/Icons/subscribe16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

BIN
src/Icons/systemtray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 856 B

BIN
src/Icons/unavailable.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 765 B

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

After

Width:  |  Height:  |  Size: 629 B

BIN
src/Icons/wizard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<ui version="4.0" >
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
@@ -10,266 +9,264 @@
<height>563</height>
</rect>
</property>
<property name="contextMenuPolicy">
<property name="contextMenuPolicy" >
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="windowTitle">
<property name="windowTitle" >
<string/>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout"/>
<widget class="QWidget" name="centralwidget" >
<layout class="QVBoxLayout" />
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>914</width>
<height>23</height>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menu_Edit">
<property name="title">
<widget class="QMenu" name="menu_Edit" >
<property name="title" >
<string>&amp;Edit</string>
</property>
<addaction name="actionStart_All"/>
<addaction name="actionPause_All"/>
<addaction name="separator"/>
<addaction name="actionStart"/>
<addaction name="actionPause"/>
<addaction name="separator"/>
<addaction name="actionTorrent_Properties"/>
<addaction name="separator"/>
<addaction name="actionDelete"/>
<addaction name="actionDelete_Permanently"/>
<addaction name="actionDecreasePriority"/>
<addaction name="actionIncreasePriority"/>
<addaction name="actionStart_All" />
<addaction name="actionPause_All" />
<addaction name="separator" />
<addaction name="actionStart" />
<addaction name="actionPause" />
<addaction name="separator" />
<addaction name="actionTorrent_Properties" />
<addaction name="separator" />
<addaction name="actionDelete" />
<addaction name="actionDelete_Permanently" />
<addaction name="actionDecreasePriority" />
<addaction name="actionIncreasePriority" />
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
<widget class="QMenu" name="menu_Help" >
<property name="title" >
<string>&amp;Help</string>
</property>
<addaction name="actionBugReport"/>
<addaction name="actionWebsite"/>
<addaction name="actionDocumentation"/>
<addaction name="actionAbout"/>
<addaction name="actionBugReport" />
<addaction name="actionWebsite" />
<addaction name="actionDocumentation" />
<addaction name="actionAbout" />
</widget>
<widget class="QMenu" name="menu_Options">
<property name="title">
<widget class="QMenu" name="menu_Options" >
<property name="title" >
<string>Options</string>
</property>
<addaction name="actionOptions"/>
<addaction name="actionShow_console"/>
<addaction name="actionOptions" />
<addaction name="actionShow_console" />
</widget>
<widget class="QMenu" name="menu_File">
<property name="title">
<widget class="QMenu" name="menu_File" >
<property name="title" >
<string>&amp;File</string>
</property>
<addaction name="actionOpen"/>
<addaction name="actionDownload_from_URL"/>
<addaction name="actionCreate_torrent"/>
<addaction name="actionExit"/>
<addaction name="actionOpen" />
<addaction name="actionDownload_from_URL" />
<addaction name="actionCreate_torrent" />
<addaction name="actionExit" />
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Edit"/>
<addaction name="menu_Options"/>
<addaction name="menu_Help"/>
<addaction name="menu_File" />
<addaction name="menu_Edit" />
<addaction name="menu_Options" />
<addaction name="menu_Help" />
</widget>
<widget class="QToolBar" name="toolBar">
<property name="enabled">
<widget class="QToolBar" name="toolBar" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="contextMenuPolicy">
<property name="contextMenuPolicy" >
<enum>Qt::NoContextMenu</enum>
</property>
<property name="movable">
<property name="movable" >
<bool>false</bool>
</property>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="iconSize">
<property name="iconSize" >
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="floatable">
<property name="floatable" >
<bool>false</bool>
</property>
<attribute name="toolBarArea">
<attribute name="toolBarArea" >
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<attribute name="toolBarBreak" >
<bool>false</bool>
</attribute>
<addaction name="actionOpen"/>
<addaction name="actionDownload_from_URL"/>
<addaction name="separator"/>
<addaction name="actionDelete"/>
<addaction name="actionDelete_Permanently"/>
<addaction name="separator"/>
<addaction name="actionTorrent_Properties"/>
<addaction name="separator"/>
<addaction name="actionStart"/>
<addaction name="actionPause"/>
<addaction name="separator"/>
<addaction name="actionStart_All"/>
<addaction name="actionPause_All"/>
<addaction name="separator"/>
<addaction name="actionOptions"/>
<addaction name="actionDecreasePriority"/>
<addaction name="actionIncreasePriority"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
<addaction name="actionOpen" />
<addaction name="actionDownload_from_URL" />
<addaction name="separator" />
<addaction name="actionDelete" />
<addaction name="actionDelete_Permanently" />
<addaction name="separator" />
<addaction name="actionTorrent_Properties" />
<addaction name="separator" />
<addaction name="actionStart" />
<addaction name="actionPause" />
<addaction name="separator" />
<addaction name="actionStart_All" />
<addaction name="actionPause_All" />
<addaction name="separator" />
<addaction name="actionOptions" />
<addaction name="actionDecreasePriority" />
<addaction name="actionIncreasePriority" />
<addaction name="separator" />
<addaction name="actionExit" />
<addaction name="separator" />
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionOpen">
<property name="text">
<widget class="QStatusBar" name="statusBar" />
<action name="actionOpen" >
<property name="text" >
<string>Open</string>
</property>
</action>
<action name="actionExit">
<property name="text">
<action name="actionExit" >
<property name="text" >
<string>Exit</string>
</property>
</action>
<action name="actionOptions">
<property name="text">
<action name="actionOptions" >
<property name="text" >
<string>Preferences</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<action name="actionAbout" >
<property name="text" >
<string>About</string>
</property>
</action>
<action name="actionStart">
<property name="text">
<action name="actionStart" >
<property name="text" >
<string>Start</string>
</property>
</action>
<action name="actionPause">
<property name="text">
<action name="actionPause" >
<property name="text" >
<string>Pause</string>
</property>
</action>
<action name="actionDelete">
<property name="text">
<action name="actionDelete" >
<property name="text" >
<string>Delete</string>
</property>
</action>
<action name="actionPause_All">
<property name="text">
<action name="actionPause_All" >
<property name="text" >
<string>Pause All</string>
</property>
</action>
<action name="actionStart_All">
<property name="text">
<action name="actionStart_All" >
<property name="text" >
<string>Start All</string>
</property>
</action>
<action name="actionWebsite">
<property name="text">
<action name="actionWebsite" >
<property name="text" >
<string>Visit website</string>
</property>
</action>
<action name="actionDelete_Permanently">
<property name="text">
<action name="actionDelete_Permanently" >
<property name="text" >
<string>Delete Permanently</string>
</property>
</action>
<action name="actionTorrent_Properties">
<property name="text">
<action name="actionTorrent_Properties" >
<property name="text" >
<string>Torrent Properties</string>
</property>
</action>
<action name="actionDownload_from_URL">
<property name="text">
<action name="actionDownload_from_URL" >
<property name="text" >
<string>Download from URL</string>
</property>
</action>
<action name="actionCreate_torrent">
<property name="text">
<action name="actionCreate_torrent" >
<property name="text" >
<string>Create torrent</string>
</property>
</action>
<action name="actionPreview_file">
<property name="text">
<action name="actionPreview_file" >
<property name="text" >
<string>Preview file</string>
</property>
</action>
<action name="actionClearLog">
<property name="text">
<action name="actionClearLog" >
<property name="text" >
<string>Clear log</string>
</property>
</action>
<action name="actionBugReport">
<property name="text">
<action name="actionBugReport" >
<property name="text" >
<string>Report a bug</string>
</property>
</action>
<action name="actionSet_upload_limit">
<property name="text">
<action name="actionSet_upload_limit" >
<property name="text" >
<string>Set upload limit</string>
</property>
</action>
<action name="actionSet_download_limit">
<property name="text">
<action name="actionSet_download_limit" >
<property name="text" >
<string>Set download limit</string>
</property>
</action>
<action name="actionDocumentation">
<property name="text">
<action name="actionDocumentation" >
<property name="text" >
<string>Documentation</string>
</property>
</action>
<action name="actionSet_global_download_limit">
<property name="text">
<action name="actionSet_global_download_limit" >
<property name="text" >
<string>Set global download limit</string>
</property>
</action>
<action name="actionSet_global_upload_limit">
<property name="text">
<action name="actionSet_global_upload_limit" >
<property name="text" >
<string>Set global upload limit</string>
</property>
</action>
<action name="actionDecreasePriority">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/skin/decrease.png</normaloff>:/Icons/skin/decrease.png</iconset>
<action name="actionDecreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/decrease.png</iconset>
</property>
<property name="text">
<property name="text" >
<string>Decrease priority</string>
</property>
<property name="visible">
<property name="visible" >
<bool>false</bool>
</property>
</action>
<action name="actionIncreasePriority">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/skin/increase.png</normaloff>:/Icons/skin/increase.png</iconset>
<action name="actionIncreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/increase.png</iconset>
</property>
<property name="text">
<property name="text" >
<string>Increase priority</string>
</property>
<property name="visible">
<property name="visible" >
<bool>false</bool>
</property>
</action>
<action name="actionShow_console">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/log.png</normaloff>:/Icons/oxygen/log.png</iconset>
<action name="actionShow_console" >
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/log.png</iconset>
</property>
<property name="text">
<property name="text" >
<string>Console</string>
</property>
</action>
</widget>
<resources>
<include location="icons.qrc"/>
<include location="icons.qrc" />
</resources>
<connections/>
</ui>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<ui version="4.0" >
<author>Christophe Dumez</author>
<class>AboutDlg</class>
<widget class="QDialog" name="AboutDlg">
<property name="geometry">
<widget class="QDialog" name="AboutDlg" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
@@ -11,65 +10,65 @@
<height>320</height>
</rect>
</property>
<property name="minimumSize">
<property name="minimumSize" >
<size>
<width>504</width>
<height>320</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>504</width>
<height>320</height>
</size>
</property>
<property name="windowTitle">
<property name="windowTitle" >
<string>About qBittorrent</string>
</property>
<layout class="QVBoxLayout">
<layout class="QVBoxLayout" >
<item>
<layout class="QHBoxLayout">
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="logo">
<property name="minimumSize">
<widget class="QLabel" name="logo" >
<property name="minimumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<property name="text" >
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lb_name">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<widget class="QLabel" name="lb_name" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;h3&gt;&lt;b&gt;qBittorrent&lt;/b&gt;&lt;/h3&gt;</string>
<property name="text" >
<string>&lt;h3>&lt;b>qBittorrent&lt;/b>&lt;/h3></string>
</property>
<property name="textFormat">
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -80,90 +79,79 @@
</layout>
</item>
<item>
<widget class="QTabWidget" name="tw_tabs">
<property name="currentIndex">
<widget class="QTabWidget" name="tw_tabs" >
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="tab2">
<attribute name="title">
<widget class="QWidget" name="tab2" >
<attribute name="title" >
<string>About</string>
</attribute>
<widget class="QLabel" name="mascot_lbl">
<property name="geometry">
<widget class="QLabel" name="mascot_lbl" >
<property name="geometry" >
<rect>
<x>380</x>
<y>70</y>
<y>50</y>
<width>94</width>
<height>162</height>
</rect>
</property>
<property name="text">
<property name="text" >
<string/>
</property>
</widget>
<widget class="QLabel" name="lb_about">
<property name="geometry">
<widget class="QLabel" name="lb_about" >
<property name="geometry" >
<rect>
<x>0</x>
<y>30</y>
<y>40</y>
<width>481</width>
<height>102</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A Bittorrent client programmed in C++, based on Qt4 toolkit &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and libtorrent-rasterbar. &lt;br /&gt;&lt;br /&gt;Copyright ©2006-2009 Christophe Dumez&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;Home Page:&lt;/span&gt; &lt;a href=&quot;http://www.qbittorrent.org&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;http://www.qbittorrent.org&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<property name="text" >
<string>A bittorrent client using Qt4 and libtorrent, programmed in C++.&lt;br>
&lt;br>
Copyright © 2006 by Christophe Dumez&lt;br>
&lt;br> &lt;u>Home Page:&lt;/u> &lt;i>http://www.qbittorrent.org&lt;/i>&lt;br></string>
</property>
<property name="textFormat">
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab3">
<attribute name="title">
<widget class="QWidget" name="tab3" >
<attribute name="title" >
<string>Author</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QFrame" name="te_authors">
<layout class="QHBoxLayout">
<property name="spacing">
<widget class="QFrame" name="te_authors" >
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<property name="sizeType" >
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
@@ -172,13 +160,13 @@ p, li { white-space: pre-wrap; }
</spacer>
</item>
<item>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<widget class="QLabel" name="label_3" >
<property name="font" >
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
@@ -189,14 +177,14 @@ p, li { white-space: pre-wrap; }
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<property name="text" >
<string>Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="font">
<widget class="QLabel" name="label_4" >
<property name="font" >
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
@@ -207,14 +195,14 @@ p, li { white-space: pre-wrap; }
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<property name="text" >
<string>Country:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_birthday">
<property name="font">
<widget class="QLabel" name="lbl_birthday" >
<property name="font" >
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
@@ -225,14 +213,14 @@ p, li { white-space: pre-wrap; }
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<property name="text" >
<string>Birthday:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_occupation">
<property name="font">
<widget class="QLabel" name="lbl_occupation" >
<property name="font" >
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
@@ -243,14 +231,14 @@ p, li { white-space: pre-wrap; }
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<property name="text" >
<string>Occupation:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="font">
<widget class="QLabel" name="label_5" >
<property name="font" >
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
@@ -261,14 +249,14 @@ p, li { white-space: pre-wrap; }
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<property name="text" >
<string>E-mail:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="font">
<widget class="QLabel" name="label_8" >
<property name="font" >
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
@@ -279,7 +267,7 @@ p, li { white-space: pre-wrap; }
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<property name="text" >
<string>Home page:</string>
</property>
</widget>
@@ -288,13 +276,13 @@ p, li { white-space: pre-wrap; }
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<property name="sizeType" >
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
@@ -303,48 +291,48 @@ p, li { white-space: pre-wrap; }
</spacer>
</item>
<item>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Christophe Dumez</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<widget class="QLabel" name="label_7" >
<property name="text" >
<string>France</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<widget class="QLabel" name="label_11" >
<property name="text" >
<string>03/05/1985</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<widget class="QLabel" name="label_10" >
<property name="text" >
<string>Student in computer science</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<widget class="QLabel" name="label_6" >
<property name="text" >
<string>chris@qbittorrent.org</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<widget class="QLabel" name="label_9" >
<property name="text" >
<string>http://www.dchris.eu</string>
</property>
</widget>
@@ -353,10 +341,10 @@ p, li { white-space: pre-wrap; }
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -369,46 +357,46 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</widget>
<widget class="QWidget" name="tab4">
<attribute name="title">
<widget class="QWidget" name="tab4" >
<attribute name="title" >
<string>Thanks to</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QTextBrowser" name="te_thanks"/>
<widget class="QTextBrowser" name="te_thanks" />
</item>
</layout>
</widget>
<widget class="QWidget" name="tab5">
<attribute name="title">
<widget class="QWidget" name="tab5" >
<attribute name="title" >
<string>Translation</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QTextBrowser" name="te_translation">
<property name="lineWrapMode">
<widget class="QTextBrowser" name="te_translation" >
<property name="lineWrapMode" >
<enum>QTextEdit::NoWrap</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab1">
<attribute name="title">
<widget class="QWidget" name="tab1" >
<attribute name="title" >
<string>License</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QTextBrowser" name="te_license"/>
<widget class="QTextBrowser" name="te_license" />
</item>
</layout>
</widget>
@@ -416,7 +404,7 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<layoutdefault spacing="6" margin="11" />
<resources/>
<connections/>
</ui>

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
@@ -46,8 +37,8 @@ class about : public QDialog, private Ui::AboutDlg{
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
// Set icons
logo->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/qbittorrent22.png")));
mascot_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/mascot.png")));
logo->setPixmap(QPixmap(QString::fromUtf8(":/Icons/qbittorrent22.png")));
mascot_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/mascot.png")));
//Title
lb_name->setText(QString::fromUtf8("<b><h1>")+tr("qBittorrent")+QString::fromUtf8(" "VERSION"</h1></b>"));
// Thanks
@@ -70,7 +61,7 @@ class about : public QDialog, private Ui::AboutDlg{
- <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\
- <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\
- <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net) and Peter Koeleman (peter@peerweb.nl)<br>\
- <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net) and Pekka Niemi (pekka.niemi@iki.fi)<br>\
- <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net)<br>\
- <u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\
- <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\
- <u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)<br>\
@@ -91,19 +82,7 @@ class about : public QDialog, private Ui::AboutDlg{
te_translation->scrollToAnchor(QString::fromUtf8("top"));
// License
te_license->append(QString::fromUtf8("<a name='top'></a>"));
te_license->append(QString::fromUtf8("qBittorrent is licensed under the GNU General Public License version 2 with the\
addition of the following special exception:\
<br><br>\
<i>In addition, as a special exception, the copyright holders give permission to\
link this program with the OpenSSL project\'s \"OpenSSL\" library (or with\
modified versions of it that use the same license as the \"OpenSSL\" library),\
and distribute the linked executables. You must obey the GNU General Public\
License in all respects for all of the code used other than \"OpenSSL\". If you\
modify file(s), you may extend this exception to your version of the file(s),\
but you are not obligated to do so. If you do not wish to do so, delete this\
exception statement from your version.</i>\
<br><br>\
<center><b>GNU GENERAL PUBLIC LICENSE</b></center><br>\
te_license->append(QString::fromUtf8("<center><b>GNU GENERAL PUBLIC LICENSE</b></center><br>\
<center>Version 2, June 1991</center><br>\
Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br>\
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA<br>\

View File

@@ -1,60 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<ui version="4.0" >
<class>addTorrentDialog</class>
<widget class="QDialog" name="addTorrentDialog">
<property name="geometry">
<widget class="QDialog" name="addTorrentDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>511</width>
<height>461</height>
<height>441</height>
</rect>
</property>
<property name="windowTitle">
<property name="windowTitle" >
<string>Torrent addition dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="fileNameLbl">
<property name="text">
<widget class="QLabel" name="fileNameLbl" >
<property name="text" >
<string/>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<widget class="Line" name="line" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="savePathLbl">
<property name="font">
<widget class="QLabel" name="savePathLbl" >
<property name="font" >
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<property name="text" >
<string>Save path:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="savePathTxt"/>
<widget class="QLineEdit" name="savePathTxt" />
</item>
<item>
<widget class="QToolButton" name="browseButton">
<property name="text">
<widget class="QToolButton" name="browseButton" >
<property name="text" >
<string>...</string>
</property>
</widget>
@@ -62,108 +70,39 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Torrent size:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_torrent_size">
<property name="text">
<string>Unknown</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Free disk space:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_disk_space">
<property name="text">
<string>Unknown</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_space_msg">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<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>
<item>
<widget class="QLabel" name="torrentContentLbl">
<property name="font">
<widget class="QLabel" name="torrentContentLbl" >
<property name="font" >
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<property name="text" >
<string>Torrent content:</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="torrentContentList">
<property name="contextMenuPolicy">
<widget class="QTreeView" name="torrentContentList" >
<property name="contextMenuPolicy" >
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="editTriggers">
<property name="editTriggers" >
<set>QAbstractItemView::AllEditTriggers</set>
</property>
<property name="selectionMode">
<property name="selectionMode" >
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -172,25 +111,25 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="collapseAllButton">
<property name="text">
<widget class="QPushButton" name="collapseAllButton" >
<property name="text" >
<string>Collapse all</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandAllButton">
<property name="text">
<widget class="QPushButton" name="expandAllButton" >
<property name="text" >
<string>Expand all</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -201,33 +140,42 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkIncrementalDL">
<property name="text">
<string>Download in sequential order (slower but good for previewing)</string>
<widget class="QCheckBox" name="checkIncrementalDL" >
<property name="text" >
<string>Download in correct order (slower but good for previewing)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="addInPause">
<property name="text">
<widget class="QCheckBox" name="addInPause" >
<property name="text" >
<string>Add to download list in paused state</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -236,25 +184,25 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="OkButton">
<property name="text">
<widget class="QPushButton" name="OkButton" >
<property name="text" >
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="CancelButton">
<property name="text">
<widget class="QPushButton" name="CancelButton" >
<property name="text" >
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -265,23 +213,23 @@
</layout>
</item>
</layout>
<action name="actionIgnored">
<property name="text">
<action name="actionIgnored" >
<property name="text" >
<string>Ignored</string>
</property>
</action>
<action name="actionNormal">
<property name="text">
<action name="actionNormal" >
<property name="text" >
<string>Normal</string>
</property>
</action>
<action name="actionHigh">
<property name="text">
<action name="actionHigh" >
<property name="text" >
<string>High</string>
</property>
</action>
<action name="actionMaximum">
<property name="text">
<action name="actionMaximum" >
<property name="text" >
<string>Maximum</string>
</property>
</action>

View File

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

View File

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

View File

@@ -16,20 +16,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include <QDir>
#include <QDateTime>
#include <QTime>
#include <QString>
#include <QTimer>
#include <QFileSystemWatcher>
@@ -40,7 +31,6 @@
#include "misc.h"
#include "downloadThread.h"
#include "filterParserThread.h"
#include "torrentPersistentData.h"
#include <libtorrent/extensions/ut_metadata.hpp>
#include <libtorrent/extensions/ut_pex.hpp>
#include <libtorrent/extensions/smart_ban.hpp>
@@ -53,17 +43,16 @@
#include <boost/filesystem/exception.hpp>
#define MAX_TRACKER_ERRORS 2
#define MAX_RATIO 100.
// Main constructor
bittorrent::bittorrent() : DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), ratio_limit(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), queueingEnabled(false) {
bittorrent::bittorrent() : DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), queueingEnabled(false) {
// To avoid some exceptions
fs::path::default_name_check(fs::no_check);
// 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("UT", 1, 8, 3, 0), 0);
s = new session(fingerprint("AZ", 3, 0, 5, 2), 0);
} else {
s = new session(fingerprint("qB", VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, 0), 0);
}
@@ -126,7 +115,7 @@ void bittorrent::preAllocateAllFiles(bool b) {
}
void bittorrent::deleteBigRatios() {
if(ratio_limit == -1) return;
if(max_ratio == -1) return;
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
@@ -134,8 +123,7 @@ void bittorrent::deleteBigRatios() {
if(!h.is_valid()) continue;
if(h.is_seed()) {
QString hash = h.hash();
float ratio = getRealRatio(hash);
if(ratio <= MAX_RATIO && ratio > ratio_limit) {
if(getRealRatio(hash) > max_ratio) {
QString fileName = h.name();
addConsoleMessage(tr("%1 reached the maximum ratio you set.").arg(fileName));
deleteTorrent(hash);
@@ -179,12 +167,6 @@ void bittorrent::setUploadLimit(QString hash, long val) {
void bittorrent::handleDownloadFailure(QString url, QString reason) {
emit downloadFromUrlFailure(url, reason);
// Clean up
int index = url_skippingDlg.indexOf(url);
if(index >= 0)
url_skippingDlg.removeAt(index);
if(savepath_fromurl.contains(url))
savepath_fromurl.remove(url);
}
void bittorrent::startTorrentsInPause(bool b) {
@@ -267,7 +249,7 @@ unsigned int bittorrent::getUnfinishedPausedTorrentsNb() const {
// Delete a torrent from the session, given its hash
// permanent = true means that the torrent will be removed from the hard-drive too
void bittorrent::deleteTorrent(QString hash, bool permanent) {
qDebug("Deleting torrent with hash: %s", hash.toLocal8Bit().data());
qDebug("Deleting torrent with hash: %s", hash.toUtf8().data());
QTorrentHandle h = getTorrentHandle(hash);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
@@ -285,10 +267,10 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
QStringList filters;
filters << hash+".*";
QStringList files = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted);
foreach(const QString &file, files) {
QString file;
foreach(file, files) {
torrentBackup.remove(file);
}
TorrentPersistentData::deletePersistentData(hash);
// Remove tracker errors
trackersErrors.remove(hash);
if(permanent)
@@ -341,23 +323,28 @@ void bittorrent::resumeTorrent(QString hash) {
}
void bittorrent::loadWebSeeds(QString hash) {
QVariantList url_seeds = TorrentPersistentData::getUrlSeeds(hash);
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
QByteArray urlseeds_lines = urlseeds_file.readAll();
urlseeds_file.close();
QList<QByteArray> url_seeds = urlseeds_lines.split('\n');
QByteArray url_seed;
QTorrentHandle h = getTorrentHandle(hash);
// First remove from the torrent the url seeds that were deleted
// in a previous session
QStringList seeds_to_delete;
QStringList existing_seeds = h.url_seeds();
foreach(const QString &existing_seed, existing_seeds) {
if(!url_seeds.contains(existing_seed.toLocal8Bit())) {
QString existing_seed;
foreach(existing_seed, existing_seeds) {
if(!url_seeds.contains(existing_seed.toUtf8())) {
seeds_to_delete << existing_seed;
}
}
foreach(const QString &existing_seed, seeds_to_delete) {
foreach(existing_seed, seeds_to_delete) {
h.remove_url_seed(existing_seed);
}
// Add the ones that were added in a previous session
foreach(const QVariant &var_url_seed, url_seeds) {
QString url_seed = var_url_seed.toString();
foreach(url_seed, url_seeds) {
if(!url_seed.isEmpty()) {
// XXX: Should we check if it is already in the list before adding it
// or is libtorrent clever enough to know
@@ -366,136 +353,18 @@ void bittorrent::loadWebSeeds(QString hash) {
}
}
QTorrentHandle bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
QTorrentHandle h;
QString hash = misc::magnetUriToHash(magnet_uri);
if(hash.isEmpty()) {
addConsoleMessage(tr("'%1' is not a valid magnet URI.").arg(magnet_uri));
return h;
}
if(resumed) {
qDebug("Resuming magnet URI: %s", hash.toLocal8Bit().data());
} else {
qDebug("Adding new magnet URI");
}
bool fastResume=false;
Q_ASSERT(magnet_uri.startsWith("magnet:"));
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
// Checking if BT_backup Dir exists
// create it if it is not
if(! torrentBackup.exists()) {
if(! torrentBackup.mkpath(torrentBackup.path())) {
std::cerr << "Couldn't create the directory: '" << torrentBackup.path().toLocal8Bit().data() << "'\n";
exit(1);
}
}
// Check if torrent is already in download list
if(s->find_torrent(sha1_hash(hash.toLocal8Bit().data())).is_valid()) {
qDebug("/!\\ Torrent is already in download list");
// Update info Bar
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(magnet_uri));
return h;
}
add_torrent_params p;
//Getting fast resume data if existing
std::vector<char> buf;
if(resumed) {
qDebug("Trying to load fastresume data: %s", (torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data());
if (load_file((torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data(), buf) == 0) {
fastResume = true;
p.resume_data = &buf;
qDebug("Successfuly loaded");
}
}
QString savePath = getSavePath(hash);
qDebug("addMagnetURI: using save_path: %s", savePath.toLocal8Bit().data());
if(defaultTempPath.isEmpty() || (resumed && TorrentPersistentData::isSeed(hash))) {
p.save_path = savePath.toLocal8Bit().data();
} else {
p.save_path = defaultTempPath.toLocal8Bit().data();
}
// Preallocate all?
if(preAllocateAll)
p.storage_mode = storage_mode_allocate;
else
p.storage_mode = storage_mode_sparse;
// Start in pause
p.paused = false;
p.duplicate_is_error = false; // Already checked
p.auto_managed = false; // Because it is added in paused state
// Adding torrent to bittorrent session
try {
h = QTorrentHandle(add_magnet_uri(*s, magnet_uri.toStdString(), p));
}catch(std::exception e){
qDebug("Error: %s", e.what());
}
// Check if it worked
if(!h.is_valid()) {
// No need to keep on, it failed.
qDebug("/!\\ Error: Invalid handle");
return h;
}
Q_ASSERT(h.hash() == hash);
// Connections limit per torrent
h.set_max_connections(maxConnecsPerTorrent);
// Uploads limit per torrent
h.set_max_uploads(maxUploadsPerTorrent);
// Load filtered files
if(resumed) {
// Load custom url seeds
loadWebSeeds(hash);
// Load speed limit from hard drive
loadTorrentSpeedLimits(hash);
// Load trackers
loadTrackerFile(hash);
// XXX: only when resuming because torrentAddition dialog is not supported yet
loadFilesPriorities(h);
} else {
// Sequential download
if(TorrentTempData::hasTempData(hash)) {
qDebug("addMagnetUri: Setting download as sequential (from tmp data)");
h.set_sequential_download(TorrentTempData::isSequential(hash));
}
// Save persistent data for new torrent
Q_ASSERT(h.is_valid());
qDebug("addMagnetUri: hash: %s", h.hash().toLocal8Bit().data());
TorrentPersistentData::saveTorrentPersistentData(h, true);
qDebug("Persistent data saved");
// Save save_path
if(!defaultTempPath.isEmpty()) {
qDebug("addMagnetUri: Saving save_path in persistent data: %s", savePath.toLocal8Bit().data());
TorrentPersistentData::saveSavePath(hash, savePath);
}
}
if(!addInPause && !fastResume) {
// Start torrent because it was added in paused state
h.resume();
}
// Send torrent addition signal
if(fastResume)
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(magnet_uri));
else
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(magnet_uri));
emit addedTorrent(h);
return h;
}
// Add a torrent to the bittorrent session
QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) {
QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool) {
QTorrentHandle h;
bool fastResume=false;
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QString file, dest_file, hash;
boost::intrusive_ptr<torrent_info> t;
QString file, dest_file;
// Checking if BT_backup Dir exists
// create it if it is not
if(! torrentBackup.exists()) {
if(! torrentBackup.mkpath(torrentBackup.path())) {
std::cerr << "Couldn't create the directory: '" << torrentBackup.path().toLocal8Bit().data() << "'\n";
std::cerr << "Couldn't create the directory: '" << torrentBackup.path().toUtf8().data() << "'\n";
exit(1);
}
}
@@ -505,11 +374,11 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
return h;
}
Q_ASSERT(!file.startsWith("http://", Qt::CaseInsensitive) && !file.startsWith("https://", Qt::CaseInsensitive) && !file.startsWith("ftp://", Qt::CaseInsensitive));
qDebug("Adding %s to download list", file.toLocal8Bit().data());
qDebug("Adding %s to download list", file.toUtf8().data());
boost::intrusive_ptr<torrent_info> t;
try {
// Getting torrent file informations
t = new torrent_info(file.toLocal8Bit().data());
t = new torrent_info(file.toUtf8().data());
} catch(std::exception&) {
if(!from_url.isNull()) {
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
@@ -528,8 +397,14 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
}
qDebug(" -> Hash: %s", misc::toString(t->info_hash()).c_str());
qDebug(" -> Name: %s", t->name().c_str());
hash = misc::toQString(t->info_hash());
QString hash = misc::toQString(t->info_hash());
if(file.startsWith(torrentBackup.path())) {
QFileInfo fi(file);
QString old_hash = fi.baseName();
if(old_hash != hash){
qDebug("* ERROR: Strange, hash changed from %s to %s", old_hash.toUtf8().data(), hash.toUtf8().data());
}
}
// Check if torrent is already in download list
if(s->find_torrent(t->info_hash()).is_valid()) {
qDebug("/!\\ Torrent is already in download list");
@@ -553,27 +428,21 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
add_torrent_params p;
//Getting fast resume data if existing
std::vector<char> buf;
if(resumed) {
qDebug("Trying to load fastresume data: %s", (torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data());
if (load_file((torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data(), buf) == 0) {
qDebug("Trying to load fastresume data: %s", (torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toUtf8().data());
if (load_file((torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toUtf8().data(), buf) == 0) {
fastResume = true;
p.resume_data = &buf;
qDebug("Successfuly loaded");
}
QString savePath = getSavePath(hash);
// Save save_path to hard drive
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
if(!savepath_file.exists()) {
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
savepath_file.write(savePath.toUtf8());
savepath_file.close();
}
QString savePath;
if(!from_url.isEmpty() && savepath_fromurl.contains(from_url)) {
// Enforcing the save path defined before URL download (from RSS for example)
savePath = savepath_fromurl.take(from_url);
} else {
savePath = getSavePath(hash);
}
qDebug("addTorrent: using save_path: %s", savePath.toLocal8Bit().data());
if(defaultTempPath.isEmpty() || (resumed && TorrentPersistentData::isSeed(hash))) {
p.save_path = savePath.toLocal8Bit().data();
} else {
p.save_path = defaultTempPath.toLocal8Bit().data();
}
p.save_path = savePath.toUtf8().data();
p.ti = t;
// Preallocate all?
if(preAllocateAll)
@@ -604,26 +473,16 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
h.set_max_uploads(maxUploadsPerTorrent);
// Load filtered files
loadFilesPriorities(h);
if(resumed) {
// Load custom url seeds
loadWebSeeds(hash);
// Load speed limit from hard drive
loadTorrentSpeedLimits(hash);
// Load trackers
bool loaded_trackers = loadTrackerFile(hash);
// Doing this to order trackers well
if(!loaded_trackers) {
saveTrackerFile(hash);
loadTrackerFile(hash);
} else {
// Sequential download
if(TorrentTempData::hasTempData(hash)) {
qDebug("addTorrent: Setting download as sequential (from tmp data)");
h.set_sequential_download(TorrentTempData::isSequential(hash));
}
// Save persistent data for new torrent
TorrentPersistentData::saveTorrentPersistentData(h);
// Save save_path
if(!defaultTempPath.isEmpty()) {
qDebug("addTorrent: Saving save_path in persistent data: %s", savePath.toLocal8Bit().data());
TorrentPersistentData::saveSavePath(hash, savePath);
}
}
QString newFile = torrentBackup.path() + QDir::separator() + hash + ".torrent";
if(file != newFile) {
@@ -633,6 +492,11 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
// Copy it to torrentBackup directory
QFile::copy(file, newFile);
}
// Incremental download
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")) {
qDebug("Incremental download enabled for %s", t->name().c_str());
h.set_sequential_download(true);
}
if(!addInPause && !fastResume) {
// Start torrent because it was added in paused state
h.resume();
@@ -659,17 +523,27 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
return h;
}
// Check if the user filtered files in this torrent.
// Check in .priorities file if the user filtered files
// in this torrent.
bool bittorrent::has_filtered_files(QString hash) const{
QVariantList files_priority = TorrentPersistentData::getFilesPriority(hash);
foreach(QVariant var_prio, files_priority) {
int priority = var_prio.toInt();
QFile pieces_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".priorities");
// Read saved file
if(!pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false;
}
QByteArray pieces_text = pieces_file.readAll();
pieces_file.close();
QList<QByteArray> pieces_priorities_list = pieces_text.split('\n');
unsigned int listSize = pieces_priorities_list.size();
for(unsigned int i=0; i<listSize-1; ++i) {
int priority = pieces_priorities_list.at(i).toInt();
if( priority < 0 || priority > 7) {
priority = 1;
}
if(!priority)
if(!priority) {
return true;
}
}
return false;
}
@@ -762,7 +636,7 @@ void bittorrent::enableLSD(bool b) {
}
void bittorrent::loadSessionState() {
boost::filesystem::ifstream ses_state_file((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
boost::filesystem::ifstream ses_state_file((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toUtf8().data()
, std::ios_base::binary);
ses_state_file.unsetf(std::ios_base::skipws);
s->load_state(bdecode(
@@ -773,7 +647,7 @@ void bittorrent::loadSessionState() {
void bittorrent::saveSessionState() {
qDebug("Saving session state to disk...");
entry session_state = s->state();
boost::filesystem::ofstream out((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toLocal8Bit().data()
boost::filesystem::ofstream out((misc::qBittorrentPath()+QString::fromUtf8("ses_state")).toUtf8().data()
, std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), session_state);
@@ -786,7 +660,7 @@ bool bittorrent::enableDHT(bool b) {
entry dht_state;
QString dht_state_path = misc::qBittorrentPath()+QString::fromUtf8("dht_state");
if(QFile::exists(dht_state_path)) {
boost::filesystem::ifstream dht_state_file(dht_state_path.toLocal8Bit().data(), std::ios_base::binary);
boost::filesystem::ifstream dht_state_file(dht_state_path.toUtf8().data(), std::ios_base::binary);
dht_state_file.unsetf(std::ios_base::skipws);
try{
dht_state = bdecode(std::istream_iterator<char>(dht_state_file), std::istream_iterator<char>());
@@ -815,13 +689,13 @@ bool bittorrent::enableDHT(bool b) {
}
void bittorrent::saveTorrentSpeedLimits(QString hash) {
qDebug("Saving speedLimits file for %s", hash.toLocal8Bit().data());
qDebug("Saving speedLimits file for %s", hash.toUtf8().data());
QTorrentHandle h = getTorrentHandle(hash);
int download_limit = h.download_limit();
int upload_limit = h.upload_limit();
QFile speeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".speedLimits");
if(!speeds_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug("* Error: Couldn't open speed limits file for torrent: %s", hash.toLocal8Bit().data());
qDebug("* Error: Couldn't open speed limits file for torrent: %s", hash.toUtf8().data());
return;
}
speeds_file.write(misc::toQByteArray(download_limit)+QByteArray(" ")+misc::toQByteArray(upload_limit));
@@ -829,7 +703,7 @@ void bittorrent::saveTorrentSpeedLimits(QString hash) {
}
void bittorrent::loadTorrentSpeedLimits(QString hash) {
// qDebug("Loading speedLimits file for %s", hash.toLocal8Bit().data());
// qDebug("Loading speedLimits file for %s", hash.toUtf8().data());
QTorrentHandle h = getTorrentHandle(hash);
QFile speeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".speedLimits");
if(!speeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -846,27 +720,39 @@ void bittorrent::loadTorrentSpeedLimits(QString hash) {
h.set_upload_limit(speeds.at(1).toInt());
}
// Read pieces priorities from hard disk
// Read pieces priorities from .priorities file
// and ask QTorrentHandle to consider them
void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
qDebug("Applying files priority");
qDebug("Applying pieces priorities");
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
return;
}
std::vector<int> v;
QVariantList files_priority;
if(TorrentTempData::hasTempData(h.hash())) {
files_priority = TorrentTempData::getFilesPriority(h.hash());
} else {
files_priority = TorrentPersistentData::getFilesPriority(h.hash());
unsigned int nbFiles = h.num_files();
QString hash = h.hash();
QFile pieces_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".priorities");
if(!pieces_file.exists()){
return;
}
foreach(const QVariant &var_prio, files_priority) {
int priority = var_prio.toInt();
// Read saved file
if(!pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug("* Error: Couldn't open priorities file: %s", hash.toUtf8().data());
return;
}
QByteArray pieces_priorities = pieces_file.readAll();
pieces_file.close();
QList<QByteArray> pieces_priorities_list = pieces_priorities.split('\n');
if((unsigned int)pieces_priorities_list.size() != nbFiles+1) {
std::cerr << "* Error: Corrupted priorities file\n";
return;
}
std::vector<int> v;
for(unsigned int i=0; i<nbFiles; ++i) {
int priority = pieces_priorities_list.at(i).toInt();
if( priority < 0 || priority > 7) {
priority = 1;
}
qDebug("Setting file piority to %d", priority);
qDebug("Setting piece piority to %d", priority);
v.push_back(priority);
}
h.prioritize_files(v);
@@ -878,13 +764,13 @@ float bittorrent::getRealRatio(QString hash) const{
Q_ASSERT(h.all_time_upload() >= 0);
if(h.all_time_download() == 0) {
if(h.all_time_upload() == 0)
return 0;
return 101;
return 1.;
return 10.;
}
float ratio = (float)h.all_time_upload()/(float)h.all_time_download();
Q_ASSERT(ratio >= 0.);
if(ratio > 100.)
ratio = 100.;
if(ratio > 10.)
ratio = 10.;
return ratio;
}
@@ -902,7 +788,7 @@ void bittorrent::saveFastResumeData() {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if(!h.is_valid() || !h.has_metadata()) continue;
if(isQueueingEnabled())
TorrentPersistentData::savePriority(h);
saveTorrentPriority(h.hash(), h.queue_position());
if(h.is_paused()) continue;
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) continue;
h.save_resume_data();
@@ -937,7 +823,7 @@ void bittorrent::saveFastResumeData() {
// Remove old fastresume file if it exists
QFile::remove(torrentBackup.path()+QDir::separator()+ h.hash() + ".fastresume");
QString file = h.hash()+".fastresume";
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toLocal8Bit().data()) / file.toLocal8Bit().data(), std::ios_base::binary);
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toUtf8().data()) / file.toUtf8().data(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), *rd->resume_data);
// Remove torrent from session
@@ -958,7 +844,7 @@ void bittorrent::addConsoleMessage(QString msg, QColor color) {
if(consoleMessages.size() > 100) {
consoleMessages.removeFirst();
}
consoleMessages.append(QString::fromUtf8("<font color='grey'>")+ QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + msg + QString::fromUtf8("</i></font>"));
consoleMessages.append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + msg + QString::fromUtf8("</i></font>"));
}
void bittorrent::addPeerBanMessage(QString ip, bool from_ipfilter) {
@@ -966,9 +852,9 @@ void bittorrent::addPeerBanMessage(QString ip, bool from_ipfilter) {
peerBanMessages.removeFirst();
}
if(from_ipfilter)
peerBanMessages.append(QString::fromUtf8("<font color='grey'>")+ QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + QString::fromUtf8("</font> - ")+tr("<font color='red'>%1</font> <i>was blocked due to your IP filter</i>", "x.y.z.w was blocked").arg(ip));
peerBanMessages.append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - ")+tr("<font color='red'>%1</font> <i>was blocked due to your IP filter</i>", "x.y.z.w was blocked").arg(ip));
else
peerBanMessages.append(QString::fromUtf8("<font color='grey'>")+ QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + QString::fromUtf8("</font> - ")+tr("<font color='red'>%1</font> <i>was banned due to corrupt pieces</i>", "x.y.z.w was banned").arg(ip));
peerBanMessages.append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - ")+tr("<font color='red'>%1</font> <i>was banned due to corrupt pieces</i>", "x.y.z.w was banned").arg(ip));
}
bool bittorrent::isFilePreviewPossible(QString hash) const{
@@ -992,19 +878,20 @@ bool bittorrent::isFilePreviewPossible(QString hash) const{
// and add them to download list
void bittorrent::scanDirectory(QString scan_dir) {
FSMutex->lock();
qDebug("Scanning directory: %s", scan_dir.toLocal8Bit().data());
qDebug("Scanning directory: %s", scan_dir.toUtf8().data());
QString file;
QDir dir(scan_dir);
QStringList filters;
filters << "*.torrent";
QStringList files = dir.entryList(filters, QDir::Files, QDir::Unsorted);
foreach(const QString &file, files) {
foreach(file, files) {
QString fullPath = dir.path()+QDir::separator()+file;
QFile torrent(fullPath);
if(torrent.size() != 0) {
qDebug("Adding for scan_dir: %s", fullPath.toLocal8Bit().data());
qDebug("Adding for scan_dir: %s", fullPath.toUtf8().data());
addTorrent(fullPath, true);
} else {
qDebug("Ignoring empty file: %s", fullPath.toLocal8Bit().data());
qDebug("Ignoring empty file: %s", fullPath.toUtf8().data());
}
}
FSMutex->unlock();
@@ -1014,45 +901,6 @@ void bittorrent::setDefaultSavePath(QString savepath) {
defaultSavePath = savepath;
}
QString bittorrent::getDefaultSavePath() const {
return defaultSavePath;
}
bool bittorrent::useTemporaryFolder() const {
return !defaultTempPath.isEmpty();
}
void bittorrent::setDefaultTempPath(QString temppath) {
if(defaultTempPath == temppath)
return;
if(temppath.isEmpty()) {
// Disabling temp dir
// Moving all torrents to their destination folder
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if(!h.is_valid()) continue;
h.move_storage(getSavePath(h.hash()));
}
} else {
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if(!h.is_valid()) continue;
if(!h.is_seed())
h.move_storage(temppath);
}
}
defaultTempPath = temppath;
}
void bittorrent::saveTrackerFile(QString hash) {
QTorrentHandle h = getTorrentHandle(hash);
TorrentPersistentData::saveTrackers(h);
}
// Enable directory scanning
void bittorrent::enableDirectoryScanning(QString scan_dir) {
if(!scan_dir.isEmpty()) {
@@ -1130,41 +978,67 @@ void bittorrent::setGlobalRatio(float ratio) {
// be automatically deleted
void bittorrent::setDeleteRatio(float ratio) {
if(ratio != -1 && ratio < 1.) ratio = 1.;
if(ratio_limit == -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(ratio_limit != -1 && ratio == -1) {
if(max_ratio != -1 && ratio == -1) {
delete BigRatioTimer;
}
}
if(ratio_limit != ratio) {
ratio_limit = ratio;
qDebug("* Set deleteRatio to %.1f", ratio_limit);
if(max_ratio != ratio) {
max_ratio = ratio;
qDebug("* Set deleteRatio to %.1f", max_ratio);
deleteBigRatios();
}
}
void bittorrent::loadTrackerFile(QString hash) {
QHash<QString, QVariant> tiers = TorrentPersistentData::getTrackers(hash);
bool bittorrent::loadTrackerFile(QString hash) {
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
if(!tracker_file.exists()) return false;
tracker_file.open(QIODevice::ReadOnly | QIODevice::Text);
QStringList lines = QString::fromUtf8(tracker_file.readAll().data()).split("\n");
std::vector<announce_entry> trackers;
foreach(const QString tracker_url, tiers.keys()) {
announce_entry t(tracker_url.toStdString());
t.tier = tiers[tracker_url].toInt();
QString line;
foreach(line, lines) {
QStringList parts = line.split("|");
if(parts.size() != 2) continue;
announce_entry t(parts[0].toStdString());
t.tier = parts[1].toInt();
trackers.push_back(t);
}
if(!trackers.empty()) {
QTorrentHandle h = getTorrentHandle(hash);
h.replace_trackers(trackers);
h.force_reannounce();
return true;
}else{
return false;
}
}
// Set DHT port (>= 1000 or 0 if same as BT)
void bittorrent::saveTrackerFile(QString hash) {
qDebug("Saving tracker file for %s", hash.toUtf8().data());
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
if(tracker_file.exists()) {
tracker_file.remove();
}
tracker_file.open(QIODevice::WriteOnly | QIODevice::Text);
QTorrentHandle h = getTorrentHandle(hash);
std::vector<announce_entry> trackers = h.trackers();
for(unsigned int i=0; i<trackers.size(); ++i) {
tracker_file.write(QByteArray(trackers[i].url.c_str())+QByteArray("|")+QByteArray(misc::toString(i).c_str())+QByteArray("\n"));
}
tracker_file.close();
}
// Set DHT port (>= 1000)
void bittorrent::setDHTPort(int dht_port) {
if(dht_port == 0 or dht_port >= 1000) {
if(dht_port >= 1000) {
struct dht_settings DHTSettings;
DHTSettings.service_port = dht_port;
s->set_dht_settings(DHTSettings);
@@ -1239,36 +1113,12 @@ void bittorrent::readAlerts() {
if(h.is_valid()){
emit finishedTorrent(h);
QString hash = h.hash();
// Remember finished state
TorrentPersistentData::saveSeedStatus(h);
// Move to download directory if necessary
if(!defaultTempPath.isEmpty()) {
// Check if directory is different
QDir current_dir(h.save_path());
QDir save_dir(getSavePath(h.hash()));
if(current_dir != save_dir) {
h.move_storage(save_dir.path());
}
}
// Create .finished file if necessary
QFile finished_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished");
finished_file.open(QIODevice::WriteOnly | QIODevice::Text);
finished_file.close();
h.save_resume_data();
// Check if there is a single torrent file inside
QString torrent_relpath = misc::toQString(h.get_torrent_info().file_at(0).path);
if(torrent_relpath.endsWith(".torrent")) {
addConsoleMessage(tr("Recursive download of file %1 embedded in torrent %2", "Recursive download of test.torrent embedded in torrent test2").arg(torrent_relpath).arg(h.name()));
QString torrent_fullpath = h.save_path()+QDir::separator()+torrent_relpath;
boost::intrusive_ptr<torrent_info> t;
try {
t = new torrent_info(torrent_fullpath.toLocal8Bit().data());
QString sub_hash = misc::toQString(t->info_hash());
// Passing the save path along to the sub torrent file
TorrentTempData::setSavePath(sub_hash, h.save_path());
addTorrent(torrent_fullpath);
} catch(std::exception&) {
qDebug("Caught error loading torrent");
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(torrent_fullpath), QString::fromUtf8("red"));
}
}
qDebug("Received finished alert for %s", h.name().toLocal8Bit().data());
qDebug("Received finished alert for %s", h.name().toUtf8().data());
}
}
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get())) {
@@ -1278,45 +1128,25 @@ void bittorrent::readAlerts() {
// Delete old fastresume file if necessary
if(QFile::exists(file))
QFile::remove(file);
qDebug("Saving fastresume data in %s", file.toLocal8Bit().data());
qDebug("Saving fastresume data in %s", file.toUtf8().data());
if (p->resume_data)
{
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toLocal8Bit().data()) / file.toLocal8Bit().data(), std::ios_base::binary);
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toUtf8().data()) / file.toUtf8().data(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), *p->resume_data);
}
}
else if (metadata_received_alert* p = dynamic_cast<metadata_received_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if(h.is_valid()) {
qDebug("Received metadata for %s", h.hash().toLocal8Bit().data());
emit metadataReceived(h);
if(h.is_paused()) {
// XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert
// and the torrent can be paused when metadata is received
emit torrentPaused(h);
}
}
}
else if (file_error_alert* p = dynamic_cast<file_error_alert*>(a.get())) {
QTorrentHandle h(p->handle);
h.auto_managed(false);
std::cerr << "File Error: " << p->message().c_str() << std::endl;
qDebug("File Error: %s", p->message().c_str());
if(h.is_valid())
emit fullDiskError(h, misc::toQString(p->message()));
emit fullDiskError(h);
}
else if (dynamic_cast<listen_failed_alert*>(a.get())) {
// Level: fatal
addConsoleMessage(tr("Couldn't listen on any of the given ports."), QString::fromUtf8("red"));
//emit portListeningFailure();
}
else if (torrent_paused_alert* p = dynamic_cast<torrent_paused_alert*>(a.get())) {
QTorrentHandle h(p->handle);
qDebug("Received a torrent_paused_alert for %s", h.hash().toLocal8Bit().data());
if(h.is_valid()) {
emit torrentPaused(h);
}
}
else if (tracker_error_alert* p = dynamic_cast<tracker_error_alert*>(a.get())) {
// Level: fatal
QTorrentHandle h(p->handle);
@@ -1337,7 +1167,7 @@ void bittorrent::readAlerts() {
else if (tracker_reply_alert* p = dynamic_cast<tracker_reply_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if(h.is_valid()){
qDebug("Received a tracker reply from %s", (const char*)h.current_tracker().toLocal8Bit());
qDebug("Received a tracker reply from %s", (const char*)h.current_tracker().toUtf8());
QString hash = h.hash();
QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>());
// p->url requires at least libtorrent v0.13.1
@@ -1365,7 +1195,7 @@ void bittorrent::readAlerts() {
else if (fastresume_rejected_alert* p = dynamic_cast<fastresume_rejected_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if(h.is_valid()){
qDebug("/!\\ Fast resume failed for %s, reason: %s", h.name().toLocal8Bit().data(), p->message().c_str());
qDebug("/!\\ Fast resume failed for %s, reason: %s", h.name().toUtf8().data(), p->message().c_str());
addConsoleMessage(tr("Fast resume data was rejected for torrent %1, checking again...").arg(h.name()), QString::fromUtf8("red"));
//emit fastResumeDataRejected(h.name());
}
@@ -1378,18 +1208,8 @@ void bittorrent::readAlerts() {
QTorrentHandle h(p->handle);
if(h.is_valid()){
QString hash = h.hash();
qDebug("%s have just finished checking", hash.toLocal8Bit().data());
// Move to temp directory if necessary
if(!h.is_seed() && !defaultTempPath.isEmpty()) {
// Check if directory is different
QDir current_dir(h.save_path());
QDir save_dir(getSavePath(h.hash()));
if(current_dir == save_dir) {
h.move_storage(defaultTempPath);
}
}
qDebug("%s have just finished checking", hash.toUtf8().data());
emit torrentFinishedChecking(h);
emit metadataReceived(h);
}
}
a = s->pop_alert();
@@ -1409,17 +1229,17 @@ session_status bittorrent::getSessionStatus() const{
}
QString bittorrent::getSavePath(QString hash) {
QFile savepath_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".savepath");
QByteArray line;
QString savePath;
if(TorrentTempData::hasTempData(hash)) {
savePath = TorrentTempData::getSavePath(hash);
qDebug("getSavePath, got save_path from temp data: %s", savePath.toLocal8Bit().data());
} else {
savePath = TorrentPersistentData::getSavePath(hash);
qDebug("getSavePath, got save_path from persistent data: %s", savePath.toLocal8Bit().data());
}
if(savePath.isEmpty()) {
// use default save path if no other can be found
qDebug("Using default save path because none was set: %s", defaultSavePath.toLocal8Bit().data());
if(savepath_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
line = savepath_file.readAll();
savepath_file.close();
qDebug(" -> Save path: %s", line.data());
savePath = QString::fromUtf8(line.data());
}else{
// use default save path
qDebug("Using default save path because none was set");
savePath = defaultSavePath;
}
// Checking if savePath Dir exists
@@ -1427,7 +1247,7 @@ QString bittorrent::getSavePath(QString hash) {
QDir saveDir(savePath);
if(!saveDir.exists()) {
if(!saveDir.mkpath(saveDir.path())) {
std::cerr << "Couldn't create the save directory: " << saveDir.path().toLocal8Bit().data() << "\n";
std::cerr << "Couldn't create the save directory: " << saveDir.path().toUtf8().data() << "\n";
// XXX: handle this better
return QDir::homePath();
}
@@ -1445,10 +1265,8 @@ void bittorrent::downloadFromUrl(QString url) {
downloader->downloadUrl(url);
}
void bittorrent::downloadUrlAndSkipDialog(QString url, QString save_path) {
void bittorrent::downloadUrlAndSkipDialog(QString url) {
//emit aboutToDownloadFromUrl(url);
if(!save_path.isEmpty())
savepath_fromurl[url] = save_path;
url_skippingDlg << url;
// Launch downloader thread
downloader->downloadUrl(url);
@@ -1466,6 +1284,14 @@ void bittorrent::processDownloadedFile(QString url, QString file_path) {
}
}
void bittorrent::downloadFromURLList(const QStringList& url_list) {
QString url;
qDebug("DownloadFromUrlList");
foreach(url, url_list) {
downloadFromUrl(url);
}
}
// Return current download rate for the BT
// session. Payload means that it only take into
// account "useful" part of the rate
@@ -1488,7 +1314,7 @@ void bittorrent::saveDHTEntry() {
if(DHTEnabled) {
try{
entry dht_state = s->dht_state();
boost::filesystem::ofstream out((misc::qBittorrentPath()+QString::fromUtf8("dht_state")).toLocal8Bit().data(), std::ios_base::binary);
boost::filesystem::ofstream out((misc::qBittorrentPath()+QString::fromUtf8("dht_state")).toUtf8().data(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), dht_state);
qDebug("DHT entry saved");
@@ -1503,44 +1329,57 @@ void bittorrent::applyEncryptionSettings(pe_settings se) {
s->set_pe_settings(se);
}
void bittorrent::saveTorrentPriority(QString hash, int prio) {
// Write .queued file
QFile prio_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".prio");
prio_file.open(QIODevice::WriteOnly | QIODevice::Text);
prio_file.write(QByteArray::number(prio));
prio_file.close();
}
// Will fast resume torrents in
// backup directory
void bittorrent::startUpTorrents() {
void bittorrent::resumeUnfinishedTorrents() {
qDebug("Resuming unfinished torrents");
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QStringList fileNames;
QStringList known_torrents = TorrentPersistentData::knownTorrents();
// Scan torrentBackup directory
QStringList filters;
filters << "*.torrent";
fileNames = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted);
if(isQueueingEnabled()) {
QList<QPair<int, QString> > hashes;
foreach(const QString &hash, known_torrents) {
QString filePath;
if(TorrentPersistentData::isMagnet(hash)) {
filePath = TorrentPersistentData::getMagnetUri(hash);
} else {
filePath = torrentBackup.path()+QDir::separator()+hash+".torrent";
QList<QPair<int, QString> > filePaths;
foreach(QString fileName, fileNames) {
QString filePath = torrentBackup.path()+QDir::separator()+fileName;
int prio = 99999;
// Get priority
QString prioPath = filePath;
prioPath.replace(".torrent", ".prio");
if(QFile::exists(prioPath)) {
QFile prio_file(prioPath);
if(prio_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
bool ok = false;
prio = prio_file.readAll().toInt(&ok);
if(!ok)
prio = 99999;
prio_file.close();
}
int prio = TorrentPersistentData::getPriority(hash);
misc::insertSort2<QString>(hashes, qMakePair(prio, hash));
}
misc::insertSort2<QString>(filePaths, qMakePair(prio, filePath));
}
// Resume downloads
QPair<int, QString> couple;
foreach(couple, hashes) {
QString hash = couple.second;
qDebug("Starting up torrent %s", hash.toLocal8Bit().data());
if(TorrentPersistentData::isMagnet(hash)) {
addMagnetUri(TorrentPersistentData::getMagnetUri(hash), true);
} else {
addTorrent(torrentBackup.path()+QDir::separator()+hash+".torrent", false, QString(), true);
}
QPair<int, QString> fileName;
foreach(fileName, filePaths) {
addTorrent(fileName.second, false, QString(), true);
}
} else {
QStringList filePaths;
foreach(QString fileName, fileNames) {
filePaths.append(torrentBackup.path()+QDir::separator()+fileName);
}
// Resume downloads
foreach(const QString &hash, known_torrents) {
qDebug("Starting up torrent %s", hash.toLocal8Bit().data());
if(TorrentPersistentData::isMagnet(hash))
addMagnetUri(TorrentPersistentData::getMagnetUri(hash), true);
else
addTorrent(torrentBackup.path()+QDir::separator()+hash+".torrent", false, QString(), true);
foreach(QString fileName, filePaths) {
addTorrent(fileName, false, QString(), true);
}
}
qDebug("Unfinished torrents resumed");

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef __BITTORRENT_H__
@@ -60,7 +51,6 @@ class bittorrent : public QObject {
bool DHTEnabled;
QPointer<downloadThread> downloader;
QString defaultSavePath;
QString defaultTempPath;
QHash<QString, QHash<QString, QString> > trackersErrors;
QStringList consoleMessages;
QStringList peerBanMessages;
@@ -68,7 +58,7 @@ class bittorrent : public QObject {
bool addInPause;
int maxConnecsPerTorrent;
int maxUploadsPerTorrent;
float ratio_limit;
float max_ratio;
bool UPnPEnabled;
bool NATPMPEnabled;
bool LSDEnabled;
@@ -76,7 +66,6 @@ class bittorrent : public QObject {
QString filterPath;
bool queueingEnabled;
QStringList url_skippingDlg;
QHash<QString, QString> savepath_fromurl;
protected:
QString getSavePath(QString hash);
@@ -108,22 +97,19 @@ class bittorrent : public QObject {
QStringList getConsoleMessages() const;
QStringList getPeerBanMessages() const;
qlonglong getETA(QString hash) const;
bool useTemporaryFolder() const;
QString getDefaultSavePath() const;
public slots:
QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
QTorrentHandle addMagnetUri(QString magnet_uri, bool resumed=false);
void loadSessionState();
void saveSessionState();
void downloadFromUrl(QString url);
void downloadFromURLList(const QStringList& url_list);
void deleteTorrent(QString hash, bool permanent = false);
void startUpTorrents();
/* Needed by Web UI */
void pauseAllTorrents();
void resumeAllTorrents();
void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
void resumeAllTorrents();
/* End Web UI */
void saveDHTEntry();
void preAllocateAllFiles(bool b);
@@ -133,13 +119,15 @@ class bittorrent : public QObject {
void enableIPFilter(QString filter);
void disableIPFilter();
void setQueueingEnabled(bool enable);
void resumeUnfinishedTorrents();
void saveTorrentPriority(QString hash, int prio);
void saveTorrentSpeedLimits(QString hash);
void loadTorrentSpeedLimits(QString hash);
void handleDownloadFailure(QString url, QString reason);
void loadWebSeeds(QString fileHash);
void increaseDlTorrentPriority(QString hash);
void decreaseDlTorrentPriority(QString hash);
void downloadUrlAndSkipDialog(QString url, QString save_path=QString::null);
void downloadUrlAndSkipDialog(QString);
// Session configuration - Setters
void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports);
void setMaxConnections(int maxConnec);
@@ -154,7 +142,6 @@ class bittorrent : public QObject {
void setSessionSettings(session_settings sessionSettings);
void startTorrentsInPause(bool b);
void setDefaultSavePath(QString savepath);
void setDefaultTempPath(QString temppath);
void applyEncryptionSettings(pe_settings se);
void loadFilesPriorities(QTorrentHandle& h);
void setDownloadLimit(QString hash, long val);
@@ -165,13 +152,13 @@ class bittorrent : public QObject {
bool enableDHT(bool b);
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
void addPeerBanMessage(QString msg, bool from_ipfilter);
void processDownloadedFile(QString, QString);
void saveTrackerFile(QString hash);
protected slots:
void scanDirectory(QString);
void readAlerts();
void loadTrackerFile(QString hash);
void processDownloadedFile(QString, QString);
bool loadTrackerFile(QString hash);
void saveTrackerFile(QString hash);
void deleteBigRatios();
signals:
@@ -180,15 +167,13 @@ class bittorrent : public QObject {
void pausedTorrent(QTorrentHandle& h);
void resumedTorrent(QTorrentHandle& h);
void finishedTorrent(QTorrentHandle& h);
void fullDiskError(QTorrentHandle& h, QString msg);
void fullDiskError(QTorrentHandle& h);
void trackerError(QString hash, QString time, QString msg);
void trackerAuthenticationRequired(QTorrentHandle& h);
void newDownloadedTorrent(QString path, QString url);
void updateFileSize(QString hash);
void downloadFromUrlFailure(QString url, QString reason);
void torrentFinishedChecking(QTorrentHandle& h);
void metadataReceived(QTorrentHandle &h);
void torrentPaused(QTorrentHandle &h);
};
#endif

View File

@@ -13,7 +13,7 @@
<string>qBittorrent console</string>
</property>
<property name="windowIcon" >
<iconset resource="icons.qrc" >:/Icons/oxygen/log.png</iconset>
<iconset resource="icons.qrc" >:/Icons/log.png</iconset>
</property>
<layout class="QVBoxLayout" >
<item>
@@ -26,7 +26,7 @@
<string>General</string>
</attribute>
<attribute name="icon" >
<iconset resource="icons.qrc" >:/Icons/oxygen/log.png</iconset>
<iconset resource="icons.qrc" >:/Icons/log.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<item>

View File

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

View File

@@ -1,34 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<ui version="4.0" >
<class>createTorrentDialog</class>
<widget class="QDialog" name="createTorrentDialog">
<property name="geometry">
<widget class="QDialog" name="createTorrentDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>592</width>
<height>658</height>
<height>655</height>
</rect>
</property>
<property name="windowTitle">
<property name="windowTitle" >
<string>Torrent Creation Tool</string>
</property>
<layout class="QVBoxLayout">
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="createTorrent_title">
<property name="minimumSize">
<widget class="QLabel" name="createTorrent_title" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>27</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>27</height>
</size>
</property>
<property name="font">
<property name="font" >
<font>
<family>Sans Serif</family>
<pointsize>14</pointsize>
@@ -39,107 +38,105 @@
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<property name="text" >
<string>Torrent file creation</string>
</property>
<property name="alignment">
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_input">
<property name="text">
<widget class="QLabel" name="lbl_input" >
<property name="text" >
<string>File or folder to add to the torrent:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="textInputPath"/>
<widget class="QLineEdit" name="textInputPath" />
</item>
<item>
<layout class="QHBoxLayout">
<layout class="QHBoxLayout" >
<item>
<widget class="QPushButton" name="addFile_button">
<property name="text">
<widget class="QPushButton" name="addFile_button" >
<property name="text" >
<string>Add a file</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/add_file.png</normaloff>:/Icons/add_file.png</iconset>
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/add_file.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addFolder_button">
<property name="text">
<widget class="QPushButton" name="addFolder_button" >
<property name="text" >
<string>Add a folder</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/add_folder.png</normaloff>:/Icons/add_folder.png</iconset>
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/add_folder.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<layout class="QHBoxLayout" >
<item>
<layout class="QVBoxLayout">
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="lbl_announce_url">
<property name="minimumSize">
<widget class="QLabel" name="lbl_announce_url" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>102</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>70</height>
</size>
</property>
<property name="text">
<property name="text" >
<string>Announce urls (trackers):</string>
</property>
<property name="buddy">
<property name="buddy" >
<cstring></cstring>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="urlSeeds_lbl">
<property name="minimumSize">
<widget class="QLabel" name="urlSeeds_lbl" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>101</height>
</size>
</property>
<property name="text">
<property name="text" >
<string>Web seeds urls (optional):</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_comment">
<property name="minimumSize">
<widget class="QLabel" name="lbl_comment" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>102</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>102</height>
</size>
</property>
<property name="text">
<property name="text" >
<string>Comment (optional):</string>
</property>
<property name="buddy">
<property name="buddy" >
<cstring>txt_comment</cstring>
</property>
</widget>
@@ -147,36 +144,54 @@
</layout>
</item>
<item>
<layout class="QVBoxLayout">
<layout class="QVBoxLayout" >
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="trackers_list">
<property name="selectionMode">
<widget class="QListWidget" name="trackers_list" >
<property name="selectionMode" >
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>20</width>
<height>16</height>
@@ -185,69 +200,55 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="addTracker_button">
<property name="minimumSize">
<widget class="QPushButton" name="addTracker_button" >
<property name="minimumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<property name="text" >
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-add.png</normaloff>:/Icons/oxygen/list-add.png</iconset>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeTracker_button">
<property name="minimumSize">
<widget class="QPushButton" name="removeTracker_button" >
<property name="minimumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<property name="text" >
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-remove.png</normaloff>:/Icons/oxygen/list-remove.png</iconset>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/remove.png</iconset>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>20</width>
<height>16</height>
@@ -260,34 +261,52 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="URLSeeds_list">
<property name="selectionMode">
<widget class="QListWidget" name="URLSeeds_list" >
<property name="selectionMode" >
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>20</width>
<height>16</height>
@@ -296,69 +315,55 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="addURLSeed_button">
<property name="minimumSize">
<widget class="QPushButton" name="addURLSeed_button" >
<property name="minimumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<property name="text" >
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-add.png</normaloff>:/Icons/oxygen/list-add.png</iconset>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeURLSeed_button">
<property name="minimumSize">
<widget class="QPushButton" name="removeURLSeed_button" >
<property name="minimumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<property name="maximumSize" >
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<property name="text" >
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/list-remove.png</normaloff>:/Icons/oxygen/list-remove.png</iconset>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/remove.png</iconset>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>20</width>
<height>16</height>
@@ -371,14 +376,14 @@
</layout>
</item>
<item>
<widget class="QTextEdit" name="txt_comment">
<property name="maximumSize">
<widget class="QTextEdit" name="txt_comment" >
<property name="maximumSize" >
<size>
<width>421</width>
<height>102</height>
</size>
</property>
<property name="acceptRichText">
<property name="acceptRichText" >
<bool>false</bool>
</property>
</widget>
@@ -388,56 +393,56 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="txtPieceSize">
<property name="text">
<widget class="QLabel" name="txtPieceSize" >
<property name="text" >
<string>Piece size:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboPieceSize">
<property name="currentIndex">
<widget class="QComboBox" name="comboPieceSize" >
<property name="currentIndex" >
<number>3</number>
</property>
<item>
<property name="text">
<property name="text" >
<string>32 KiB</string>
</property>
</item>
<item>
<property name="text">
<property name="text" >
<string>64 KiB</string>
</property>
</item>
<item>
<property name="text">
<property name="text" >
<string>128 KiB</string>
</property>
</item>
<item>
<property name="text">
<property name="text" >
<string>256 KiB</string>
</property>
</item>
<item>
<property name="text">
<property name="text" >
<string>512 KiB</string>
</property>
</item>
<item>
<property name="text">
<property name="text" >
<string>1 MiB</string>
</property>
</item>
<item>
<property name="text">
<property name="text" >
<string>2 MiB</string>
</property>
</item>
<item>
<property name="text">
<property name="text" >
<string>4 MiB</string>
</property>
</item>
@@ -445,10 +450,10 @@
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -459,47 +464,56 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="check_private">
<property name="text">
<widget class="QCheckBox" name="check_private" >
<property name="text" >
<string>Private (won't be distributed on DHT network if enabled)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkStartSeeding">
<property name="text">
<widget class="QCheckBox" name="checkStartSeeding" >
<property name="text" >
<string>Start seeding after creation</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="progressLbl">
<property name="text">
<widget class="QLabel" name="progressLbl" >
<property name="text" >
<string>Progress:</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<widget class="QProgressBar" name="progressBar" >
<property name="value" >
<number>0</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>131</width>
<height>31</height>
@@ -508,25 +522,25 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="createButton">
<property name="text">
<widget class="QPushButton" name="createButton" >
<property name="text" >
<string>Create and save...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<widget class="QPushButton" name="cancelButton" >
<property name="text" >
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
@@ -539,7 +553,7 @@
</layout>
</widget>
<resources>
<include location="icons.qrc"/>
<include location="icons.qrc" />
</resources>
<connections>
<connection>
@@ -548,11 +562,11 @@
<receiver>createTorrentDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<hint type="sourcelabel" >
<x>355</x>
<y>275</y>
</hint>
<hint type="destinationlabel">
<hint type="destinationlabel" >
<x>179</x>
<y>282</y>
</hint>

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
@@ -184,6 +175,7 @@ void createtorrent::on_createButton_clicked(){
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) {
@@ -191,7 +183,7 @@ void createtorrent::handleCreationSuccess(QString path, const char* branch_path)
// Create save path file
boost::intrusive_ptr<torrent_info> t;
try {
t = new torrent_info(path.toLocal8Bit().data());
t = new torrent_info(path.toUtf8().data());
} catch(std::exception&) {
QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list."));
return;
@@ -204,7 +196,7 @@ void createtorrent::handleCreationSuccess(QString path, const char* branch_path)
emit torrent_to_seed(path);
}
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
close();
hide();
}
void createtorrent::updateProgressBar(int progress) {
@@ -227,12 +219,8 @@ void torrentCreatorThread::create(QString _input_path, QString _save_path, QStri
start();
}
void sendProgressUpdateSignal(int i, int num, torrentCreatorThread *parent){
parent->sendProgressSignal((int)(i*100./(float)num));
}
void torrentCreatorThread::sendProgressSignal(int progress) {
emit updateProgress(progress);
void sendProgressUpdateSignal(int i, int num, QDialog *parent){
((createtorrent*)parent)->updateProgressBar((int)(i*100./(float)num));
}
void torrentCreatorThread::run() {
@@ -241,7 +229,7 @@ void torrentCreatorThread::run() {
try {
file_storage fs;
file_pool fp;
path full_path = complete(path(input_path.toLocal8Bit().data()));
path full_path = complete(path(input_path.toUtf8().data()));
// Adding files to the torrent
add_files(fs, full_path, file_filter);
if(abort) return;
@@ -250,23 +238,25 @@ void torrentCreatorThread::run() {
// Add url seeds
QString seed;
foreach(seed, url_seeds){
t.add_url_seed(seed.toLocal8Bit().data());
t.add_url_seed(seed.toUtf8().data());
}
for(int i=0; i<trackers.size(); ++i){
t.add_tracker(trackers.at(i).toLocal8Bit().data());
t.add_tracker(trackers.at(i).toUtf8().data());
}
if(abort) return;
// calculate the hash for all pieces
set_piece_hashes(t, full_path.branch_path(), boost::bind<void>(&sendProgressUpdateSignal, _1, t.num_pieces(), this));
set_piece_hashes(t, full_path.branch_path(), boost::bind<void>(&sendProgressUpdateSignal, _1, t.num_pieces(), parent));
// Set qBittorrent as creator and add user comment to
// torrent_info structure
t.set_creator(creator_str);
t.set_comment((const char*)comment.toLocal8Bit());
t.set_comment((const char*)comment.toUtf8());
// Is private ?
t.set_priv(is_private);
if(is_private){
t.set_priv(true);
}
if(abort) return;
// create the torrent and print it to out
ofstream out(complete(path((const char*)save_path.toLocal8Bit())), std::ios_base::binary);
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
bencode(std::ostream_iterator<char>(out), t.generate());
emit updateProgress(100);
emit creationSuccess(save_path, full_path.branch_path().string().c_str());

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
@@ -57,7 +48,6 @@ class torrentCreatorThread : public QThread {
wait();
}
void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size);
void sendProgressSignal(int progress);
protected:
void run();
@@ -65,8 +55,6 @@ class torrentCreatorThread : public QThread {
signals:
void creationFailure(QString msg);
void creationSuccess(QString path, const char* branch_path);
signals:
void updateProgress(int progress);
};

View File

@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<ui version="4.0" >
<class>downloading</class>
<widget class="QWidget" name="downloading">
<property name="geometry">
<widget class="QWidget" name="downloading" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
@@ -10,39 +9,39 @@
<height>453</height>
</rect>
</property>
<property name="windowTitle">
<property name="windowTitle" >
<string>Search</string>
</property>
<layout class="QVBoxLayout">
<layout class="QVBoxLayout" >
<item>
<layout class="QVBoxLayout">
<property name="spacing">
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin">
<property name="margin" >
<number>0</number>
</property>
<item>
<widget class="QTreeView" name="downloadList">
<property name="minimumSize">
<widget class="QTreeView" name="downloadList" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="contextMenuPolicy">
<property name="contextMenuPolicy" >
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="autoScroll">
<property name="autoScroll" >
<bool>true</bool>
</property>
<property name="selectionMode">
<property name="selectionMode" >
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="indentation">
<property name="indentation" >
<number>1</number>
</property>
<property name="itemsExpandable">
<property name="itemsExpandable" >
<bool>false</bool>
</property>
</widget>
@@ -50,144 +49,139 @@
</layout>
</item>
</layout>
<action name="actionStart">
<property name="text">
<action name="actionStart" >
<property name="text" >
<string>Start</string>
</property>
</action>
<action name="actionPause">
<property name="text">
<action name="actionPause" >
<property name="text" >
<string>Pause</string>
</property>
</action>
<action name="actionDelete">
<property name="text">
<action name="actionDelete" >
<property name="text" >
<string>Delete</string>
</property>
</action>
<action name="actionPreview_file">
<property name="text">
<action name="actionPreview_file" >
<property name="text" >
<string>Preview file</string>
</property>
</action>
<action name="actionSet_upload_limit">
<property name="text">
<action name="actionSet_upload_limit" >
<property name="text" >
<string>Set upload limit</string>
</property>
</action>
<action name="actionSet_download_limit">
<property name="text">
<action name="actionSet_download_limit" >
<property name="text" >
<string>Set download limit</string>
</property>
</action>
<action name="actionDelete_Permanently">
<property name="text">
<action name="actionDelete_Permanently" >
<property name="text" >
<string>Delete Permanently</string>
</property>
</action>
<action name="actionTorrent_Properties">
<property name="text">
<action name="actionTorrent_Properties" >
<property name="text" >
<string>Torrent Properties</string>
</property>
</action>
<action name="actionOpen_destination_folder">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/folder.png</normaloff>:/Icons/oxygen/folder.png</iconset>
<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">
<property name="text" >
<string>Open destination folder</string>
</property>
</action>
<action name="actionHOSColName">
<property name="text">
<action name="actionHOSColName" >
<property name="text" >
<string>Name</string>
</property>
</action>
<action name="actionHOSColSize">
<property name="text">
<action name="actionHOSColSize" >
<property name="text" >
<string>Size</string>
</property>
</action>
<action name="actionHOSColProgress">
<property name="text">
<action name="actionHOSColProgress" >
<property name="text" >
<string>Progress</string>
</property>
</action>
<action name="actionHOSColDownSpeed">
<property name="text">
<action name="actionHOSColDownSpeed" >
<property name="text" >
<string>DLSpeed</string>
</property>
</action>
<action name="actionHOSColUpSpeed">
<property name="text">
<action name="actionHOSColUpSpeed" >
<property name="text" >
<string>UpSpeed</string>
</property>
</action>
<action name="actionHOSColSeedersLeechers">
<property name="text">
<action name="actionHOSColSeedersLeechers" >
<property name="text" >
<string>Seeds/Leechs</string>
</property>
</action>
<action name="actionHOSColRatio">
<property name="text">
<action name="actionHOSColRatio" >
<property name="text" >
<string>Ratio</string>
</property>
</action>
<action name="actionHOSColEta">
<property name="text">
<action name="actionHOSColEta" >
<property name="text" >
<string>ETA</string>
</property>
</action>
<action name="actionBuy_it">
<property name="icon">
<iconset resource="icons.qrc">
<action name="actionBuy_it" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/money.png</normaloff>:/Icons/money.png</iconset>
</property>
<property name="text">
<property name="text" >
<string>Buy it</string>
</property>
</action>
<action name="actionHOSColPriority">
<property name="text">
<action name="actionHOSColPriority" >
<property name="text" >
<string>Priority</string>
</property>
</action>
<action name="actionIncreasePriority">
<property name="icon">
<iconset resource="icons.qrc">
<action name="actionIncreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/skin/increase.png</normaloff>:/Icons/skin/increase.png</iconset>
</property>
<property name="text">
<property name="text" >
<string>Increase priority</string>
</property>
</action>
<action name="actionDecreasePriority">
<property name="icon">
<iconset resource="icons.qrc">
<action name="actionDecreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/skin/decrease.png</normaloff>:/Icons/skin/decrease.png</iconset>
</property>
<property name="text">
<property name="text" >
<string>Decrease priority</string>
</property>
</action>
<action name="actionForce_recheck">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/gear.png</normaloff>:/Icons/oxygen/gear.png</iconset>
<action name="actionForce_recheck" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/gear.png</normaloff>:/Icons/gear.png</iconset>
</property>
<property name="text">
<property name="text" >
<string>Force recheck</string>
</property>
</action>
<action name="actionCopy_magnet_link">
<property name="text">
<string>Copy magnet link</string>
</property>
</action>
</widget>
<resources>
<include location="icons.qrc"/>
<include location="icons.qrc" />
</resources>
<connections/>
</ui>

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
@@ -36,7 +27,6 @@
#include <QString>
#include <QRegExp>
#include <QStringList>
#include <QClipboard>
#include "ui_downloadFromURL.h"
class downloadFromURL : public QDialog, private Ui::downloadFromURL{
@@ -48,11 +38,6 @@ class downloadFromURL : public QDialog, private Ui::downloadFromURL{
setAttribute(Qt::WA_DeleteOnClose);
icon_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/url.png")));
show();
// Paste clipboard if there is an URL in it
QString clip_txt = qApp->clipboard()->text();
if(clip_txt.startsWith("http://", Qt::CaseInsensitive) || clip_txt.startsWith("https://", Qt::CaseInsensitive) || clip_txt.startsWith("ftp://", Qt::CaseInsensitive) || clip_txt.startsWith("magnet:", Qt::CaseInsensitive)) {
textUrls->setText(clip_txt);
}
}
~downloadFromURL(){}

View File

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

View File

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

View File

@@ -16,15 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include "downloadingTorrents.h"
@@ -53,9 +44,8 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
actionCopy_magnet_link->setIcon(QIcon(QString::fromUtf8(":/Icons/magnet.png")));
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/oxygen/log.png")));
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/oxygen/filter.png")));
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.png")));
// Set Download list model
DLListModel = new QStandardItemModel(0,10);
@@ -69,8 +59,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
DLListModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left"));
DLListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority"));
downloadList->setModel(DLListModel);
downloadList->setRootIsDecorated(false);
downloadList->setAllColumnsShowFocus(true);
DLDelegate = new DLListDelegate(downloadList);
downloadList->setItemDelegate(DLDelegate);
// Hide priority column
@@ -80,7 +68,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
loadHiddenColumns();
connect(BTSession, SIGNAL(torrentFinishedChecking(QTorrentHandle&)), this, SLOT(sortProgressColumn(QTorrentHandle&)));
connect(BTSession, SIGNAL(metadataReceived(QTorrentHandle&)), this, SLOT(updateMetadata(QTorrentHandle&)));
// Load last columns width for download list
if(!loadColWidthDLList()) {
@@ -107,7 +94,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
connect(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
connect(actionCopy_magnet_link, SIGNAL(triggered()), (GUI*)parent, SLOT(copyMagnetURI()));
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
@@ -176,12 +162,10 @@ void DownloadingTorrents::showProperties(const QModelIndex &index) {
void DownloadingTorrents::showPropertiesFromHash(QString hash) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid() && h.has_metadata()) {
properties *prop = new properties(this, BTSession, h);
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSizeAndProgress(QString)));
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
prop->show();
}
}
// Remove a torrent from the download list but NOT from the BT Session
@@ -198,8 +182,9 @@ void DownloadingTorrents::deleteTorrent(QString hash) {
void DownloadingTorrents::on_actionSet_download_limit_triggered() {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QModelIndex index;
QStringList hashes;
foreach(const QModelIndex &index, selectedIndexes) {
foreach(index, selectedIndexes) {
if(index.column() == NAME) {
// Get the file hash
hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
@@ -211,8 +196,9 @@ void DownloadingTorrents::on_actionSet_download_limit_triggered() {
void DownloadingTorrents::on_actionSet_upload_limit_triggered() {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QModelIndex index;
QStringList hashes;
foreach(const QModelIndex &index, selectedIndexes) {
foreach(index, selectedIndexes) {
if(index.column() == NAME) {
// Get the file hash
hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
@@ -225,7 +211,8 @@ void DownloadingTorrents::on_actionSet_upload_limit_triggered() {
// display properties of selected items
void DownloadingTorrents::propertiesSelection(){
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){
QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == NAME){
showProperties(index);
}
@@ -234,34 +221,29 @@ void DownloadingTorrents::propertiesSelection(){
void DownloadingTorrents::forceRecheck() {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes){
QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == NAME){
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid() && h.has_metadata())
h.force_recheck();
}
}
}
void DownloadingTorrents::displayDLListMenu(const QPoint&) {
void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
QMenu myDLLlistMenu(this);
QModelIndex index;
// Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
bool has_pause = false, has_start = false, has_preview = false;
bool one_has_metadata = false;
QTorrentHandle h;
qDebug("Displaying menu");
foreach(const QModelIndex &index, selectedIndexes) {
foreach(index, selectedIndexes) {
if(index.column() == NAME) {
// Get the file name
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
// Get handle and pause the torrent
h = BTSession->getTorrentHandle(hash);
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(!h.is_valid()) continue;
if(h.has_metadata()) {
one_has_metadata = true;
}
if(h.is_paused()) {
if(!has_start) {
myDLLlistMenu.addAction(actionStart);
@@ -273,7 +255,7 @@ void DownloadingTorrents::displayDLListMenu(const QPoint&) {
has_pause = true;
}
}
if(h.has_metadata() && BTSession->isFilePreviewPossible(hash) && !has_preview) {
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
myDLLlistMenu.addAction(actionPreview_file);
has_preview = true;
}
@@ -287,12 +269,9 @@ void DownloadingTorrents::displayDLListMenu(const QPoint&) {
myDLLlistMenu.addAction(actionSet_download_limit);
myDLLlistMenu.addAction(actionSet_upload_limit);
myDLLlistMenu.addSeparator();
if(one_has_metadata) {
myDLLlistMenu.addAction(actionForce_recheck);
myDLLlistMenu.addSeparator();
}
myDLLlistMenu.addAction(actionOpen_destination_folder);
if(one_has_metadata)
myDLLlistMenu.addAction(actionTorrent_Properties);
if(BTSession->isQueueingEnabled()) {
myDLLlistMenu.addSeparator();
@@ -300,10 +279,10 @@ void DownloadingTorrents::displayDLListMenu(const QPoint&) {
myDLLlistMenu.addAction(actionDecreasePriority);
}
myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionCopy_magnet_link);
myDLLlistMenu.addAction(actionBuy_it);
// Call menu
myDLLlistMenu.exec(QCursor::pos());
// XXX: why mapToGlobal() is not enough?
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,35));
}
@@ -343,12 +322,12 @@ void DownloadingTorrents::hideOrShowColumn(int index) {
if(nbVisibleColumns <= 1) return;
// User can hide the column, do it.
downloadList->setColumnHidden(index, true);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png")));
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
--nbVisibleColumns;
} else {
// User want to display the column
downloadList->setColumnHidden(index, false);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png")));
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
++nbVisibleColumns;
}
//resize all others non-hidden columns
@@ -362,9 +341,9 @@ void DownloadingTorrents::hideOrShowColumn(int index) {
void DownloadingTorrents::hidePriorityColumn(bool hide) {
downloadList->setColumnHidden(PRIORITY, hide);
if(hide)
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png")));
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
else
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png")));
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
}
// save the hidden columns in settings
@@ -402,9 +381,9 @@ bool DownloadingTorrents::loadHiddenColumns() {
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/oxygen/button_cancel.png")));
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
} else {
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png")));
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
}
}
return loaded;
@@ -478,13 +457,14 @@ QAction* DownloadingTorrents::getActionHoSCol(int index) {
break;
default :
return NULL;
}
}
}
QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
QStringList res;
QModelIndex index;
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
foreach(const QModelIndex &index, selectedIndexes) {
foreach(index, selectedIndexes) {
if(index.column() == NAME) {
// Get the file hash
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
@@ -495,20 +475,9 @@ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
return res;
}
void DownloadingTorrents::updateMetadata(QTorrentHandle &h) {
QString hash = h.hash();
int row = getRowFromHash(hash);
if(row != -1) {
qDebug("Updating torrent metadata in download list");
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.name()));
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size()));
}
}
// get information from torrent handles and
// update download list accordingly
bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
if(!h.is_valid()) return false;
bool added = false;
try{
QString hash = h.hash();
@@ -525,7 +494,7 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
if(h.is_queued()) {
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
@@ -552,7 +521,7 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
switch(h.state()) {
case torrent_status::checking_files:
case torrent_status::queued_for_checking:
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
break;
case torrent_status::downloading:
@@ -583,13 +552,7 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
}
}
if(!downloadList->isColumnHidden(SEEDSLEECH)) {
QString tmp = misc::toQString(h.num_seeds(), true);
if(h.num_complete() >= 0)
tmp.append(QString("(")+misc::toQString(h.num_complete())+QString(")"));
tmp.append(QString("/")+misc::toQString(h.num_peers() - h.num_seeds(), true));
if(h.num_incomplete() >= 0)
tmp.append(QString("(")+misc::toQString(h.num_incomplete())+QString(")"));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(tmp));
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))));
@@ -601,7 +564,7 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
void DownloadingTorrents::addTorrent(QString hash) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
int row = getRowFromHash(hash);
qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toLocal8Bit(), row);
qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toUtf8(), row);
if(row != -1) return;
row = DLListModel->rowCount();
// Adding torrent to download list
@@ -612,7 +575,6 @@ void DownloadingTorrents::addTorrent(QString hash) {
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
DLListModel->setData(DLListModel->index(row, RATIO), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
if(BTSession->isQueueingEnabled())
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
@@ -752,7 +714,7 @@ void DownloadingTorrents::saveColWidthDLList() const{
width_list = line.split(' ');
}
for(short i=0; i<nbColumns; ++i){
if(downloadList->columnWidth(i)<1 && width_list.size() == nbColumns && width_list.at(i).toInt()>=1) {
if(downloadList->columnWidth(i)<1 && width_list.size() == DLListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
// load the former width
new_width_list << width_list.at(i);
} else if(downloadList->columnWidth(i)>=1) {
@@ -765,11 +727,6 @@ void DownloadingTorrents::saveColWidthDLList() const{
}
}
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), new_width_list.join(QString::fromUtf8(" ")));
QVariantList visualIndexes;
for(int i=0; i<nbColumns; ++i) {
visualIndexes.append(downloadList->header()->visualIndex(i));
}
settings.setValue(QString::fromUtf8("DownloadListVisualIndexes"), visualIndexes);
qDebug("Download list columns width saved");
}
@@ -790,23 +747,6 @@ bool DownloadingTorrents::loadColWidthDLList() {
for(unsigned int i=0; i<listSize; ++i) {
downloadList->header()->resizeSection(i, width_list.at(i).toInt());
}
QVariantList visualIndexes = settings.value(QString::fromUtf8("DownloadListVisualIndexes"), QVariantList()).toList();
if(visualIndexes.size() != DLListModel->columnCount()-1) {
qDebug("Corrupted values for download list columns sizes");
return false;
}
bool change = false;
do {
change = false;
for(int i=0;i<visualIndexes.size(); ++i) {
int new_visual_index = visualIndexes.at(downloadList->header()->logicalIndex(i)).toInt();
if(i != new_visual_index) {
qDebug("Moving column from %d to %d", downloadList->header()->logicalIndex(i), new_visual_index);
downloadList->header()->moveSection(i, new_visual_index);
change = true;
}
}
}while(change);
qDebug("Download list columns width loaded");
return true;
}

Some files were not shown because too many files have changed in this diff Show More