- 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: RSS Feeds can now be copied to the clipboard
This commit is contained in:
Christophe Dumez 2009-08-21 07:40:57 +00:00
parent 2477dc1fc0
commit 0b9c05d41b
79 changed files with 8294 additions and 5496 deletions

View file

@ -1,7 +1,12 @@
* 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 [TODO]
- BUGFIX: torrent resume code rewrited
* Thu Aug 13 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.4.0

View file

@ -23,7 +23,7 @@ public:
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());
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());
return true;
}
};

331
src/FeedDownloader.h Normal file
View file

@ -0,0 +1,331 @@
/*
* 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 "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 tokens = getMatchingTokens();
foreach(const QString& token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive);
if(reg.indexIn(s) < 0) 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 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(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());
// Fill filter list
foreach(QString filter_name, filters.names()) {
new QListWidgetItem(filter_name, filtersList);
}
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 showFilterSettings(QListWidgetItem *item) {
// First, save current filter settings
saveCurrentFilterSettings();
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());
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) {
filters.remove(selected_filter);
selected_filter = QString::null;
QListWidgetItem * item = items.first();
delete item;
// Reset Filter settings view
if(filters.size() == 0) {
clearFields();
filterSettingsBox->setEnabled(false);
}
}
}
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(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();
}
};
#endif // FEEDDOWNLOADER_H

377
src/FeedDownloader.ui Normal file
View file

@ -0,0 +1,377 @@
<?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>392</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"/>
</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_6">
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<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>
</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>
</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>
</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>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</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>
</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

@ -315,7 +315,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
if(enable) {
// RSS tab
if(rssWidget == 0) {
rssWidget = new RSSImp();
rssWidget = new RSSImp(BTSession);
tabs->addTab(rssWidget, tr("RSS"));
tabs->setTabIcon(3, QIcon(QString::fromUtf8(":/Icons/rss32.png")));
}
@ -450,8 +450,8 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
}
void GUI::setPaused(QTorrentHandle &h) const {
Q_ASSERT(h.is_paused());
qDebug("Marking torrent %s as paused", h.hash().toUtf8().data());
if(!h.is_paused()) return;
qDebug("Marking torrent %s as paused", h.hash().toLocal8Bit().data());
if(h.is_seed()) {
// In finished list
qDebug("Automatically paused torrent was in finished list");

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 739 B

After

Width:  |  Height:  |  Size: 752 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 629 B

After

Width:  |  Height:  |  Size: 722 B

Before After
Before After

View file

@ -179,6 +179,12 @@ 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) {
@ -368,7 +374,7 @@ QTorrentHandle bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
return h;
}
if(resumed) {
qDebug("Resuming magnet URI: %s", hash.toUtf8().data());
qDebug("Resuming magnet URI: %s", hash.toLocal8Bit().data());
} else {
qDebug("Adding new magnet URI");
}
@ -386,7 +392,7 @@ QTorrentHandle bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
}
// Check if torrent is already in download list
if(s->find_torrent(sha1_hash(hash.toUtf8().data())).is_valid()) {
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));
@ -405,7 +411,7 @@ QTorrentHandle bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
}
}
QString savePath = getSavePath(hash);
qDebug("addMagnetURI: using save_path: %s", savePath.toUtf8().data());
qDebug("addMagnetURI: using save_path: %s", savePath.toLocal8Bit().data());
if(defaultTempPath.isEmpty() || (resumed && TorrentPersistentData::isSeed(hash))) {
p.save_path = savePath.toLocal8Bit().data();
} else {
@ -455,12 +461,12 @@ QTorrentHandle bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
}
// Save persistent data for new torrent
Q_ASSERT(h.is_valid());
qDebug("addMagnetUri: hash: %s", h.hash().toUtf8().data());
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.toUtf8().data());
qDebug("addMagnetUri: Saving save_path in persistent data: %s", savePath.toLocal8Bit().data());
TorrentPersistentData::saveSavePath(hash, savePath);
}
}
@ -555,8 +561,14 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
qDebug("Successfuly loaded");
}
}
QString savePath = getSavePath(hash);
qDebug("addTorrent: using save_path: %s", savePath.toUtf8().data());
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 {
@ -609,7 +621,7 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
TorrentPersistentData::saveTorrentPersistentData(h);
// Save save_path
if(!defaultTempPath.isEmpty()) {
qDebug("addTorrent: Saving save_path in persistent data: %s", savePath.toUtf8().data());
qDebug("addTorrent: Saving save_path in persistent data: %s", savePath.toLocal8Bit().data());
TorrentPersistentData::saveSavePath(hash, savePath);
}
}
@ -1002,6 +1014,10 @@ void bittorrent::setDefaultSavePath(QString savepath) {
defaultSavePath = savepath;
}
QString bittorrent::getDefaultSavePath() const {
return defaultSavePath;
}
bool bittorrent::useTemporaryFolder() const {
return !defaultTempPath.isEmpty();
}
@ -1256,7 +1272,7 @@ void bittorrent::readAlerts() {
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().toUtf8().data());
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
@ -1279,7 +1295,7 @@ void bittorrent::readAlerts() {
}
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().toUtf8().data());
qDebug("Received a torrent_paused_alert for %s", h.hash().toLocal8Bit().data());
if(h.is_valid()) {
emit torrentPaused(h);
}
@ -1379,14 +1395,14 @@ QString bittorrent::getSavePath(QString hash) {
QString savePath;
if(TorrentTempData::hasTempData(hash)) {
savePath = TorrentTempData::getSavePath(hash);
qDebug("getSavePath, got save_path from temp data: %s", savePath.toUtf8().data());
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.toUtf8().data());
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.toUtf8().data());
qDebug("Using default save path because none was set: %s", defaultSavePath.toLocal8Bit().data());
savePath = defaultSavePath;
}
// Checking if savePath Dir exists
@ -1412,8 +1428,10 @@ void bittorrent::downloadFromUrl(QString url) {
downloader->downloadUrl(url);
}
void bittorrent::downloadUrlAndSkipDialog(QString url) {
void bittorrent::downloadUrlAndSkipDialog(QString url, QString save_path) {
//emit aboutToDownloadFromUrl(url);
if(!save_path.isEmpty())
savepath_fromurl[url] = save_path;
url_skippingDlg << url;
// Launch downloader thread
downloader->downloadUrl(url);
@ -1491,7 +1509,7 @@ void bittorrent::startUpTorrents() {
QPair<int, QString> couple;
foreach(couple, hashes) {
QString hash = couple.second;
qDebug("Starting up torrent %s", hash.toUtf8().data());
qDebug("Starting up torrent %s", hash.toLocal8Bit().data());
if(TorrentPersistentData::isMagnet(hash)) {
addMagnetUri(TorrentPersistentData::getMagnetUri(hash), true);
} else {
@ -1501,7 +1519,7 @@ void bittorrent::startUpTorrents() {
} else {
// Resume downloads
foreach(const QString &hash, known_torrents) {
qDebug("Starting up torrent %s", hash.toUtf8().data());
qDebug("Starting up torrent %s", hash.toLocal8Bit().data());
if(TorrentPersistentData::isMagnet(hash))
addMagnetUri(TorrentPersistentData::getMagnetUri(hash), true);
else

View file

@ -76,6 +76,7 @@ class bittorrent : public QObject {
QString filterPath;
bool queueingEnabled;
QStringList url_skippingDlg;
QHash<QString, QString> savepath_fromurl;
protected:
QString getSavePath(QString hash);
@ -108,6 +109,7 @@ class bittorrent : public QObject {
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);
@ -137,7 +139,7 @@ class bittorrent : public QObject {
void loadWebSeeds(QString fileHash);
void increaseDlTorrentPriority(QString hash);
void decreaseDlTorrentPriority(QString hash);
void downloadUrlAndSkipDialog(QString);
void downloadUrlAndSkipDialog(QString url, QString save_path=QString::null);
// Session configuration - Setters
void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports);
void setMaxConnections(int maxConnec);

View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>createTorrentDialog</class>
<widget class="QDialog" name="createTorrentDialog">
@ -6,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>592</width>
<height>655</height>
<height>658</height>
</rect>
</property>
<property name="windowTitle">
@ -64,7 +65,8 @@
<string>Add a file</string>
</property>
<property name="icon">
<iconset resource="icons.qrc" >:/Icons/add_file.png</iconset>
<iconset resource="icons.qrc">
<normaloff>:/Icons/add_file.png</normaloff>:/Icons/add_file.png</iconset>
</property>
</widget>
</item>
@ -74,7 +76,8 @@
<string>Add a folder</string>
</property>
<property name="icon">
<iconset resource="icons.qrc" >:/Icons/add_folder.png</iconset>
<iconset resource="icons.qrc">
<normaloff>:/Icons/add_folder.png</normaloff>:/Icons/add_folder.png</iconset>
</property>
</widget>
</item>
@ -150,16 +153,7 @@
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<property name="margin">
<number>0</number>
</property>
<item>
@ -174,16 +168,7 @@
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<property name="margin">
<number>0</number>
</property>
<item>
@ -191,7 +176,7 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
@ -217,7 +202,14 @@
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc" >:/Icons/skin/add.png</iconset>
<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>
</widget>
</item>
@ -239,7 +231,14 @@
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc" >:/Icons/skin/remove.png</iconset>
<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>
</widget>
</item>
@ -248,7 +247,7 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
@ -265,16 +264,7 @@
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<property name="margin">
<number>0</number>
</property>
<item>
@ -289,16 +279,7 @@
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<property name="margin">
<number>0</number>
</property>
<item>
@ -306,7 +287,7 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
@ -332,7 +313,14 @@
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc" >:/Icons/skin/add.png</iconset>
<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>
</widget>
</item>
@ -354,7 +342,14 @@
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc" >:/Icons/skin/remove.png</iconset>
<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>
</widget>
</item>
@ -363,7 +358,7 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
@ -453,7 +448,7 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
@ -496,16 +491,7 @@
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<property name="margin">
<number>0</number>
</property>
<item>
@ -513,7 +499,7 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>131</width>
<height>31</height>
@ -540,7 +526,7 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>

View file

@ -59,7 +59,7 @@ engineSelectDlg::engineSelectDlg(QWidget *parent) : QDialog(parent) {
pluginsTree->hideColumn(ENGINE_ID);
actionEnable->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_ok.png")));
actionDisable->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png")));
actionUninstall->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/remove.png")));
actionUninstall->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/list-remove.png")));
connect(actionEnable, SIGNAL(triggered()), this, SLOT(enableSelection()));
connect(actionDisable, SIGNAL(triggered()), this, SLOT(disableSelection()));
connect(pluginsTree, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayContextMenu(const QPoint&)));

View file

@ -19,7 +19,6 @@
<file>Icons/skin/qbittorrent22.png</file>
<file>Icons/skin/new.png</file>
<file>Icons/skin/preview.png</file>
<file>Icons/skin/add.png</file>
<file>Icons/skin/stalled.png</file>
<file>Icons/skin/delete.png</file>
<file>Icons/skin/url.png</file>
@ -31,7 +30,6 @@
<file>Icons/skin/paused.png</file>
<file>Icons/skin/qb_question.png</file>
<file>Icons/skin/open.png</file>
<file>Icons/skin/remove.png</file>
<file>Icons/skin/qbittorrent16.png</file>
<file>Icons/skin/downloading.png</file>
<file>Icons/skin/search.png</file>
@ -96,8 +94,10 @@
<file>Icons/oxygen/edit-copy.png</file>
<file>Icons/oxygen/bt_settings.png</file>
<file>Icons/oxygen/webui.png</file>
<file>Icons/oxygen/list-remove.png</file>
<file>Icons/oxygen/connection.png</file>
<file>Icons/oxygen/bug.png</file>
<file>Icons/oxygen/list-add.png</file>
<file>Icons/oxygen/folder.png</file>
<file>Icons/oxygen/configure.png</file>
<file>Icons/oxygen/edit-cut.png</file>

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -649,7 +649,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Duplo clique na lista de transferência
<translation type="obsolete">Duplo clique na lista de transferência
qBittorrent irá procurar no diretório e baixará automaticamente torrents present</translation>
</message>
<message>
@ -910,6 +910,11 @@ qBittorrent irá procurar no diretório e baixará automaticamente torrents pres
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2252,7 +2257,7 @@ Deseja mesmo sair do qBittorrent?</translation>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Info:&lt;/b&gt; &lt;i&gt;(clique-duplo para abrir o link no seu browser)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Info:&lt;/b&gt; &lt;i&gt;(clique-duplo para abrir o link no seu browser)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -2274,6 +2279,22 @@ Deseja mesmo sair do qBittorrent?</translation>
<source>Mark all as read</source>
<translation>Marcar todos como lido</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -2729,7 +2750,7 @@ Log de mudanças:</translation>
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Baixar em ordem (lento mas bom para pré-visualizar)</translation>
<translation type="obsolete">Baixar em ordem (lento mas bom para pré-visualizar)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -2775,6 +2796,22 @@ Log de mudanças:</translation>
<source>Expand all</source>
<translation>Expandir todos</translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Desconhecido</translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -2903,6 +2940,10 @@ Log de mudanças:</translation>
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>baixando &apos;%1&apos;, por favor espere...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3300,6 +3341,10 @@ Log de mudanças:</translation>
<source>Force recheck</source>
<translation>Forçar re-checagem</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4218,6 +4263,10 @@ Portanto os plugins foram desabilitados.</translation>
<source>Force recheck</source>
<translation>Forçar re-checagem</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4332,5 +4381,19 @@ Portanto os plugins foram desabilitados.</translation>
<source>Priority</source>
<translation>Prioridade</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Desconhecido</translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -649,7 +649,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Duplo clique na lista de transferência
<translation type="obsolete">Duplo clique na lista de transferência
qBittorrent irá procurar no diretório e baixará automaticamente torrents present</translation>
</message>
<message>
@ -910,6 +910,11 @@ qBittorrent irá procurar no diretório e baixará automaticamente torrents pres
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2252,7 +2257,7 @@ Deseja mesmo sair do qBittorrent?</translation>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Info:&lt;/b&gt; &lt;i&gt;(clique-duplo para abrir o link no seu browser)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Info:&lt;/b&gt; &lt;i&gt;(clique-duplo para abrir o link no seu browser)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -2274,6 +2279,22 @@ Deseja mesmo sair do qBittorrent?</translation>
<source>Mark all as read</source>
<translation>Marcar todos como lido</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -2729,7 +2750,7 @@ Log de mudanças:</translation>
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Baixar em ordem (lento mas bom para pré-visualizar)</translation>
<translation type="obsolete">Baixar em ordem (lento mas bom para pré-visualizar)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -2775,6 +2796,22 @@ Log de mudanças:</translation>
<source>Expand all</source>
<translation>Expandir todos</translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Desconhecido</translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -2903,6 +2940,10 @@ Log de mudanças:</translation>
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>baixando &apos;%1&apos;, por favor espere...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3300,6 +3341,10 @@ Log de mudanças:</translation>
<source>Force recheck</source>
<translation>Forçar re-checagem</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4218,6 +4263,10 @@ Portanto os plugins foram desabilitados.</translation>
<source>Force recheck</source>
<translation>Forçar re-checagem</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4332,5 +4381,19 @@ Portanto os plugins foram desabilitados.</translation>
<source>Priority</source>
<translation>Prioridade</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Desconhecido</translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -657,7 +657,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Lista cu transferuri dublu-click
<translation type="obsolete">Lista cu transferuri dublu-click
qBittorrent va monitoriza directoriul și va adăuga în lista de descărcare a torentelor din directoriu</translation>
</message>
<message>
@ -918,6 +918,11 @@ qBittorrent va monitoriza directoriul și va adăuga în lista de descărcare a
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2181,7 +2186,7 @@ Motivul : %2</translation>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Noutăţi:&lt;/b&gt; &lt;i&gt;(dubli click pentru a deschide)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Noutăţi:&lt;/b&gt; &lt;i&gt;(dubli click pentru a deschide)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -2203,6 +2208,22 @@ Motivul : %2</translation>
<source>Mark all as read</source>
<translation>Marchează toate ca citite</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -2568,7 +2589,7 @@ Changelog:
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Descarcă în ordine corectă (mai încet dar bun pentru preview)</translation>
<translation type="obsolete">Descarcă în ordine corectă (mai încet dar bun pentru preview)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -2614,6 +2635,22 @@ Changelog:
<source>Expand all</source>
<translation>Deschide toate</translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Necunoscut</translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -2742,6 +2779,10 @@ Changelog:
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>Descarc &apos;%1&apos;, rugăm aşteptaţi...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3139,6 +3180,10 @@ Changelog:
<source>Force recheck</source>
<translation>Reverificarea forţată</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4065,6 +4110,10 @@ Numai acele adăugate de dvs. pot fi dezinstalate.
<source>Force recheck</source>
<translation>Reverificarea forţată</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4179,5 +4228,19 @@ Numai acele adăugate de dvs. pot fi dezinstalate.
<source>Priority</source>
<translation>Prioritate</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Necunoscut</translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -704,7 +704,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Двойной щелчок по списку закачек</translation>
<translation type="obsolete">Двойной щелчок по списку закачек</translation>
</message>
<message>
<source>Download list:</source>
@ -964,6 +964,11 @@ p, li { white-space: pre-wrap; }
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2354,7 +2359,7 @@ Are you sure you want to quit qBittorrent?</source>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Новости:&lt;/b&gt; &lt;i&gt;(двойной клик откроет ссылку в вашем браузере)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Новости:&lt;/b&gt; &lt;i&gt;(двойной клик откроет ссылку в вашем браузере)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -2376,6 +2381,22 @@ Are you sure you want to quit qBittorrent?</source>
<source>Mark all as read</source>
<translation>Отметить все как прочитанное</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -2753,7 +2774,7 @@ Changelog:
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Загрузить в правильном порядке (медленнее, но удобнее для предпросмотра)</translation>
<translation type="obsolete">Загрузить в правильном порядке (медленнее, но удобнее для предпросмотра)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -2803,6 +2824,22 @@ Changelog:
<source>Expand all</source>
<translation>Развернуть все</translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Неизвестно</translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -2931,6 +2968,10 @@ Changelog:
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>Скачивание &apos;%1&apos;, подождите...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3320,6 +3361,10 @@ Changelog:
<source>Force recheck</source>
<translation>Проверить принудительно</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4275,6 +4320,10 @@ However, those plugins were disabled.</source>
<source>Force recheck</source>
<translation>Проверить принудительно</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4389,5 +4438,19 @@ However, those plugins were disabled.</source>
<source>Priority</source>
<translation>Приоритет</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Неизвестно</translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -665,7 +665,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Dvojité kliknutie v zozname prenosov</translation>
<translation type="obsolete">Dvojité kliknutie v zozname prenosov</translation>
</message>
<message>
<source>Download list:</source>
@ -925,6 +925,11 @@ p, li { white-space: pre-wrap; }
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2256,7 +2261,7 @@ Ste si istý, že chcete ukončiť qBittorrent?</translation>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Novinky:&lt;/b&gt; &lt;i&gt;(dvojitým kliknutím otvoríte odkaz vo webovom prehliadači)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Novinky:&lt;/b&gt; &lt;i&gt;(dvojitým kliknutím otvoríte odkaz vo webovom prehliadači)&lt;/i&gt;</translation>
</message>
<message>
<source>Delete</source>
@ -2290,6 +2295,22 @@ Ste si istý, že chcete ukončiť qBittorrent?</translation>
<source>Mark all as read</source>
<translation>Označiť všetky ako prečítané</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -2666,7 +2687,7 @@ Záznam zmien:</translation>
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Stiahnuť v správnom poradí (pomalšie ale lepšie pre náhľad)</translation>
<translation type="obsolete">Stiahnuť v správnom poradí (pomalšie ale lepšie pre náhľad)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -2720,6 +2741,22 @@ Záznam zmien:</translation>
<source>Expand all</source>
<translation>Rozbaliť všetko</translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -2848,6 +2885,10 @@ Záznam zmien:</translation>
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>Sťahuje sa %1, čakajte prosím...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3249,6 +3290,10 @@ Záznam zmien:</translation>
<source>Force recheck</source>
<translation>Vynútiť opätovnú kontrolu</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4243,6 +4288,10 @@ Tieto moduly však boli vypnuté.</translation>
<source>Force recheck</source>
<translation>Vynútiť opätovnú kontrolu</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4357,5 +4406,19 @@ Tieto moduly však boli vypnuté.</translation>
<source>Priority</source>
<translation>Priorita</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Dubbelklick i överföringslistan</translation>
<translation type="obsolete">Dubbelklick i överföringslistan</translation>
</message>
<message>
<source>Download list:</source>
@ -607,6 +607,11 @@ p, li { white-space: pre-wrap; }
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation>Simulera µtorrent för att undvika bannlysning (kräver omstart)</translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -1175,7 +1180,7 @@ Are you sure you want to quit qBittorrent?</source>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Nyheter:&lt;/b&gt; &lt;i&gt;(dubbelklicka för att öppna länken i din webbläsare)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Nyheter:&lt;/b&gt; &lt;i&gt;(dubbelklicka för att öppna länken i din webbläsare)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -1197,6 +1202,22 @@ Are you sure you want to quit qBittorrent?</source>
<source>Mark all as read</source>
<translation>Markera alla som lästa</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -1421,7 +1442,7 @@ Are you sure you want to quit qBittorrent?</source>
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Hämta i korrekt ordning (långsammare men bra för förhandsvisning)</translation>
<translation type="obsolete">Hämta i korrekt ordning (långsammare men bra för förhandsvisning)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -1463,6 +1484,22 @@ Are you sure you want to quit qBittorrent?</source>
<source>Expand all</source>
<translation>Fäll ut alla</translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -1591,6 +1628,10 @@ Are you sure you want to quit qBittorrent?</source>
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>Hämtar &quot;%1&quot;, vänta...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -1876,6 +1917,10 @@ Are you sure you want to quit qBittorrent?</source>
<source>Force recheck</source>
<translation>Tvinga återkontroll</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -2503,6 +2548,10 @@ Dock har dessa insticksmoduler blivit inaktiverade.</translation>
<source>Force recheck</source>
<translation>Tvinga återkontroll</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -2597,5 +2646,19 @@ Dock har dessa insticksmoduler blivit inaktiverade.</translation>
<source>Priority</source>
<translation>Prioritet</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -690,7 +690,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Aktarım listesinde çift-tıklamada yapılacak </translation>
<translation type="obsolete">Aktarım listesinde çift-tıklamada yapılacak </translation>
</message>
<message>
<source>Download list:</source>
@ -950,6 +950,11 @@ p, li { white-space: pre-wrap; }
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2340,7 +2345,7 @@ qBittorrent&apos;ten çıkmak istediğinize emin misiniz?</translation>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Haberler:&lt;/b&gt; &lt;i&gt;(bağlantıyı tarayıcınızda açmak için çift tıklayın)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Haberler:&lt;/b&gt; &lt;i&gt;(bağlantıyı tarayıcınızda açmak için çift tıklayın)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -2362,6 +2367,22 @@ qBittorrent&apos;ten çıkmak istediğinize emin misiniz?</translation>
<source>Mark all as read</source>
<translation>Tümünü okunmuş olarak işaretle</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -2735,7 +2756,7 @@ Changelog:
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Doğru düzende indir (yavaş ama önizleme için iyi)</translation>
<translation type="obsolete">Doğru düzende indir (yavaş ama önizleme için iyi)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -2785,6 +2806,22 @@ Changelog:
<source>Expand all</source>
<translation>Tümünü genişlet</translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Bilinmeyen</translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -2913,6 +2950,10 @@ Changelog:
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>&apos;%1&apos; indiriliyor, lütfen bekleyin...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3298,6 +3339,10 @@ Changelog:
<source>Force recheck</source>
<translation>Yeniden denetlemeye çalış</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4229,6 +4274,10 @@ Bununla birlikte, o eklentiler devre dışı.</translation>
<source>Force recheck</source>
<translation>Yeniden denetlemeye çalış</translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4343,5 +4392,19 @@ Bununla birlikte, o eklentiler devre dışı.</translation>
<source>Priority</source>
<translation>Öncelik</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Bilinmeyen</translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -697,11 +697,6 @@ p, li { white-space: pre-wrap; }
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation>Спостерігати за папкою</translation>
</message>
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download list:</source>
<translation type="unfinished"></translation>
@ -935,6 +930,11 @@ p, li { white-space: pre-wrap; }
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2320,7 +2320,7 @@ Are you sure you want to quit qBittorrent?</source>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;Новини:&lt;/b&gt; &lt;i&gt;(подвійний клік відкриє посилання у вашому броузері)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;Новини:&lt;/b&gt; &lt;i&gt;(подвійний клік відкриє посилання у вашому броузері)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -2342,6 +2342,22 @@ Are you sure you want to quit qBittorrent?</source>
<source>Mark all as read</source>
<translation>Позначити всі як прочитані</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -2719,7 +2735,7 @@ Changelog:
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>Завантажувати в правильному порядку (повільніше, але краще для перегляду)</translation>
<translation type="obsolete">Завантажувати в правильному порядку (повільніше, але краще для перегляду)</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -2769,6 +2785,22 @@ Changelog:
<source>Expand all</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Невідомо</translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -2897,6 +2929,10 @@ Changelog:
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3294,6 +3330,10 @@ Changelog:
<source>Force recheck</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4227,6 +4267,10 @@ However, those plugins were disabled.</source>
<source>Force recheck</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4341,5 +4385,19 @@ However, those plugins were disabled.</source>
<source>Priority</source>
<translation>Пріоритет</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Невідомо</translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -771,7 +771,7 @@ folder:</source>
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation></translation>
<translation type="obsolete"></translation>
</message>
<message>
<source>Download list:</source>
@ -997,6 +997,11 @@ folder:</source>
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation>µtorrent名义避免被阻止()</translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -2506,7 +2511,23 @@ link in your web browser)&lt;/i&gt;</source>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;:&lt;/b&gt; &lt;i&gt;(双击以连接到网页浏览器)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;:&lt;/b&gt; &lt;i&gt;(双击以连接到网页浏览器)&lt;/i&gt;</translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
@ -2962,7 +2983,7 @@ previewing)</source>
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation>()</translation>
<translation type="obsolete">()</translation>
</message>
<message>
<source>Collapse all</source>
@ -2976,6 +2997,22 @@ previewing)</source>
<source>Expand all</source>
<translation></translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -3104,6 +3141,10 @@ previewing)</source>
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation>&apos;%1&apos;,...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -3502,6 +3543,10 @@ enabled)</source>
<source>Force recheck</source>
<translation></translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -4528,6 +4573,10 @@ network.</source>
<source>Force recheck</source>
<translation></translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -4647,5 +4696,19 @@ torrent.</source>
<source>This file is either corrupted or this isn&apos;t a torrent.</source>
<translation type="obsolete">torrent文件或已经损坏.</translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

Binary file not shown.

View file

@ -337,7 +337,7 @@ p, li { white-space: pre-wrap; }
<message>
<source>Transfer lists double-click</source>
<comment>qBittorrent will watch a directory and automatically download torrents present in it</comment>
<translation></translation>
<translation type="obsolete"></translation>
</message>
<message>
<source>Download list:</source>
@ -609,6 +609,11 @@ p, li { white-space: pre-wrap; }
<source>Spoof µtorrent to avoid ban (requires restart)</source>
<translation> µtorrent ()</translation>
</message>
<message>
<source>Transfer lists double-click action</source>
<comment>Action executed when doucle-clicking on an item in transfer (download/upload) list</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadingTorrents</name>
@ -1264,7 +1269,7 @@ Are you sure you want to quit qBittorrent?</source>
</message>
<message>
<source>&lt;b&gt;News:&lt;/b&gt; &lt;i&gt;(double-click to open the link in your web browser)&lt;/i&gt;</source>
<translation>&lt;b&gt;:&lt;/b&gt; &lt;i&gt;(雙擊連結從網路瀏覽器打開)&lt;/i&gt;</translation>
<translation type="obsolete">&lt;b&gt;:&lt;/b&gt; &lt;i&gt;(雙擊連結從網路瀏覽器打開)&lt;/i&gt;</translation>
</message>
<message>
<source>Add RSS stream</source>
@ -1286,6 +1291,22 @@ Are you sure you want to quit qBittorrent?</source>
<source>Mark all as read</source>
<translation></translation>
</message>
<message>
<source>&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:&apos;Sans&apos;; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download torrent</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open news URL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RSSImp</name>
@ -1510,7 +1531,7 @@ Are you sure you want to quit qBittorrent?</source>
</message>
<message>
<source>Download in correct order (slower but good for previewing)</source>
<translation> ()</translation>
<translation type="obsolete"> ()</translation>
</message>
<message>
<source>Add to download list in paused state</source>
@ -1552,6 +1573,22 @@ Are you sure you want to quit qBittorrent?</source>
<source>Expand all</source>
<translation></translation>
</message>
<message>
<source>Torrent size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Free disk space:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download in sequential order (slower but good for previewing)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>authentication</name>
@ -1680,6 +1717,10 @@ Are you sure you want to quit qBittorrent?</source>
<comment>e.g: Downloading &apos;xxx.torrent&apos;, please wait...</comment>
<translation> &apos;%1&apos; , ...</translation>
</message>
<message>
<source>&apos;%1&apos; is not a valid magnet URI.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>createTorrentDialog</name>
@ -1977,6 +2018,10 @@ Are you sure you want to quit qBittorrent?</source>
<source>Force recheck</source>
<translation></translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>engineSelect</name>
@ -2612,6 +2657,10 @@ However, those plugins were disabled.</source>
<source>Force recheck</source>
<translation></translation>
</message>
<message>
<source>Copy magnet link</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>subDownloadThread</name>
@ -2706,5 +2755,19 @@ However, those plugins were disabled.</source>
<source>Priority</source>
<translation></translation>
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 left after torrent download)</source>
<comment>e.g. (100MiB left after torrent download)</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>(%1 more are required to download)</source>
<comment>e.g. (100MiB more are required to download)</comment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View file

@ -103,7 +103,7 @@ public:
#ifndef Q_WS_WIN
unsigned long long available;
struct statfs stats;
int ret = statfs ((path+"/.").toUtf8().data(), &stats) ;
int ret = statfs ((path+"/.").toLocal8Bit().data(), &stats) ;
if(ret == 0) {
available = ((unsigned long long)stats.f_bavail) *
((unsigned long long)stats.f_bsize) ;
@ -293,7 +293,7 @@ public:
sha1.assign(base32decode(reg.cap(1).toStdString()));
hash = misc::toQString(sha1);
}
qDebug("magnetUriToHash: hash: %s", hash.toUtf8().data());
qDebug("magnetUriToHash: hash: %s", hash.toLocal8Bit().data());
return hash;
}

View file

@ -2550,7 +2550,7 @@
<number>9999</number>
</property>
<property name="value">
<number>50</number>
<number>100</number>
</property>
</widget>
</item>

View file

@ -53,12 +53,12 @@ properties::properties(QWidget *parent, bittorrent *BTSession, QTorrentHandle &h
setupUi(this);
lbl_priorities->setText(tr("Priorities:")+"<ul><li>"+tr("Ignored: file is not downloaded at all")+"</li><li>"+tr("Normal: normal priority. Download order is dependent on availability")+"</li><li>"+tr("High: higher than normal priority. Pieces are preferred over pieces with the same availability, but not over pieces with lower availability")+"</li><li>"+tr("Maximum: maximum priority, availability is disregarded, the piece is preferred over any other piece with lower priority")+"</li></ul>");
// set icons
addTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/add.png")));
removeTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/remove.png")));
addTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/list-add.png")));
removeTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/list-remove.png")));
lowerTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/downarrow.png")));
riseTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/uparrow.png")));
addWS_button->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/add.png")));
deleteWS_button->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/remove.png")));
addWS_button->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/list-add.png")));
deleteWS_button->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/list-remove.png")));
setAttribute(Qt::WA_DeleteOnClose);
// Set Properties list model
PropListModel = new QStandardItemModel(0,5);

160
src/rss.h
View file

@ -45,6 +45,8 @@
#include <QCryptographicHash>
#include "misc.h"
#include "FeedDownloader.h"
#include "bittorrent.h"
#include "downloadThread.h"
class RssManager;
@ -79,14 +81,16 @@ class RssItem : public QObject {
private:
QString title;
QString link;
QString torrent_url;
QString news_link;
QString description;
QString image;
QString author;
QDateTime date;
QString author;
QString hash;
bool is_valid;
bool read;
QString downloadLink;
protected:
// Ported to Qt4 from KDElibs4
@ -222,29 +226,82 @@ class RssItem : public QObject {
public:
// public constructor
RssItem(const QDomElement& properties) : read(false), downloadLink("none") {
RssItem(const QDomElement& properties): read(false) {
is_valid = false;
torrent_url = QString::null;
news_link = QString::null;
title = QString::null;
QDomElement property = properties.firstChild().toElement();
while(!property.isNull()) {
if (property.tagName() == "title")
if (property.tagName() == "title") {
title = property.text();
if(title.isEmpty()) {
is_valid = false;
return;
}
if(!torrent_url.isEmpty())
is_valid = true;
}
else if (property.tagName() == "enclosure") {
if(property.attribute("type", "") == "application/x-bittorrent") {
torrent_url = property.attribute("url", QString::null);
if(torrent_url.isNull()) {
qDebug("Error: Torrent URL is null");
return;
}
if(!title.isEmpty())
is_valid = true;
}
}
else if (property.tagName() == "link")
link = property.text();
news_link = property.text();
else if (property.tagName() == "description")
description = property.text();
else if (property.tagName() == "image")
image = property.text();
else if (property.tagName() == "pubDate")
date = parseDate(property.text());
else if (property.tagName() == "author")
author = property.text();
property = property.nextSibling().toElement();
}
hash = QCryptographicHash::hash(QByteArray(title.toLocal8Bit())+QByteArray(description.toLocal8Bit()), QCryptographicHash::Md5);
hash = QCryptographicHash::hash(QByteArray(title.toLocal8Bit()), QCryptographicHash::Md5);
}
RssItem(QString _title, QString _torrent_url, QString _news_link, QString _description, QDateTime _date, QString _author, bool _read):
title(_title), torrent_url(_torrent_url), news_link(_news_link), description(_description), date(_date), author(_author), read(_read){
if(!title.isEmpty() && !torrent_url.isEmpty()) {
is_valid = true;
} else {
std::cerr << "ERROR: an invalid RSS item was saved" << std::endl;
is_valid = false;
}
hash = QCryptographicHash::hash(QByteArray(title.toLocal8Bit()), QCryptographicHash::Md5);
}
~RssItem(){
}
QHash<QString, QVariant> toHash() const {
QHash<QString, QVariant> item;
item["title"] = title;
item["torrent_url"] = torrent_url;
item["news_link"] = news_link;
item["description"] = description;
item["date"] = date;
item["author"] = author;
item["read"] = read;
return item;
}
static RssItem* fromHash(QHash<QString, QVariant> h) {
RssItem * item = new RssItem(h["title"].toString(), h["torrent_url"].toString(), h["news_link"].toString(),
h["description"].toString(), h["date"].toDateTime(), h["author"].toString(), h["read"].toBool());
return item;
}
bool isValid() const {
return is_valid;
}
QString getTitle() const{
return title;
}
@ -253,32 +310,28 @@ class RssItem : public QObject {
return author;
}
QString getLink() const{
return link;
QString getTorrentUrl() const{
return torrent_url;
}
QString getHash() const {
return hash;
}
QString getLink() const {
return news_link;
}
QString getDescription() const{
if(description.isEmpty())
return tr("No description available");
return description;
}
QString getImage() const{
return image;
}
QDateTime getDate() const {
return date;
}
QString getDownloadLink() const{
return downloadLink;
}
bool isRead() const{
return read;
}
@ -293,6 +346,7 @@ class RssStream : public QObject{
Q_OBJECT
private:
bittorrent *BTSession;
QString title;
QString link;
QString description;
@ -324,13 +378,21 @@ class RssStream : public QObject{
}
public:
RssStream(QString _url): url(_url), alias(""), iconPath(":/Icons/rss16.png"), refreshed(false), downloadFailure(false), currently_loading(false) {
RssStream(bittorrent *BTSession, QString _url): BTSession(BTSession), url(_url), alias(""), iconPath(":/Icons/rss16.png"), refreshed(false), downloadFailure(false), currently_loading(false) {
qDebug("RSSStream constructed");
}
~RssStream(){
QSettings qBTRSS("qBittorrent-rss");
qBTRSS.setValue(url, getAllReadHashes());
if(refreshed) {
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QVariantList old_items;
foreach(RssItem *item, listItem) {
old_items << item->toHash();
}
QHash<QString, QVariant> all_old_items = qBTRSS.value("old_items", QHash<QString, QVariant>()).toHash();
all_old_items[url] = old_items;
qBTRSS.setValue(url, all_old_items);
}
removeAllItems();
if(QFile::exists(filePath))
QFile::remove(filePath);
@ -338,15 +400,6 @@ class RssStream : public QObject{
QFile::remove(iconPath);
}
QStringList getAllReadHashes() {
QStringList hashes;
foreach(RssItem *item, listItem) {
if(item->isRead())
hashes << item->getHash();
}
return hashes;
}
// delete all the items saved
void removeAllItems() {
qDeleteAll(listItem);
@ -482,10 +535,16 @@ class RssStream : public QObject{
private:
// read and create items from a rss document
short readDoc(const QDomDocument& doc) {
QStringList old_items;
if(!refreshed) {
QSettings qBTRSS("qBittorrent-rss");
old_items = qBTRSS.value(this->url, QVariant()).toStringList();
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QHash<QString, QVariant> all_old_items = qBTRSS.value("old_items", QHash<QString, QVariant>()).toHash();
QVariantList old_items = all_old_items.value(url, QVariantList()).toList();
foreach(const QVariant &var_it, old_items) {
QHash<QString, QVariant> item = var_it.toHash();
RssItem *rss_item = RssItem::fromHash(item);
if(rss_item->isValid())
listItem << rss_item;
}
}
// is it a rss file ?
QDomElement root = doc.documentElement();
@ -518,10 +577,26 @@ class RssStream : public QObject{
image = property.text();
else if(property.tagName() == "item") {
RssItem * item = new RssItem(property);
if(!itemAlreadyExists(item->getHash())) {
if(!refreshed && old_items.contains(item->getHash()))
item->setRead();
if(item->isValid() && !itemAlreadyExists(item->getHash())) {
listItem.append(item);
// Check if the item should be automatically downloaded
FeedFilter * matching_filter = FeedFilters::getFeedFilters(url).matches(item->getTitle());
if(matching_filter != 0) {
// Download the torrent
BTSession->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item->getTorrentUrl()).arg(getAliasOrUrl()));
if(matching_filter->isValid()) {
QString save_path = matching_filter->getSavePath();
if(save_path.isEmpty())
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl());
else
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl(), save_path);
} else {
// All torrents are downloaded from this feed
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl());
}
// Clean up
delete matching_filter;
}
} else {
delete item;
}
@ -555,7 +630,7 @@ class RssStream : public QObject{
void resizeList() {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
unsigned int max_articles = settings.value(QString::fromUtf8("Preferences/RSS/RSSMaxArticlesPerFeed"), 50).toInt();
unsigned int max_articles = settings.value(QString::fromUtf8("Preferences/RSS/RSSMaxArticlesPerFeed"), 100).toInt();
int excess = listItem.size() - max_articles;
if(excess <= 0) return;
for(int i=0; i<excess; ++i){
@ -602,6 +677,7 @@ class RssManager : public QObject{
downloadThread *downloader;
QTimer newsRefresher;
unsigned int refreshInterval;
bittorrent *BTSession;
signals:
void feedInfosChanged(QString url, QString aliasOrUrl, unsigned int nbUnread);
@ -682,7 +758,7 @@ class RssManager : public QObject{
}
public :
RssManager(){
RssManager(bittorrent *BTSession): BTSession(BTSession){
downloader = new downloadThread(this);
connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processFinishedDownload(QString, QString)));
connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
@ -715,7 +791,7 @@ class RssManager : public QObject{
QString url;
unsigned int i = 0;
foreach(url, streamsUrl){
RssStream *stream = new RssStream(url);
RssStream *stream = new RssStream(BTSession, url);
QString alias = aliases.at(i);
if(!alias.isEmpty()) {
stream->setAlias(alias);
@ -760,7 +836,7 @@ class RssManager : public QObject{
qDebug("Not adding the Rss stream because it is already in the list");
return 0;
}
RssStream* stream = new RssStream(url);
RssStream* stream = new RssStream(BTSession, url);
streams[url] = stream;
refresh(url);
return stream;

View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RSS</class>
<widget class="QWidget" name="RSS">
@ -166,7 +167,11 @@
</font>
</property>
<property name="text">
<string>&lt;b>News:&lt;/b> &lt;i>(double-click to open the link in your web browser)&lt;/i></string>
<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:'Sans'; font-size:10pt; 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;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@ -175,7 +180,14 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QListWidget" name="listNews" />
<widget class="QListWidget" name="listNews">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</widget>
<widget class="QTextBrowser" name="textBrowser"/>
</widget>
</item>
@ -214,7 +226,45 @@
<string>Mark all as read</string>
</property>
</action>
<action name="actionDownload_torrent">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/download.png</normaloff>:/Icons/oxygen/download.png</iconset>
</property>
<property name="text">
<string>Download torrent</string>
</property>
</action>
<action name="actionOpen_news_URL">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/url.png</normaloff>:/Icons/url.png</iconset>
</property>
<property name="text">
<string>Open news URL</string>
</property>
</action>
<action name="actionCopy_feed_URL">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/edit-copy.png</normaloff>:/Icons/oxygen/edit-copy.png</iconset>
</property>
<property name="text">
<string>Copy feed URL</string>
</property>
</action>
<action name="actionRSS_feed_downloader">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/Icons/oxygen/download.png</normaloff>:/Icons/oxygen/download.png</iconset>
</property>
<property name="text">
<string>RSS feed downloader</string>
</property>
</action>
</widget>
<resources/>
<resources>
<include location="icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -28,9 +28,6 @@
* Contact : chris@qbittorrent.org arnaud@qbittorrent.org
*/
#include "rss_imp.h"
#include "rss.h"
#include <QDesktopServices>
#include <QInputDialog>
#include <QMenu>
@ -38,23 +35,41 @@
#include <QMessageBox>
#include <QTimer>
#include <QString>
#include <QClipboard>
#include "rss_imp.h"
#include "rss.h"
#include "FeedDownloader.h"
#include "bittorrent.h"
// display a right-click menu
void RSSImp::displayRSSListMenu(const QPoint& pos){
void RSSImp::displayRSSListMenu(const QPoint&){
QMenu myFinishedListMenu(this);
QTreeWidgetItem* item = listStreams->itemAt(pos);
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
if(item != 0) {
if(selectedItems.size() > 0) {
myFinishedListMenu.addAction(actionMark_all_as_read);
myFinishedListMenu.addAction(actionDelete);
if(selectedItems.size() == 1)
if(selectedItems.size() == 1) {
myFinishedListMenu.addAction(actionRename);
myFinishedListMenu.addAction(actionRSS_feed_downloader);
}
myFinishedListMenu.addAction(actionCopy_feed_URL);
myFinishedListMenu.addAction(actionRefresh);
}else{
myFinishedListMenu.addAction(actionCreate);
myFinishedListMenu.addAction(actionRefreshAll);
}
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,33));
myFinishedListMenu.exec(QCursor::pos());
}
void RSSImp::displayItemsListMenu(const QPoint&){
QMenu myItemListMenu(this);
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
if(selectedItems.size() > 0) {
myItemListMenu.addAction(actionDownload_torrent);
myItemListMenu.addAction(actionOpen_news_URL);
}
myItemListMenu.exec(QCursor::pos());
}
// add a stream by a button
@ -95,13 +110,24 @@
refreshAllStreams();
}
void RSSImp::downloadTorrent() {
QList<QListWidgetItem *> selected_items = listNews->selectedItems();
foreach(const QListWidgetItem* item, selected_items) {
RssItem* news = rssmanager->getFeed(selectedFeedUrl)->getItem(listNews->row(item));
BTSession->downloadFromUrl(news->getTorrentUrl());
}
}
// open the url of the news in a browser
void RSSImp::openInBrowser(QListWidgetItem *item) {
void RSSImp::openNewsUrl() {
QList<QListWidgetItem *> selected_items = listNews->selectedItems();
foreach(const QListWidgetItem* item, selected_items) {
RssItem* news = rssmanager->getFeed(selectedFeedUrl)->getItem(listNews->row(item));
QString link = news->getLink();
if(!link.isEmpty())
QDesktopServices::openUrl(QUrl(link));
}
}
//right-click on stream : give him an alias
void RSSImp::renameStream() {
@ -129,6 +155,21 @@
}
}
void RSSImp::copySelectedFeedsURL() {
QStringList URLs;
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
QTreeWidgetItem* item;
foreach(item, selectedItems){
URLs << item->text(1);
}
qApp->clipboard()->setText(URLs.join("\n"));
}
void RSSImp::showFeedDownloader() {
QTreeWidgetItem* item = listStreams->selectedItems()[0];
new FeedDownloaderDlg(this, item->text(1), rssmanager->getFeed(item->text(1))->getAliasOrUrl(), BTSession);
}
void RSSImp::on_actionMark_all_as_read_triggered() {
textBrowser->clear();
listNews->clear();
@ -170,7 +211,12 @@
//right-click, register a new stream
void RSSImp::createStream() {
bool ok;
QString newUrl = QInputDialog::getText(this, tr("Please type a rss stream url"), tr("Stream URL:"), QLineEdit::Normal, "http://", &ok);
QString clip_txt = qApp->clipboard()->text();
QString default_url = "http://";
if(clip_txt.startsWith("http://", Qt::CaseInsensitive) || clip_txt.startsWith("https://", Qt::CaseInsensitive) || clip_txt.startsWith("ftp://", Qt::CaseInsensitive)) {
default_url = clip_txt;
}
QString newUrl = QInputDialog::getText(this, tr("Please type a rss stream url"), tr("Stream URL:"), QLineEdit::Normal, default_url, &ok);
if(ok) {
newUrl = newUrl.trimmed();
if(!newUrl.isEmpty()){
@ -208,12 +254,12 @@
void RSSImp::refreshNewsList(QTreeWidgetItem* item, int) {
selectedFeedUrl = item->text(1);
RssStream *stream = rssmanager->getFeed(selectedFeedUrl);
listNews->clear();
qDebug("Getting the list of news");
QList<RssItem*> news = stream->getNewsList();
// Clear the list first
listNews->clear();
qDebug("Got the list of news");
RssItem* article;
foreach(article, news){
foreach(RssItem* article, news){
QListWidgetItem* it = new QListWidgetItem(article->getTitle(), listNews);
if(article->isRead()){
it->setData(Qt::ForegroundRole, QVariant(QColor("grey")));
@ -224,7 +270,7 @@
}
}
qDebug("Added all news to the GUI");
selectFirstNews();
//selectFirstNews();
qDebug("First news selected");
}
@ -304,7 +350,7 @@
}
}
RSSImp::RSSImp() : QWidget(){
RSSImp::RSSImp(bittorrent *BTSession) : QWidget(), BTSession(BTSession){
setupUi(this);
// icons of bottom buttons
addStream_button->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/subscribe.png")));
@ -321,20 +367,28 @@
// Hide second column (url)
listStreams->hideColumn(1);
rssmanager = new RssManager();
rssmanager = new RssManager(BTSession);
fillFeedsList();
connect(rssmanager, SIGNAL(feedInfosChanged(QString, QString, unsigned int)), this, SLOT(updateFeedInfos(QString, QString, unsigned int)));
connect(rssmanager, SIGNAL(feedIconChanged(QString, QString)), this, SLOT(updateFeedIcon(QString, QString)));
connect(listStreams, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayRSSListMenu(const QPoint&)));
connect(listNews, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayItemsListMenu(const QPoint&)));
connect(actionDelete, SIGNAL(triggered()), this, SLOT(on_delStream_button_clicked()));
connect(actionRename, SIGNAL(triggered()), this, SLOT(renameStream()));
connect(actionRefresh, SIGNAL(triggered()), this, SLOT(refreshSelectedStreams()));
connect(actionCreate, SIGNAL(triggered()), this, SLOT(createStream()));
connect(actionRefreshAll, SIGNAL(triggered()), this, SLOT(refreshAllStreams()));
connect(actionCopy_feed_URL, SIGNAL(triggered()), this, SLOT(copySelectedFeedsURL()));
connect(actionRSS_feed_downloader, SIGNAL(triggered()), this, SLOT(showFeedDownloader()));
connect(actionOpen_news_URL, SIGNAL(triggered()), this, SLOT(openNewsUrl()));
connect(actionDownload_torrent, SIGNAL(triggered()), this, SLOT(downloadTorrent()));
connect(listStreams, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(refreshNewsList(QTreeWidgetItem*,int)));
connect(listNews, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(refreshTextBrowser(QListWidgetItem *)));
connect(listNews, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(openInBrowser(QListWidgetItem *)));
connect(listNews, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(downloadTorrent()));
refreshTimeTimer = new QTimer(this);
connect(refreshTimeTimer, SIGNAL(timeout()), this, SLOT(updateLastRefreshedTimeForStreams()));
refreshTimeTimer->start(60000); // 1min

View file

@ -36,6 +36,7 @@
class QTimer;
class RssManager;
class bittorrent;
class RSSImp : public QWidget, public Ui::RSS{
Q_OBJECT
@ -44,6 +45,7 @@ class RSSImp : public QWidget, public Ui::RSS{
RssManager *rssmanager;
QTimer *refreshTimeTimer;
QString selectedFeedUrl;
bittorrent *BTSession;
public slots:
void on_delStream_button_clicked();
@ -52,8 +54,10 @@ class RSSImp : public QWidget, public Ui::RSS{
void on_addStream_button_clicked();
void on_refreshAll_button_clicked();
void displayRSSListMenu(const QPoint&);
void displayItemsListMenu(const QPoint&);
void renameStream();
void refreshSelectedStreams();
void copySelectedFeedsURL();
void createStream();
void refreshAllStreams();
void refreshNewsList(QTreeWidgetItem* item, int);
@ -61,7 +65,8 @@ class RSSImp : public QWidget, public Ui::RSS{
void updateLastRefreshedTimeForStreams();
void updateFeedIcon(QString url, QString icon_path);
void updateFeedInfos(QString url, QString aliasOrUrl, unsigned int nbUnread);
void openInBrowser(QListWidgetItem *);
void openNewsUrl();
void downloadTorrent();
void fillFeedsList();
void selectFirstFeed();
void selectFirstNews();
@ -69,9 +74,10 @@ class RSSImp : public QWidget, public Ui::RSS{
void on_actionMark_all_as_read_triggered();
void saveSlidersPosition();
void restoreSlidersPosition();
void showFeedDownloader();
public:
RSSImp();
RSSImp(bittorrent *BTSession);
~RSSImp();
QTreeWidgetItem* getTreeItemFromUrl(QString url) const;
};

View file

@ -14,7 +14,7 @@ CONFIG += qt \
network
# Update this VERSION for each release
DEFINES += VERSION=\\\"v1.5.0alpha\\\"
DEFINES += VERSION=\\\"v1.5.0beta1\\\"
DEFINES += VERSION_MAJOR=1
DEFINES += VERSION_MINOR=5
DEFINES += VERSION_BUGFIX=0
@ -183,7 +183,8 @@ HEADERS += GUI.h \
console_imp.h \
ico.h \
stacktrace.h \
torrentPersistentData.h
torrentPersistentData.h \
FeedDownloader.h
FORMS += MainWindow.ui \
options.ui \
about.ui \
@ -201,7 +202,8 @@ FORMS += MainWindow.ui \
engineSelect.ui \
pluginSource.ui \
trackersAdd.ui \
console.ui
console.ui \
FeedDownloader.ui
SOURCES += GUI.cpp \
main.cpp \
options_imp.cpp \

View file

@ -145,7 +145,7 @@ public:
static void saveTorrentPersistentData(QTorrentHandle h, bool is_magnet = false) {
Q_ASSERT(h.is_valid());
qDebug("Saving persistent data for %s", h.hash().toUtf8().data());
qDebug("Saving persistent data for %s", h.hash().toLocal8Bit().data());
// First, remove temp data
TorrentTempData::deleteTempData(h.hash());
Q_ASSERT(!TorrentTempData::hasTempData(h.hash()));
@ -187,7 +187,7 @@ public:
// Save data
all_data[h.hash()] = data;
settings.setValue("torrents", all_data);
qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", h.save_path().toUtf8().data(), h.hash().toUtf8().data());
qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", h.save_path().toLocal8Bit().data(), h.hash().toLocal8Bit().data());
}
static void saveTrackers(QTorrentHandle h) {
@ -233,7 +233,7 @@ public:
data["save_path"] = save_path;
all_data[hash] = data;
settings.setValue("torrents", all_data);
qDebug("TorrentPersistentData: Saving save_path: %s, hash: %s", save_path.toUtf8().data(), hash.toUtf8().data());
qDebug("TorrentPersistentData: Saving save_path: %s, hash: %s", save_path.toLocal8Bit().data(), hash.toLocal8Bit().data());
}
static void saveUrlSeeds(QTorrentHandle h) {
@ -295,7 +295,7 @@ public:
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
QHash<QString, QVariant> data = all_data[hash].toHash();
qDebug("TorrentPersistentData: getSavePath %s", data["save_path"].toString().toUtf8().data());
qDebug("TorrentPersistentData: getSavePath %s", data["save_path"].toString().toLocal8Bit().data());
return data["save_path"].toString();
}