mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-10-22 10:46:04 +03:00
- Rewrited torrent resume code to make it cleaner and more generic
* magnet URI support should be easy to implement now Warning: Since a lot of code was rewrited, some bugs may have been introduced
This commit is contained in:
parent
360a327d7d
commit
2742a54d6e
11 changed files with 1879 additions and 1656 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.5.0
|
||||||
|
- BUGFIX: torrent resume code rewrited
|
||||||
|
|
||||||
* Thu Aug 13 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.4.0
|
* Thu Aug 13 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.4.0
|
||||||
- FEATURE: Display swarm information in lists
|
- FEATURE: Display swarm information in lists
|
||||||
- FEATURE: Allow to define temporary download folder
|
- FEATURE: Allow to define temporary download folder
|
||||||
|
|
405
src/GUI.cpp
405
src/GUI.cpp
|
@ -35,13 +35,13 @@
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
#ifdef QT_4_4
|
#ifdef QT_4_4
|
||||||
#include <QLocalServer>
|
#include <QLocalServer>
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#else
|
#else
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
|
@ -67,6 +67,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "console_imp.h"
|
#include "console_imp.h"
|
||||||
#include "httpserver.h"
|
#include "httpserver.h"
|
||||||
|
#include "torrentPersistentData.h"
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
@ -171,7 +172,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
||||||
// Configure BT session according to options
|
// Configure BT session according to options
|
||||||
configureSession(true);
|
configureSession(true);
|
||||||
// Resume unfinished torrents
|
// Resume unfinished torrents
|
||||||
BTSession->resumeUnfinishedTorrents();
|
BTSession->startUpTorrents();
|
||||||
downloadingTorrentTab->loadLastSortedColumn();
|
downloadingTorrentTab->loadLastSortedColumn();
|
||||||
finishedTorrentTab->loadLastSortedColumn();
|
finishedTorrentTab->loadLastSortedColumn();
|
||||||
// Add torrent given on command line
|
// Add torrent given on command line
|
||||||
|
@ -253,10 +254,10 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
|
||||||
connect(scrapeTimer, SIGNAL(timeout()), this, SLOT(scrapeTrackers()));
|
connect(scrapeTimer, SIGNAL(timeout()), this, SLOT(scrapeTrackers()));
|
||||||
scrapeTimer->start(20000);
|
scrapeTimer->start(20000);
|
||||||
qDebug("GUI Built");
|
qDebug("GUI Built");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
GUI::~GUI() {
|
GUI::~GUI() {
|
||||||
qDebug("GUI destruction");
|
qDebug("GUI destruction");
|
||||||
hide();
|
hide();
|
||||||
// Do this as soon as possible
|
// Do this as soon as possible
|
||||||
|
@ -306,9 +307,9 @@ GUI::~GUI() {
|
||||||
qDebug("4");
|
qDebug("4");
|
||||||
delete BTSession;
|
delete BTSession;
|
||||||
qDebug("5");
|
qDebug("5");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::displayRSSTab(bool enable) {
|
void GUI::displayRSSTab(bool enable) {
|
||||||
if(enable) {
|
if(enable) {
|
||||||
// RSS tab
|
// RSS tab
|
||||||
if(rssWidget == 0) {
|
if(rssWidget == 0) {
|
||||||
|
@ -322,9 +323,9 @@ void GUI::displayRSSTab(bool enable) {
|
||||||
rssWidget = 0;
|
rssWidget = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::scrapeTrackers() {
|
void GUI::scrapeTrackers() {
|
||||||
std::vector<torrent_handle> torrents = BTSession->getTorrents();
|
std::vector<torrent_handle> torrents = BTSession->getTorrents();
|
||||||
std::vector<torrent_handle>::iterator torrentIT;
|
std::vector<torrent_handle>::iterator torrentIT;
|
||||||
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
|
||||||
|
@ -332,9 +333,9 @@ void GUI::scrapeTrackers() {
|
||||||
if(!h.is_valid()) continue;
|
if(!h.is_valid()) continue;
|
||||||
h.scrape_tracker();
|
h.scrape_tracker();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateRatio() {
|
void GUI::updateRatio() {
|
||||||
// Update ratio info
|
// Update ratio info
|
||||||
float ratio = 1.;
|
float ratio = 1.;
|
||||||
session_status sessionStatus = BTSession->getSessionStatus();
|
session_status sessionStatus = BTSession->getSessionStatus();
|
||||||
|
@ -351,34 +352,34 @@ void GUI::updateRatio() {
|
||||||
ratioLbl->setText(tr("Ratio: %1").arg(QString(QByteArray::number(ratio, 'f', 1))));
|
ratioLbl->setText(tr("Ratio: %1").arg(QString(QByteArray::number(ratio, 'f', 1))));
|
||||||
// Update DHT nodes
|
// Update DHT nodes
|
||||||
DHTLbl->setText(tr("DHT: %1 nodes").arg(QString::number(sessionStatus.dht_nodes)));
|
DHTLbl->setText(tr("DHT: %1 nodes").arg(QString::number(sessionStatus.dht_nodes)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionWebsite_triggered() const {
|
void GUI::on_actionWebsite_triggered() const {
|
||||||
QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://www.qbittorrent.org")));
|
QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://www.qbittorrent.org")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionDocumentation_triggered() const {
|
void GUI::on_actionDocumentation_triggered() const {
|
||||||
QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://wiki.qbittorrent.org")));
|
QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://wiki.qbittorrent.org")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionBugReport_triggered() const {
|
void GUI::on_actionBugReport_triggered() const {
|
||||||
QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://bugs.qbittorrent.org")));
|
QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://bugs.qbittorrent.org")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::writeSettings() {
|
void GUI::writeSettings() {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
settings.beginGroup(QString::fromUtf8("MainWindow"));
|
settings.beginGroup(QString::fromUtf8("MainWindow"));
|
||||||
settings.setValue(QString::fromUtf8("size"), size());
|
settings.setValue(QString::fromUtf8("size"), size());
|
||||||
settings.setValue(QString::fromUtf8("pos"), pos());
|
settings.setValue(QString::fromUtf8("pos"), pos());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// called when a torrent has finished
|
// called when a torrent has finished
|
||||||
void GUI::finishedTorrent(QTorrentHandle& h) const {
|
void GUI::finishedTorrent(QTorrentHandle& h) const {
|
||||||
qDebug("In GUI, a torrent has finished");
|
qDebug("In GUI, a torrent has finished");
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
bool show_msg = true;
|
bool show_msg = true;
|
||||||
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+h.hash()+".finished"))
|
if(TorrentPersistentData::isSeed(h.hash()))
|
||||||
show_msg = false;
|
show_msg = false;
|
||||||
QString fileName = h.name();
|
QString fileName = h.name();
|
||||||
bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool();
|
bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool();
|
||||||
|
@ -391,49 +392,49 @@ void GUI::finishedTorrent(QTorrentHandle& h) const {
|
||||||
if(show_msg && systrayIntegration && useNotificationBalloons) {
|
if(show_msg && systrayIntegration && useNotificationBalloons) {
|
||||||
myTrayIcon->showMessage(tr("Download finished"), tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName), QSystemTrayIcon::Information, TIME_TRAY_BALLOON);
|
myTrayIcon->showMessage(tr("Download finished"), tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName), QSystemTrayIcon::Information, TIME_TRAY_BALLOON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::addedTorrent(QTorrentHandle& h) const {
|
void GUI::addedTorrent(QTorrentHandle& h) const {
|
||||||
if(h.is_seed()) {
|
if(h.is_seed()) {
|
||||||
finishedTorrentTab->addTorrent(h.hash());
|
finishedTorrentTab->addTorrent(h.hash());
|
||||||
} else {
|
} else {
|
||||||
downloadingTorrentTab->addTorrent(h.hash());
|
downloadingTorrentTab->addTorrent(h.hash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::pausedTorrent(QTorrentHandle& h) const {
|
void GUI::pausedTorrent(QTorrentHandle& h) const {
|
||||||
if(h.is_seed()) {
|
if(h.is_seed()) {
|
||||||
finishedTorrentTab->pauseTorrent(h.hash());
|
finishedTorrentTab->pauseTorrent(h.hash());
|
||||||
} else {
|
} else {
|
||||||
downloadingTorrentTab->pauseTorrent(h.hash());
|
downloadingTorrentTab->pauseTorrent(h.hash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::resumedTorrent(QTorrentHandle& h) const {
|
void GUI::resumedTorrent(QTorrentHandle& h) const {
|
||||||
if(h.is_seed()) {
|
if(h.is_seed()) {
|
||||||
finishedTorrentTab->updateTorrent(h);
|
finishedTorrentTab->updateTorrent(h);
|
||||||
} else {
|
} else {
|
||||||
downloadingTorrentTab->updateTorrent(h);
|
downloadingTorrentTab->updateTorrent(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::checkedTorrent(QTorrentHandle& h) const {
|
void GUI::checkedTorrent(QTorrentHandle& h) const {
|
||||||
if(h.is_seed()) {
|
if(h.is_seed()) {
|
||||||
// Move torrent to finished tab
|
// Move torrent to finished tab
|
||||||
downloadingTorrentTab->deleteTorrent(h.hash());
|
downloadingTorrentTab->deleteTorrent(h.hash());
|
||||||
finishedTorrentTab->addTorrent(h.hash());
|
finishedTorrentTab->addTorrent(h.hash());
|
||||||
} else {
|
} else {
|
||||||
// Move torrent back to download list (if necessary)
|
// Move torrent back to download list (if necessary)
|
||||||
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+h.hash()+".finished")) {
|
if(TorrentPersistentData::isSeed(h.hash())) {
|
||||||
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+h.hash()+".finished");
|
TorrentPersistentData::saveSeedStatus(h);
|
||||||
finishedTorrentTab->deleteTorrent(h.hash());
|
finishedTorrentTab->deleteTorrent(h.hash());
|
||||||
downloadingTorrentTab->addTorrent(h.hash());
|
downloadingTorrentTab->addTorrent(h.hash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notification when disk is full
|
// Notification when disk is full
|
||||||
void GUI::fullDiskError(QTorrentHandle& h, QString msg) const {
|
void GUI::fullDiskError(QTorrentHandle& h, QString msg) const {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool();
|
bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool();
|
||||||
if(systrayIntegration && useNotificationBalloons) {
|
if(systrayIntegration && useNotificationBalloons) {
|
||||||
|
@ -450,9 +451,9 @@ void GUI::fullDiskError(QTorrentHandle& h, QString msg) const {
|
||||||
downloadingTorrentTab->pauseTorrent(hash);
|
downloadingTorrentTab->pauseTorrent(hash);
|
||||||
}
|
}
|
||||||
BTSession->addConsoleMessage(tr("An error occured (full disk?), '%1' paused.", "e.g: An error occured (full disk?), 'xxx.avi' paused.").arg(h.name()));
|
BTSession->addConsoleMessage(tr("An error occured (full disk?), '%1' paused.", "e.g: An error occured (full disk?), 'xxx.avi' paused.").arg(h.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::createKeyboardShortcuts() {
|
void GUI::createKeyboardShortcuts() {
|
||||||
actionCreate_torrent->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+N")));
|
actionCreate_torrent->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+N")));
|
||||||
actionOpen->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+O")));
|
actionOpen->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+O")));
|
||||||
actionExit->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Q")));
|
actionExit->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Q")));
|
||||||
|
@ -476,36 +477,36 @@ void GUI::createKeyboardShortcuts() {
|
||||||
actionPause_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+P")));
|
actionPause_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+P")));
|
||||||
actionDecreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+-")));
|
actionDecreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+-")));
|
||||||
actionIncreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl++")));
|
actionIncreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl++")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard shortcuts slots
|
// Keyboard shortcuts slots
|
||||||
void GUI::displayDownTab() const {
|
void GUI::displayDownTab() const {
|
||||||
tabs->setCurrentIndex(0);
|
tabs->setCurrentIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::displayUpTab() const {
|
void GUI::displayUpTab() const {
|
||||||
tabs->setCurrentIndex(1);
|
tabs->setCurrentIndex(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::displaySearchTab() const {
|
void GUI::displaySearchTab() const {
|
||||||
tabs->setCurrentIndex(2);
|
tabs->setCurrentIndex(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::displayRSSTab() const {
|
void GUI::displayRSSTab() const {
|
||||||
tabs->setCurrentIndex(3);
|
tabs->setCurrentIndex(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// End of keyboard shortcuts slots
|
// End of keyboard shortcuts slots
|
||||||
|
|
||||||
void GUI::readSettings() {
|
void GUI::readSettings() {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
settings.beginGroup(QString::fromUtf8("MainWindow"));
|
settings.beginGroup(QString::fromUtf8("MainWindow"));
|
||||||
resize(settings.value(QString::fromUtf8("size"), size()).toSize());
|
resize(settings.value(QString::fromUtf8("size"), size()).toSize());
|
||||||
move(settings.value(QString::fromUtf8("pos"), screenCenter()).toPoint());
|
move(settings.value(QString::fromUtf8("pos"), screenCenter()).toPoint());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::balloonClicked() {
|
void GUI::balloonClicked() {
|
||||||
if(isHidden()) {
|
if(isHidden()) {
|
||||||
show();
|
show();
|
||||||
if(isMinimized()) {
|
if(isMinimized()) {
|
||||||
|
@ -514,15 +515,15 @@ void GUI::balloonClicked() {
|
||||||
raise();
|
raise();
|
||||||
activateWindow();
|
activateWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::acceptConnection() {
|
void GUI::acceptConnection() {
|
||||||
clientConnection = localServer->nextPendingConnection();
|
clientConnection = localServer->nextPendingConnection();
|
||||||
connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket()));
|
connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket()));
|
||||||
qDebug("accepted connection from another instance");
|
qDebug("accepted connection from another instance");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::readParamsOnSocket() {
|
void GUI::readParamsOnSocket() {
|
||||||
if(clientConnection) {
|
if(clientConnection) {
|
||||||
QByteArray params = clientConnection->readAll();
|
QByteArray params = clientConnection->readAll();
|
||||||
if(!params.isEmpty()) {
|
if(!params.isEmpty()) {
|
||||||
|
@ -530,28 +531,28 @@ void GUI::readParamsOnSocket() {
|
||||||
qDebug("Received parameters from another instance");
|
qDebug("Received parameters from another instance");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{
|
void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{
|
||||||
// Display a message box
|
// Display a message box
|
||||||
QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason));
|
QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionSet_global_upload_limit_triggered() {
|
void GUI::on_actionSet_global_upload_limit_triggered() {
|
||||||
qDebug("actionSet_global_upload_limit_triggered");
|
qDebug("actionSet_global_upload_limit_triggered");
|
||||||
new BandwidthAllocationDialog(this, true, BTSession, QStringList());
|
new BandwidthAllocationDialog(this, true, BTSession, QStringList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionShow_console_triggered() {
|
void GUI::on_actionShow_console_triggered() {
|
||||||
new consoleDlg(this, BTSession);
|
new consoleDlg(this, BTSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionSet_global_download_limit_triggered() {
|
void GUI::on_actionSet_global_download_limit_triggered() {
|
||||||
qDebug("actionSet_global_download_limit_triggered");
|
qDebug("actionSet_global_download_limit_triggered");
|
||||||
new BandwidthAllocationDialog(this, false, BTSession, QStringList());
|
new BandwidthAllocationDialog(this, false, BTSession, QStringList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionPreview_file_triggered() {
|
void GUI::on_actionPreview_file_triggered() {
|
||||||
QString hash;
|
QString hash;
|
||||||
switch(tabs->currentIndex()){
|
switch(tabs->currentIndex()){
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -565,9 +566,9 @@ void GUI::on_actionPreview_file_triggered() {
|
||||||
}
|
}
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
new previewSelect(this, h);
|
new previewSelect(this, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::openDestinationFolder() const {
|
void GUI::openDestinationFolder() const {
|
||||||
QStringList hashes;
|
QStringList hashes;
|
||||||
switch(tabs->currentIndex()){
|
switch(tabs->currentIndex()){
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -588,9 +589,9 @@ void GUI::openDestinationFolder() const {
|
||||||
QDesktopServices::openUrl(QString("file://")+savePath);
|
QDesktopServices::openUrl(QString("file://")+savePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::goBuyPage() const {
|
void GUI::goBuyPage() const {
|
||||||
QStringList hashes;
|
QStringList hashes;
|
||||||
switch(tabs->currentIndex()){
|
switch(tabs->currentIndex()){
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -607,31 +608,31 @@ void GUI::goBuyPage() const {
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
QDesktopServices::openUrl("http://match.sharemonkey.com/?info_hash="+hash+"&n="+h.name()+"&cid=33");
|
QDesktopServices::openUrl("http://match.sharemonkey.com/?info_hash="+hash+"&n="+h.name()+"&cid=33");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Necessary if we want to close the window
|
// Necessary if we want to close the window
|
||||||
// in one time if "close to systray" is enabled
|
// in one time if "close to systray" is enabled
|
||||||
void GUI::on_actionExit_triggered() {
|
void GUI::on_actionExit_triggered() {
|
||||||
force_exit = true;
|
force_exit = true;
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::previewFile(QString filePath) {
|
void GUI::previewFile(QString filePath) {
|
||||||
QDesktopServices::openUrl(QString("file://")+filePath);
|
QDesktopServices::openUrl(QString("file://")+filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GUI::getCurrentTabIndex() const{
|
int GUI::getCurrentTabIndex() const{
|
||||||
if(isMinimized() || isHidden())
|
if(isMinimized() || isHidden())
|
||||||
return -1;
|
return -1;
|
||||||
return tabs->currentIndex();
|
return tabs->currentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::setTabText(int index, QString text) const {
|
void GUI::setTabText(int index, QString text) const {
|
||||||
tabs->setTabText(index, text);
|
tabs->setTabText(index, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle Main window visibility
|
// Toggle Main window visibility
|
||||||
void GUI::toggleVisibility(QSystemTrayIcon::ActivationReason e) {
|
void GUI::toggleVisibility(QSystemTrayIcon::ActivationReason e) {
|
||||||
if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
|
if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
|
||||||
if(isHidden()) {
|
if(isHidden()) {
|
||||||
show();
|
show();
|
||||||
|
@ -648,10 +649,10 @@ void GUI::toggleVisibility(QSystemTrayIcon::ActivationReason e) {
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center window
|
// Center window
|
||||||
QPoint GUI::screenCenter() const{
|
QPoint GUI::screenCenter() const{
|
||||||
int scrn = 0;
|
int scrn = 0;
|
||||||
QWidget *w = this->topLevelWidget();
|
QWidget *w = this->topLevelWidget();
|
||||||
|
|
||||||
|
@ -664,22 +665,22 @@ QPoint GUI::screenCenter() const{
|
||||||
|
|
||||||
QRect desk(QApplication::desktop()->availableGeometry(scrn));
|
QRect desk(QApplication::desktop()->availableGeometry(scrn));
|
||||||
return QPoint((desk.width() - this->frameGeometry().width()) / 2, (desk.height() - this->frameGeometry().height()) / 2);
|
return QPoint((desk.width() - this->frameGeometry().width()) / 2, (desk.height() - this->frameGeometry().height()) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display About Dialog
|
// Display About Dialog
|
||||||
void GUI::on_actionAbout_triggered() {
|
void GUI::on_actionAbout_triggered() {
|
||||||
//About dialog
|
//About dialog
|
||||||
new about(this);
|
new about(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::showEvent(QShowEvent *e) {
|
void GUI::showEvent(QShowEvent *e) {
|
||||||
qDebug("** Show Event **");
|
qDebug("** Show Event **");
|
||||||
updateLists(true);
|
updateLists(true);
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when we close the program
|
// Called when we close the program
|
||||||
void GUI::closeEvent(QCloseEvent *e) {
|
void GUI::closeEvent(QCloseEvent *e) {
|
||||||
|
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
bool goToSystrayOnExit = settings.value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool();
|
bool goToSystrayOnExit = settings.value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool();
|
||||||
|
@ -715,16 +716,16 @@ void GUI::closeEvent(QCloseEvent *e) {
|
||||||
// Accept exit
|
// Accept exit
|
||||||
e->accept();
|
e->accept();
|
||||||
qApp->exit();
|
qApp->exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Display window to create a torrent
|
// Display window to create a torrent
|
||||||
void GUI::on_actionCreate_torrent_triggered() {
|
void GUI::on_actionCreate_torrent_triggered() {
|
||||||
createtorrent *ct = new createtorrent(this);
|
createtorrent *ct = new createtorrent(this);
|
||||||
connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString)));
|
connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GUI::event(QEvent * e) {
|
bool GUI::event(QEvent * e) {
|
||||||
if(e->type() == QEvent::WindowStateChange) {
|
if(e->type() == QEvent::WindowStateChange) {
|
||||||
//Now check to see if the window is minimised
|
//Now check to see if the window is minimised
|
||||||
if(isMinimized()) {
|
if(isMinimized()) {
|
||||||
|
@ -736,10 +737,10 @@ bool GUI::event(QEvent * e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QMainWindow::event(e);
|
return QMainWindow::event(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action executed when a file is dropped
|
// Action executed when a file is dropped
|
||||||
void GUI::dropEvent(QDropEvent *event) {
|
void GUI::dropEvent(QDropEvent *event) {
|
||||||
event->acceptProposedAction();
|
event->acceptProposedAction();
|
||||||
QStringList files;
|
QStringList files;
|
||||||
if(event->mimeData()->hasUrls()) {
|
if(event->mimeData()->hasUrls()) {
|
||||||
|
@ -769,27 +770,27 @@ void GUI::dropEvent(QDropEvent *event) {
|
||||||
BTSession->addTorrent(file);
|
BTSession->addTorrent(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode if we accept drag 'n drop or not
|
// Decode if we accept drag 'n drop or not
|
||||||
void GUI::dragEnterEvent(QDragEnterEvent *event) {
|
void GUI::dragEnterEvent(QDragEnterEvent *event) {
|
||||||
foreach(const QString &mime, event->mimeData()->formats()){
|
foreach(const QString &mime, event->mimeData()->formats()){
|
||||||
qDebug("mimeData: %s", mime.toLocal8Bit().data());
|
qDebug("mimeData: %s", mime.toLocal8Bit().data());
|
||||||
}
|
}
|
||||||
if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) {
|
if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) {
|
||||||
event->acceptProposedAction();
|
event->acceptProposedAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* *
|
* *
|
||||||
* Torrent *
|
* Torrent *
|
||||||
* *
|
* *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
// Display a dialog to allow user to add
|
// Display a dialog to allow user to add
|
||||||
// torrents to download list
|
// torrents to download list
|
||||||
void GUI::on_actionOpen_triggered() {
|
void GUI::on_actionOpen_triggered() {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
// Open File Open Dialog
|
// Open File Open Dialog
|
||||||
// Note: it is possible to select more than one file
|
// Note: it is possible to select more than one file
|
||||||
|
@ -812,10 +813,10 @@ void GUI::on_actionOpen_triggered() {
|
||||||
top_dir.removeLast();
|
top_dir.removeLast();
|
||||||
settings.setValue(QString::fromUtf8("MainWindowLastDir"), top_dir.join(QDir::separator()));
|
settings.setValue(QString::fromUtf8("MainWindowLastDir"), top_dir.join(QDir::separator()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete from download list AND from hard drive
|
// delete from download list AND from hard drive
|
||||||
void GUI::on_actionDelete_Permanently_triggered() {
|
void GUI::on_actionDelete_Permanently_triggered() {
|
||||||
QStringList hashes;
|
QStringList hashes;
|
||||||
bool inDownloadList = true;
|
bool inDownloadList = true;
|
||||||
switch(tabs->currentIndex()){
|
switch(tabs->currentIndex()){
|
||||||
|
@ -854,16 +855,16 @@ void GUI::on_actionDelete_Permanently_triggered() {
|
||||||
// Remove the torrent
|
// Remove the torrent
|
||||||
BTSession->deleteTorrent(hash, true);
|
BTSession->deleteTorrent(hash, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::deleteTorrent(QString hash) {
|
void GUI::deleteTorrent(QString hash) {
|
||||||
// Delete item from list
|
// Delete item from list
|
||||||
downloadingTorrentTab->deleteTorrent(hash);
|
downloadingTorrentTab->deleteTorrent(hash);
|
||||||
finishedTorrentTab->deleteTorrent(hash);
|
finishedTorrentTab->deleteTorrent(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete selected items in the list
|
// delete selected items in the list
|
||||||
void GUI::on_actionDelete_triggered() {
|
void GUI::on_actionDelete_triggered() {
|
||||||
QStringList hashes;
|
QStringList hashes;
|
||||||
bool inDownloadList = true;
|
bool inDownloadList = true;
|
||||||
switch(tabs->currentIndex()){
|
switch(tabs->currentIndex()){
|
||||||
|
@ -906,13 +907,13 @@ void GUI::on_actionDelete_triggered() {
|
||||||
// Remove the torrent
|
// Remove the torrent
|
||||||
BTSession->deleteTorrent(hash, false);
|
BTSession->deleteTorrent(hash, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As program parameters, we can get paths or urls.
|
// As program parameters, we can get paths or urls.
|
||||||
// This function parse the parameters and call
|
// This function parse the parameters and call
|
||||||
// the right addTorrent function, considering
|
// the right addTorrent function, considering
|
||||||
// the parameter type.
|
// the parameter type.
|
||||||
void GUI::processParams(const QStringList& params) {
|
void GUI::processParams(const QStringList& params) {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
|
bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
|
||||||
foreach(QString param, params) {
|
foreach(QString param, params) {
|
||||||
|
@ -928,13 +929,13 @@ void GUI::processParams(const QStringList& params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::addTorrent(QString path) {
|
void GUI::addTorrent(QString path) {
|
||||||
BTSession->addTorrent(path);
|
BTSession->addTorrent(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::processDownloadedFiles(QString path, QString url) {
|
void GUI::processDownloadedFiles(QString path, QString url) {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
|
bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
|
||||||
if(useTorrentAdditionDialog) {
|
if(useTorrentAdditionDialog) {
|
||||||
|
@ -943,10 +944,10 @@ void GUI::processDownloadedFiles(QString path, QString url) {
|
||||||
}else{
|
}else{
|
||||||
BTSession->addTorrent(path, false, url);
|
BTSession->addTorrent(path, false, url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set BT session configuration
|
// Set BT session configuration
|
||||||
void GUI::configureSession(bool deleteOptions) {
|
void GUI::configureSession(bool deleteOptions) {
|
||||||
qDebug("Configuring session");
|
qDebug("Configuring session");
|
||||||
// General
|
// General
|
||||||
bool new_displaySpeedInTitle = options->speedInTitleBar();
|
bool new_displaySpeedInTitle = options->speedInTitleBar();
|
||||||
|
@ -1214,20 +1215,20 @@ void GUI::configureSession(bool deleteOptions) {
|
||||||
options->deleteLater();
|
options->deleteLater();
|
||||||
}
|
}
|
||||||
qDebug("Session configured");
|
qDebug("Session configured");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateUnfinishedTorrentNumber(unsigned int nb) {
|
void GUI::updateUnfinishedTorrentNumber(unsigned int nb) {
|
||||||
unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb();
|
unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb();
|
||||||
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
|
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateFinishedTorrentNumber(unsigned int nb) {
|
void GUI::updateFinishedTorrentNumber(unsigned int nb) {
|
||||||
unsigned int paused = BTSession->getFinishedPausedTorrentsNb();
|
unsigned int paused = BTSession->getFinishedPausedTorrentsNb();
|
||||||
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
|
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow to change action on double-click
|
// Allow to change action on double-click
|
||||||
void GUI::torrentDoubleClicked(QString hash, bool finished) {
|
void GUI::torrentDoubleClicked(QString hash, bool finished) {
|
||||||
int action;
|
int action;
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
@ -1256,10 +1257,10 @@ void GUI::torrentDoubleClicked(QString hash, bool finished) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle paused state of selected torrent
|
// Toggle paused state of selected torrent
|
||||||
void GUI::togglePausedState(QString hash) {
|
void GUI::togglePausedState(QString hash) {
|
||||||
if(tabs->currentIndex() > 1) return;
|
if(tabs->currentIndex() > 1) return;
|
||||||
bool inDownloadList = true;
|
bool inDownloadList = true;
|
||||||
if(tabs->currentIndex() == 1)
|
if(tabs->currentIndex() == 1)
|
||||||
|
@ -1282,10 +1283,10 @@ void GUI::togglePausedState(QString hash) {
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause All Downloads in DL list
|
// Pause All Downloads in DL list
|
||||||
void GUI::on_actionPause_All_triggered() {
|
void GUI::on_actionPause_All_triggered() {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
std::vector<torrent_handle> torrents = BTSession->getTorrents();
|
std::vector<torrent_handle> torrents = BTSession->getTorrents();
|
||||||
std::vector<torrent_handle>::iterator torrentIT;
|
std::vector<torrent_handle>::iterator torrentIT;
|
||||||
|
@ -1300,9 +1301,9 @@ void GUI::on_actionPause_All_triggered() {
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionIncreasePriority_triggered() {
|
void GUI::on_actionIncreasePriority_triggered() {
|
||||||
if(tabs->currentIndex() != 0)
|
if(tabs->currentIndex() != 0)
|
||||||
return;
|
return;
|
||||||
QStringList hashes = downloadingTorrentTab->getSelectedTorrents();
|
QStringList hashes = downloadingTorrentTab->getSelectedTorrents();
|
||||||
|
@ -1310,19 +1311,19 @@ void GUI::on_actionIncreasePriority_triggered() {
|
||||||
BTSession->increaseDlTorrentPriority(hash);
|
BTSession->increaseDlTorrentPriority(hash);
|
||||||
}
|
}
|
||||||
updateLists();
|
updateLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::on_actionDecreasePriority_triggered() {
|
void GUI::on_actionDecreasePriority_triggered() {
|
||||||
Q_ASSERT(tabs->currentIndex() == 0);
|
Q_ASSERT(tabs->currentIndex() == 0);
|
||||||
QStringList hashes = downloadingTorrentTab->getSelectedTorrents();
|
QStringList hashes = downloadingTorrentTab->getSelectedTorrents();
|
||||||
foreach(const QString &hash, hashes) {
|
foreach(const QString &hash, hashes) {
|
||||||
BTSession->decreaseDlTorrentPriority(hash);
|
BTSession->decreaseDlTorrentPriority(hash);
|
||||||
}
|
}
|
||||||
updateLists();
|
updateLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
// pause selected items in the list
|
// pause selected items in the list
|
||||||
void GUI::on_actionPause_triggered() {
|
void GUI::on_actionPause_triggered() {
|
||||||
bool inDownloadList = true;
|
bool inDownloadList = true;
|
||||||
if(tabs->currentIndex() > 1) return;
|
if(tabs->currentIndex() > 1) return;
|
||||||
if(tabs->currentIndex() == 1)
|
if(tabs->currentIndex() == 1)
|
||||||
|
@ -1345,10 +1346,10 @@ void GUI::on_actionPause_triggered() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resume All Downloads in DL list
|
// Resume All Downloads in DL list
|
||||||
void GUI::on_actionStart_All_triggered() {
|
void GUI::on_actionStart_All_triggered() {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
std::vector<torrent_handle> torrents = BTSession->getTorrents();
|
std::vector<torrent_handle> torrents = BTSession->getTorrents();
|
||||||
std::vector<torrent_handle>::iterator torrentIT;
|
std::vector<torrent_handle>::iterator torrentIT;
|
||||||
|
@ -1363,10 +1364,10 @@ void GUI::on_actionStart_All_triggered() {
|
||||||
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
|
||||||
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start selected items in the list
|
// start selected items in the list
|
||||||
void GUI::on_actionStart_triggered() {
|
void GUI::on_actionStart_triggered() {
|
||||||
bool inDownloadList = true;
|
bool inDownloadList = true;
|
||||||
if(tabs->currentIndex() > 1) return;
|
if(tabs->currentIndex() > 1) return;
|
||||||
if(tabs->currentIndex() == 1)
|
if(tabs->currentIndex() == 1)
|
||||||
|
@ -1389,17 +1390,17 @@ void GUI::on_actionStart_triggered() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker) {
|
void GUI::addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker) {
|
||||||
// Trackers whose authentication was cancelled
|
// Trackers whose authentication was cancelled
|
||||||
if(unauthenticated_trackers.indexOf(tracker) < 0) {
|
if(unauthenticated_trackers.indexOf(tracker) < 0) {
|
||||||
unauthenticated_trackers << tracker;
|
unauthenticated_trackers << tracker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// display properties of selected items
|
// display properties of selected items
|
||||||
void GUI::on_actionTorrent_Properties_triggered() {
|
void GUI::on_actionTorrent_Properties_triggered() {
|
||||||
if(tabs->currentIndex() > 1) return;
|
if(tabs->currentIndex() > 1) return;
|
||||||
switch(tabs->currentIndex()){
|
switch(tabs->currentIndex()){
|
||||||
case 1: // DL List
|
case 1: // DL List
|
||||||
|
@ -1408,9 +1409,9 @@ void GUI::on_actionTorrent_Properties_triggered() {
|
||||||
default:
|
default:
|
||||||
downloadingTorrentTab->propertiesSelection();
|
downloadingTorrentTab->propertiesSelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateLists(bool force) {
|
void GUI::updateLists(bool force) {
|
||||||
if(isVisible() || force) {
|
if(isVisible() || force) {
|
||||||
// update global informations
|
// update global informations
|
||||||
dlSpeedLbl->setText(tr("DL: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))));
|
dlSpeedLbl->setText(tr("DL: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))));
|
||||||
|
@ -1428,7 +1429,7 @@ void GUI::updateLists(bool force) {
|
||||||
if(downloadingTorrentTab->updateTorrent(h)) {
|
if(downloadingTorrentTab->updateTorrent(h)) {
|
||||||
// Torrent was added, we may need to remove it from finished tab
|
// Torrent was added, we may need to remove it from finished tab
|
||||||
finishedTorrentTab->deleteTorrent(h.hash());
|
finishedTorrentTab->deleteTorrent(h.hash());
|
||||||
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+h.hash()+".finished");
|
TorrentPersistentData::saveSeedStatus(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1438,19 +1439,19 @@ void GUI::updateLists(bool force) {
|
||||||
QString up_rate = QByteArray::number(BTSession->getSessionStatus().payload_upload_rate/1024, 'f', 1);
|
QString up_rate = QByteArray::number(BTSession->getSessionStatus().payload_upload_rate/1024, 'f', 1);
|
||||||
setWindowTitle(tr("qBittorrent %1 (DL: %2KiB/s, UP: %3KiB/s)", "%1 is qBittorrent version").arg(QString::fromUtf8(VERSION)).arg(dl_rate).arg(up_rate));
|
setWindowTitle(tr("qBittorrent %1 (DL: %2KiB/s, UP: %3KiB/s)", "%1 is qBittorrent version").arg(QString::fromUtf8(VERSION)).arg(dl_rate).arg(up_rate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when a tracker requires authentication
|
// Called when a tracker requires authentication
|
||||||
void GUI::trackerAuthenticationRequired(QTorrentHandle& h) {
|
void GUI::trackerAuthenticationRequired(QTorrentHandle& h) {
|
||||||
if(unauthenticated_trackers.indexOf(QPair<QTorrentHandle,QString>(h, h.current_tracker())) < 0) {
|
if(unauthenticated_trackers.indexOf(QPair<QTorrentHandle,QString>(h, h.current_tracker())) < 0) {
|
||||||
// Tracker login
|
// Tracker login
|
||||||
new trackerLogin(this, h);
|
new trackerLogin(this, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check connection status and display right icon
|
// Check connection status and display right icon
|
||||||
void GUI::checkConnectionStatus() {
|
void GUI::checkConnectionStatus() {
|
||||||
// qDebug("Checking connection status");
|
// qDebug("Checking connection status");
|
||||||
// Update Ratio
|
// Update Ratio
|
||||||
updateRatio();
|
updateRatio();
|
||||||
// update global informations
|
// update global informations
|
||||||
|
@ -1482,25 +1483,25 @@ void GUI::checkConnectionStatus() {
|
||||||
connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png")));
|
connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png")));
|
||||||
connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection status:")+QString::fromUtf8("</b><br>")+QString::fromUtf8("<i>")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("</i>"));
|
connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection status:")+QString::fromUtf8("</b><br>")+QString::fromUtf8("<i>")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("</i>"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* *
|
* *
|
||||||
* Utils *
|
* Utils *
|
||||||
* *
|
* *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
void GUI::downloadFromURLList(const QStringList& urls) {
|
void GUI::downloadFromURLList(const QStringList& urls) {
|
||||||
BTSession->downloadFromURLList(urls);
|
BTSession->downloadFromURLList(urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* *
|
* *
|
||||||
* Options *
|
* Options *
|
||||||
* *
|
* *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
void GUI::createSystrayDelayed() {
|
void GUI::createSystrayDelayed() {
|
||||||
static int timeout = 10;
|
static int timeout = 10;
|
||||||
if(QSystemTrayIcon::isSystemTrayAvailable()) {
|
if(QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
// Ok, systray integration is now supported
|
// Ok, systray integration is now supported
|
||||||
|
@ -1519,14 +1520,14 @@ void GUI::createSystrayDelayed() {
|
||||||
delete systrayCreator;
|
delete systrayCreator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::createTrayIcon() {
|
void GUI::createTrayIcon() {
|
||||||
// Tray icon
|
// Tray icon
|
||||||
#ifdef Q_WS_WIN
|
#ifdef Q_WS_WIN
|
||||||
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent16.png")), this);
|
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent16.png")), this);
|
||||||
#endif
|
#endif
|
||||||
#ifndef Q_WS_WIN
|
#ifndef Q_WS_WIN
|
||||||
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent22.png")), this);
|
myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent22.png")), this);
|
||||||
#endif
|
#endif
|
||||||
// Tray icon Menu
|
// Tray icon Menu
|
||||||
|
@ -1546,17 +1547,17 @@ void GUI::createTrayIcon() {
|
||||||
// End of Icon Menu
|
// End of Icon Menu
|
||||||
connect(myTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason)));
|
connect(myTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason)));
|
||||||
myTrayIcon->show();
|
myTrayIcon->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display Program Options
|
// Display Program Options
|
||||||
void GUI::on_actionOptions_triggered() {
|
void GUI::on_actionOptions_triggered() {
|
||||||
options = new options_imp(this);
|
options = new options_imp(this);
|
||||||
connect(options, SIGNAL(status_changed(bool)), this, SLOT(OptionsSaved(bool)));
|
connect(options, SIGNAL(status_changed(bool)), this, SLOT(OptionsSaved(bool)));
|
||||||
options->show();
|
options->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is executed each time options are saved
|
// Is executed each time options are saved
|
||||||
void GUI::OptionsSaved(bool deleteOptions) {
|
void GUI::OptionsSaved(bool deleteOptions) {
|
||||||
BTSession->addConsoleMessage(tr("Options were saved successfully."));
|
BTSession->addConsoleMessage(tr("Options were saved successfully."));
|
||||||
bool newSystrayIntegration = options->systrayIntegration();
|
bool newSystrayIntegration = options->systrayIntegration();
|
||||||
if(newSystrayIntegration != systrayIntegration) {
|
if(newSystrayIntegration != systrayIntegration) {
|
||||||
|
@ -1581,9 +1582,9 @@ void GUI::OptionsSaved(bool deleteOptions) {
|
||||||
}
|
}
|
||||||
// Update session
|
// Update session
|
||||||
configureSession(deleteOptions);
|
configureSession(deleteOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GUI::initWebUi(QString username, QString password, int port) {
|
bool GUI::initWebUi(QString username, QString password, int port) {
|
||||||
if(httpServer)
|
if(httpServer)
|
||||||
httpServer->close();
|
httpServer->close();
|
||||||
else
|
else
|
||||||
|
@ -1595,17 +1596,17 @@ bool GUI::initWebUi(QString username, QString password, int port) {
|
||||||
else
|
else
|
||||||
QMessageBox::critical(this, "Web User Interface Error", "Unable to initialize HTTP Server on port " + misc::toQString(port));
|
QMessageBox::critical(this, "Web User Interface Error", "Unable to initialize HTTP Server on port " + misc::toQString(port));
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* *
|
* *
|
||||||
* HTTP Downloader *
|
* HTTP Downloader *
|
||||||
* *
|
* *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
// Display an input dialog to prompt user for
|
// Display an input dialog to prompt user for
|
||||||
// an url
|
// an url
|
||||||
void GUI::on_actionDownload_from_URL_triggered() {
|
void GUI::on_actionDownload_from_URL_triggered() {
|
||||||
downloadFromURL *downloadFromURLDialog = new downloadFromURL(this);
|
downloadFromURL *downloadFromURLDialog = new downloadFromURL(this);
|
||||||
connect(downloadFromURLDialog, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&)));
|
connect(downloadFromURLDialog, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ class arborescence {
|
||||||
Q_ASSERT(root->getSize() == t->total_size());
|
Q_ASSERT(root->getSize() == t->total_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
arborescence(torrent_info const& t, std::vector<size_type> fp, int *prioritiesTab) {
|
arborescence(torrent_info const& t, std::vector<size_type> fp, std::vector<int> files_priority) {
|
||||||
torrent_info::file_iterator fi = t.begin_files();
|
torrent_info::file_iterator fi = t.begin_files();
|
||||||
if(t.num_files() > 1) {
|
if(t.num_files() > 1) {
|
||||||
qDebug("More than one file in the torrent, setting a folder as root");
|
qDebug("More than one file in the torrent, setting a folder as root");
|
||||||
|
@ -207,13 +207,13 @@ class arborescence {
|
||||||
} else {
|
} else {
|
||||||
// XXX: Will crash if there is no file in torrent
|
// XXX: Will crash if there is no file in torrent
|
||||||
qDebug("one file in the torrent, setting it as root with index 0");
|
qDebug("one file in the torrent, setting it as root with index 0");
|
||||||
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, ((double)fp[0])/t.file_at(0).size, prioritiesTab[0]);
|
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, ((double)fp[0])/t.file_at(0).size, files_priority.at(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(fi != t.end_files()) {
|
while(fi != t.end_files()) {
|
||||||
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
||||||
addFile(path, fi->size, i, ((double)fp[i])/t.file_at(i).size, prioritiesTab[i]);
|
addFile(path, fi->size, i, ((double)fp[i])/t.file_at(i).size, files_priority.at(i));
|
||||||
fi++;
|
fi++;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "downloadThread.h"
|
#include "downloadThread.h"
|
||||||
#include "filterParserThread.h"
|
#include "filterParserThread.h"
|
||||||
|
#include "torrentPersistentData.h"
|
||||||
#include <libtorrent/extensions/ut_metadata.hpp>
|
#include <libtorrent/extensions/ut_metadata.hpp>
|
||||||
#include <libtorrent/extensions/ut_pex.hpp>
|
#include <libtorrent/extensions/ut_pex.hpp>
|
||||||
#include <libtorrent/extensions/smart_ban.hpp>
|
#include <libtorrent/extensions/smart_ban.hpp>
|
||||||
|
@ -281,6 +282,7 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
||||||
foreach(const QString &file, files) {
|
foreach(const QString &file, files) {
|
||||||
torrentBackup.remove(file);
|
torrentBackup.remove(file);
|
||||||
}
|
}
|
||||||
|
TorrentPersistentData::deletePersistentData(hash);
|
||||||
// Remove tracker errors
|
// Remove tracker errors
|
||||||
trackersErrors.remove(hash);
|
trackersErrors.remove(hash);
|
||||||
if(permanent)
|
if(permanent)
|
||||||
|
@ -333,11 +335,7 @@ void bittorrent::resumeTorrent(QString hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::loadWebSeeds(QString hash) {
|
void bittorrent::loadWebSeeds(QString hash) {
|
||||||
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
|
QVariantList url_seeds = TorrentPersistentData::getUrlSeeds(hash);
|
||||||
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
|
||||||
QByteArray urlseeds_lines = urlseeds_file.readAll();
|
|
||||||
urlseeds_file.close();
|
|
||||||
QList<QByteArray> url_seeds = urlseeds_lines.split('\n');
|
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
// First remove from the torrent the url seeds that were deleted
|
// First remove from the torrent the url seeds that were deleted
|
||||||
// in a previous session
|
// in a previous session
|
||||||
|
@ -352,7 +350,8 @@ void bittorrent::loadWebSeeds(QString hash) {
|
||||||
h.remove_url_seed(existing_seed);
|
h.remove_url_seed(existing_seed);
|
||||||
}
|
}
|
||||||
// Add the ones that were added in a previous session
|
// Add the ones that were added in a previous session
|
||||||
foreach(const QByteArray &url_seed, url_seeds) {
|
foreach(const QVariant &var_url_seed, url_seeds) {
|
||||||
|
QString url_seed = var_url_seed.toString();
|
||||||
if(!url_seed.isEmpty()) {
|
if(!url_seed.isEmpty()) {
|
||||||
// XXX: Should we check if it is already in the list before adding it
|
// XXX: Should we check if it is already in the list before adding it
|
||||||
// or is libtorrent clever enough to know
|
// or is libtorrent clever enough to know
|
||||||
|
@ -362,11 +361,12 @@ void bittorrent::loadWebSeeds(QString hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a torrent to the bittorrent session
|
// Add a torrent to the bittorrent session
|
||||||
QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool) {
|
QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) {
|
||||||
QTorrentHandle h;
|
QTorrentHandle h;
|
||||||
bool fastResume=false;
|
bool fastResume=false;
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||||
QString file, dest_file;
|
QString file, dest_file, hash;
|
||||||
|
boost::intrusive_ptr<torrent_info> t;
|
||||||
|
|
||||||
// Checking if BT_backup Dir exists
|
// Checking if BT_backup Dir exists
|
||||||
// create it if it is not
|
// create it if it is not
|
||||||
|
@ -382,8 +382,8 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
Q_ASSERT(!file.startsWith("http://", Qt::CaseInsensitive) && !file.startsWith("https://", Qt::CaseInsensitive) && !file.startsWith("ftp://", Qt::CaseInsensitive));
|
Q_ASSERT(!file.startsWith("http://", Qt::CaseInsensitive) && !file.startsWith("https://", Qt::CaseInsensitive) && !file.startsWith("ftp://", Qt::CaseInsensitive));
|
||||||
|
|
||||||
qDebug("Adding %s to download list", file.toLocal8Bit().data());
|
qDebug("Adding %s to download list", file.toLocal8Bit().data());
|
||||||
boost::intrusive_ptr<torrent_info> t;
|
|
||||||
try {
|
try {
|
||||||
// Getting torrent file informations
|
// Getting torrent file informations
|
||||||
t = new torrent_info(file.toLocal8Bit().data());
|
t = new torrent_info(file.toLocal8Bit().data());
|
||||||
|
@ -405,7 +405,7 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
}
|
}
|
||||||
qDebug(" -> Hash: %s", misc::toString(t->info_hash()).c_str());
|
qDebug(" -> Hash: %s", misc::toString(t->info_hash()).c_str());
|
||||||
qDebug(" -> Name: %s", t->name().c_str());
|
qDebug(" -> Name: %s", t->name().c_str());
|
||||||
QString hash = misc::toQString(t->info_hash());
|
hash = misc::toQString(t->info_hash());
|
||||||
if(file.startsWith(torrentBackup.path())) {
|
if(file.startsWith(torrentBackup.path())) {
|
||||||
QFileInfo fi(file);
|
QFileInfo fi(file);
|
||||||
QString old_hash = fi.baseName();
|
QString old_hash = fi.baseName();
|
||||||
|
@ -436,21 +436,17 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
add_torrent_params p;
|
add_torrent_params p;
|
||||||
//Getting fast resume data if existing
|
//Getting fast resume data if existing
|
||||||
std::vector<char> buf;
|
std::vector<char> buf;
|
||||||
|
if(resumed) {
|
||||||
qDebug("Trying to load fastresume data: %s", (torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data());
|
qDebug("Trying to load fastresume data: %s", (torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data());
|
||||||
if (load_file((torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data(), buf) == 0) {
|
if (load_file((torrentBackup.path()+QDir::separator()+hash+QString(".fastresume")).toLocal8Bit().data(), buf) == 0) {
|
||||||
fastResume = true;
|
fastResume = true;
|
||||||
p.resume_data = &buf;
|
p.resume_data = &buf;
|
||||||
qDebug("Successfuly loaded");
|
qDebug("Successfuly loaded");
|
||||||
}
|
}
|
||||||
QString savePath = getSavePath(hash);
|
|
||||||
// Save save_path to hard drive
|
|
||||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
|
||||||
if(!savepath_file.exists()) {
|
|
||||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
savepath_file.write(savePath.toLocal8Bit());
|
|
||||||
savepath_file.close();
|
|
||||||
}
|
}
|
||||||
if(defaultTempPath.isEmpty() || QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".finished"))) {
|
QString savePath = getSavePath(hash);
|
||||||
|
qDebug("addTorrent: using save_path: %s", savePath.toUtf8().data());
|
||||||
|
if(defaultTempPath.isEmpty() || (resumed && TorrentPersistentData::isSeed(hash))) {
|
||||||
p.save_path = savePath.toLocal8Bit().data();
|
p.save_path = savePath.toLocal8Bit().data();
|
||||||
} else {
|
} else {
|
||||||
p.save_path = defaultTempPath.toLocal8Bit().data();
|
p.save_path = defaultTempPath.toLocal8Bit().data();
|
||||||
|
@ -485,16 +481,26 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
h.set_max_uploads(maxUploadsPerTorrent);
|
h.set_max_uploads(maxUploadsPerTorrent);
|
||||||
// Load filtered files
|
// Load filtered files
|
||||||
loadFilesPriorities(h);
|
loadFilesPriorities(h);
|
||||||
|
if(resumed) {
|
||||||
// Load custom url seeds
|
// Load custom url seeds
|
||||||
loadWebSeeds(hash);
|
loadWebSeeds(hash);
|
||||||
// Load speed limit from hard drive
|
// Load speed limit from hard drive
|
||||||
loadTorrentSpeedLimits(hash);
|
loadTorrentSpeedLimits(hash);
|
||||||
// Load trackers
|
// Load trackers
|
||||||
bool loaded_trackers = loadTrackerFile(hash);
|
|
||||||
// Doing this to order trackers well
|
|
||||||
if(!loaded_trackers) {
|
|
||||||
saveTrackerFile(hash);
|
|
||||||
loadTrackerFile(hash);
|
loadTrackerFile(hash);
|
||||||
|
} else {
|
||||||
|
// Sequential download
|
||||||
|
if(TorrentTempData::hasTempData(hash)) {
|
||||||
|
qDebug("addTorrent: Setting download as sequential (from tmp data)");
|
||||||
|
h.set_sequential_download(TorrentTempData::isSequential(hash));
|
||||||
|
}
|
||||||
|
// Save persistent data for new torrent
|
||||||
|
TorrentPersistentData::saveTorrentPersistentData(h);
|
||||||
|
// Save save_path
|
||||||
|
if(!defaultTempPath.isEmpty()) {
|
||||||
|
qDebug("addTorrent: Saving save_path in persistent data: %s", savePath.toUtf8().data());
|
||||||
|
TorrentPersistentData::saveSavePath(hash, savePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QString newFile = torrentBackup.path() + QDir::separator() + hash + ".torrent";
|
QString newFile = torrentBackup.path() + QDir::separator() + hash + ".torrent";
|
||||||
if(file != newFile) {
|
if(file != newFile) {
|
||||||
|
@ -504,11 +510,6 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
// Copy it to torrentBackup directory
|
// Copy it to torrentBackup directory
|
||||||
QFile::copy(file, newFile);
|
QFile::copy(file, newFile);
|
||||||
}
|
}
|
||||||
// Incremental download
|
|
||||||
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")) {
|
|
||||||
qDebug("Incremental download enabled for %s", t->name().c_str());
|
|
||||||
h.set_sequential_download(true);
|
|
||||||
}
|
|
||||||
if(!addInPause && !fastResume) {
|
if(!addInPause && !fastResume) {
|
||||||
// Start torrent because it was added in paused state
|
// Start torrent because it was added in paused state
|
||||||
h.resume();
|
h.resume();
|
||||||
|
@ -535,27 +536,17 @@ QTorrentHandle bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check in .priorities file if the user filtered files
|
// Check if the user filtered files in this torrent.
|
||||||
// in this torrent.
|
|
||||||
bool bittorrent::has_filtered_files(QString hash) const{
|
bool bittorrent::has_filtered_files(QString hash) const{
|
||||||
QFile pieces_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".priorities");
|
QVariantList files_priority = TorrentPersistentData::getFilesPriority(hash);
|
||||||
// Read saved file
|
foreach(QVariant var_prio, files_priority) {
|
||||||
if(!pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
int priority = var_prio.toInt();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QByteArray pieces_text = pieces_file.readAll();
|
|
||||||
pieces_file.close();
|
|
||||||
QList<QByteArray> pieces_priorities_list = pieces_text.split('\n');
|
|
||||||
unsigned int listSize = pieces_priorities_list.size();
|
|
||||||
for(unsigned int i=0; i<listSize-1; ++i) {
|
|
||||||
int priority = pieces_priorities_list.at(i).toInt();
|
|
||||||
if( priority < 0 || priority > 7) {
|
if( priority < 0 || priority > 7) {
|
||||||
priority = 1;
|
priority = 1;
|
||||||
}
|
}
|
||||||
if(!priority) {
|
if(!priority)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,7 +706,7 @@ void bittorrent::saveTorrentSpeedLimits(QString hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::loadTorrentSpeedLimits(QString hash) {
|
void bittorrent::loadTorrentSpeedLimits(QString hash) {
|
||||||
// qDebug("Loading speedLimits file for %s", hash.toLocal8Bit().data());
|
// qDebug("Loading speedLimits file for %s", hash.toLocal8Bit().data());
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
QFile speeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".speedLimits");
|
QFile speeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".speedLimits");
|
||||||
if(!speeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if(!speeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
@ -732,7 +723,7 @@ void bittorrent::loadTorrentSpeedLimits(QString hash) {
|
||||||
h.set_upload_limit(speeds.at(1).toInt());
|
h.set_upload_limit(speeds.at(1).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read pieces priorities from .priorities file
|
// Read pieces priorities from hard disk
|
||||||
// and ask QTorrentHandle to consider them
|
// and ask QTorrentHandle to consider them
|
||||||
void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
||||||
qDebug("Applying pieces priorities");
|
qDebug("Applying pieces priorities");
|
||||||
|
@ -740,31 +731,19 @@ void bittorrent::loadFilesPriorities(QTorrentHandle &h) {
|
||||||
qDebug("/!\\ Error: Invalid handle");
|
qDebug("/!\\ Error: Invalid handle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned int nbFiles = h.num_files();
|
|
||||||
QString hash = h.hash();
|
|
||||||
QFile pieces_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".priorities");
|
|
||||||
if(!pieces_file.exists()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Read saved file
|
|
||||||
if(!pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
qDebug("* Error: Couldn't open priorities file: %s", hash.toLocal8Bit().data());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QByteArray pieces_priorities = pieces_file.readAll();
|
|
||||||
pieces_file.close();
|
|
||||||
QList<QByteArray> pieces_priorities_list = pieces_priorities.split('\n');
|
|
||||||
if((unsigned int)pieces_priorities_list.size() != nbFiles+1) {
|
|
||||||
std::cerr << "* Error: Corrupted priorities file\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::vector<int> v;
|
std::vector<int> v;
|
||||||
for(unsigned int i=0; i<nbFiles; ++i) {
|
QVariantList files_priority;
|
||||||
int priority = pieces_priorities_list.at(i).toInt();
|
if(TorrentTempData::hasTempData(h.hash())) {
|
||||||
|
files_priority = TorrentTempData::getFilesPriority(h.hash());
|
||||||
|
} else {
|
||||||
|
files_priority = TorrentPersistentData::getFilesPriority(h.hash());
|
||||||
|
}
|
||||||
|
foreach(const QVariant &var_prio, files_priority) {
|
||||||
|
int priority = var_prio.toInt();
|
||||||
if( priority < 0 || priority > 7) {
|
if( priority < 0 || priority > 7) {
|
||||||
priority = 1;
|
priority = 1;
|
||||||
}
|
}
|
||||||
qDebug("Setting piece piority to %d", priority);
|
qDebug("Setting file piority to %d", priority);
|
||||||
v.push_back(priority);
|
v.push_back(priority);
|
||||||
}
|
}
|
||||||
h.prioritize_files(v);
|
h.prioritize_files(v);
|
||||||
|
@ -800,7 +779,7 @@ void bittorrent::saveFastResumeData() {
|
||||||
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
QTorrentHandle h = QTorrentHandle(*torrentIT);
|
||||||
if(!h.is_valid() || !h.has_metadata()) continue;
|
if(!h.is_valid() || !h.has_metadata()) continue;
|
||||||
if(isQueueingEnabled())
|
if(isQueueingEnabled())
|
||||||
saveTorrentPriority(h.hash(), h.queue_position());
|
TorrentPersistentData::savePriority(h);
|
||||||
if(h.is_paused()) continue;
|
if(h.is_paused()) continue;
|
||||||
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) continue;
|
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) continue;
|
||||||
h.save_resume_data();
|
h.save_resume_data();
|
||||||
|
@ -912,6 +891,10 @@ void bittorrent::setDefaultSavePath(QString savepath) {
|
||||||
defaultSavePath = savepath;
|
defaultSavePath = savepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bittorrent::useTemporaryFolder() const {
|
||||||
|
return !defaultTempPath.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
void bittorrent::setDefaultTempPath(QString temppath) {
|
void bittorrent::setDefaultTempPath(QString temppath) {
|
||||||
if(defaultTempPath == temppath)
|
if(defaultTempPath == temppath)
|
||||||
return;
|
return;
|
||||||
|
@ -938,6 +921,11 @@ void bittorrent::setDefaultTempPath(QString temppath) {
|
||||||
defaultTempPath = temppath;
|
defaultTempPath = temppath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bittorrent::saveTrackerFile(QString hash) {
|
||||||
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
|
TorrentPersistentData::saveTrackers(h);
|
||||||
|
}
|
||||||
|
|
||||||
// Enable directory scanning
|
// Enable directory scanning
|
||||||
void bittorrent::enableDirectoryScanning(QString scan_dir) {
|
void bittorrent::enableDirectoryScanning(QString scan_dir) {
|
||||||
if(!scan_dir.isEmpty()) {
|
if(!scan_dir.isEmpty()) {
|
||||||
|
@ -1032,46 +1020,21 @@ void bittorrent::setDeleteRatio(float ratio) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bittorrent::loadTrackerFile(QString hash) {
|
void bittorrent::loadTrackerFile(QString hash) {
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
QHash<QString, QVariant> tiers = TorrentPersistentData::getTrackers(hash);
|
||||||
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
|
|
||||||
if(!tracker_file.exists()) return false;
|
|
||||||
tracker_file.open(QIODevice::ReadOnly | QIODevice::Text);
|
|
||||||
QStringList lines = QString::fromUtf8(tracker_file.readAll().data()).split("\n");
|
|
||||||
std::vector<announce_entry> trackers;
|
std::vector<announce_entry> trackers;
|
||||||
foreach(const QString &line, lines) {
|
foreach(const QString tracker_url, tiers.keys()) {
|
||||||
QStringList parts = line.split("|");
|
announce_entry t(tracker_url.toStdString());
|
||||||
if(parts.size() != 2) continue;
|
t.tier = tiers[tracker_url].toInt();
|
||||||
announce_entry t(parts[0].toStdString());
|
|
||||||
t.tier = parts[1].toInt();
|
|
||||||
trackers.push_back(t);
|
trackers.push_back(t);
|
||||||
}
|
}
|
||||||
if(!trackers.empty()) {
|
if(!trackers.empty()) {
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
h.replace_trackers(trackers);
|
h.replace_trackers(trackers);
|
||||||
h.force_reannounce();
|
h.force_reannounce();
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::saveTrackerFile(QString hash) {
|
|
||||||
qDebug("Saving tracker file for %s", hash.toLocal8Bit().data());
|
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
|
||||||
QFile tracker_file(torrentBackup.path()+QDir::separator()+ hash + ".trackers");
|
|
||||||
if(tracker_file.exists()) {
|
|
||||||
tracker_file.remove();
|
|
||||||
}
|
|
||||||
tracker_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
|
||||||
std::vector<announce_entry> trackers = h.trackers();
|
|
||||||
for(unsigned int i=0; i<trackers.size(); ++i) {
|
|
||||||
tracker_file.write(QByteArray(trackers[i].url.c_str())+QByteArray("|")+QByteArray(misc::toString(i).c_str())+QByteArray("\n"));
|
|
||||||
}
|
|
||||||
tracker_file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set DHT port (>= 1000 or 0 if same as BT)
|
// Set DHT port (>= 1000 or 0 if same as BT)
|
||||||
void bittorrent::setDHTPort(int dht_port) {
|
void bittorrent::setDHTPort(int dht_port) {
|
||||||
if(dht_port == 0 or dht_port >= 1000) {
|
if(dht_port == 0 or dht_port >= 1000) {
|
||||||
|
@ -1149,10 +1112,8 @@ void bittorrent::readAlerts() {
|
||||||
if(h.is_valid()){
|
if(h.is_valid()){
|
||||||
emit finishedTorrent(h);
|
emit finishedTorrent(h);
|
||||||
QString hash = h.hash();
|
QString hash = h.hash();
|
||||||
// Create .finished file if necessary
|
// Remember finished state
|
||||||
QFile finished_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished");
|
TorrentPersistentData::saveSeedStatus(h);
|
||||||
finished_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
finished_file.close();
|
|
||||||
// Move to download directory if necessary
|
// Move to download directory if necessary
|
||||||
if(!defaultTempPath.isEmpty()) {
|
if(!defaultTempPath.isEmpty()) {
|
||||||
// Check if directory is different
|
// Check if directory is different
|
||||||
|
@ -1284,17 +1245,17 @@ session_status bittorrent::getSessionStatus() const{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString bittorrent::getSavePath(QString hash) {
|
QString bittorrent::getSavePath(QString hash) {
|
||||||
QFile savepath_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".savepath");
|
|
||||||
QByteArray line;
|
|
||||||
QString savePath;
|
QString savePath;
|
||||||
if(savepath_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if(TorrentTempData::hasTempData(hash)) {
|
||||||
line = savepath_file.readAll();
|
savePath = TorrentTempData::getSavePath(hash);
|
||||||
savepath_file.close();
|
qDebug("getSavePath, got save_path from temp data: %s", savePath.toUtf8().data());
|
||||||
qDebug(" -> Save path: %s", line.data());
|
} else {
|
||||||
savePath = QString::fromUtf8(line.data());
|
savePath = TorrentPersistentData::getSavePath(hash);
|
||||||
}else{
|
qDebug("getSavePath, got save_path from persistent data: %s", savePath.toUtf8().data());
|
||||||
// use default save path
|
}
|
||||||
qDebug("Using default save path because none was set");
|
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());
|
||||||
savePath = defaultSavePath;
|
savePath = defaultSavePath;
|
||||||
}
|
}
|
||||||
// Checking if savePath Dir exists
|
// Checking if savePath Dir exists
|
||||||
|
@ -1383,42 +1344,23 @@ void bittorrent::applyEncryptionSettings(pe_settings se) {
|
||||||
s->set_pe_settings(se);
|
s->set_pe_settings(se);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::saveTorrentPriority(QString hash, int prio) {
|
|
||||||
// Write .queued file
|
|
||||||
QFile prio_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".prio");
|
|
||||||
prio_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
prio_file.write(QByteArray::number(prio));
|
|
||||||
prio_file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Will fast resume torrents in
|
// Will fast resume torrents in
|
||||||
// backup directory
|
// backup directory
|
||||||
void bittorrent::resumeUnfinishedTorrents() {
|
void bittorrent::startUpTorrents() {
|
||||||
qDebug("Resuming unfinished torrents");
|
qDebug("Resuming unfinished torrents");
|
||||||
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
|
||||||
QStringList fileNames;
|
QStringList fileNames;
|
||||||
// Scan torrentBackup directory
|
QStringList known_torrents = TorrentPersistentData::knownTorrents();
|
||||||
QStringList filters;
|
|
||||||
filters << "*.torrent";
|
|
||||||
fileNames = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted);
|
|
||||||
if(isQueueingEnabled()) {
|
if(isQueueingEnabled()) {
|
||||||
QList<QPair<int, QString> > filePaths;
|
QList<QPair<int, QString> > filePaths;
|
||||||
foreach(const QString &fileName, fileNames) {
|
foreach(const QString &hash, known_torrents) {
|
||||||
QString filePath = torrentBackup.path()+QDir::separator()+fileName;
|
QString filePath;
|
||||||
int prio = 99999;
|
if(TorrentPersistentData::isMagnet(hash)) {
|
||||||
// Get priority
|
filePath = TorrentPersistentData::getMagnetUri(hash);
|
||||||
QString prioPath = filePath;
|
} else {
|
||||||
prioPath.replace(".torrent", ".prio");
|
filePath = torrentBackup.path()+QDir::separator()+hash+".torrent";
|
||||||
if(QFile::exists(prioPath)) {
|
|
||||||
QFile prio_file(prioPath);
|
|
||||||
if(prio_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
bool ok = false;
|
|
||||||
prio = prio_file.readAll().toInt(&ok);
|
|
||||||
if(!ok)
|
|
||||||
prio = 99999;
|
|
||||||
prio_file.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
int prio = TorrentPersistentData::getPriority(hash);
|
||||||
misc::insertSort2<QString>(filePaths, qMakePair(prio, filePath));
|
misc::insertSort2<QString>(filePaths, qMakePair(prio, filePath));
|
||||||
}
|
}
|
||||||
// Resume downloads
|
// Resume downloads
|
||||||
|
|
|
@ -107,6 +107,7 @@ class bittorrent : public QObject {
|
||||||
QStringList getConsoleMessages() const;
|
QStringList getConsoleMessages() const;
|
||||||
QStringList getPeerBanMessages() const;
|
QStringList getPeerBanMessages() const;
|
||||||
qlonglong getETA(QString hash) const;
|
qlonglong getETA(QString hash) const;
|
||||||
|
bool useTemporaryFolder() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
||||||
|
@ -115,11 +116,12 @@ class bittorrent : public QObject {
|
||||||
void downloadFromUrl(QString url);
|
void downloadFromUrl(QString url);
|
||||||
void downloadFromURLList(const QStringList& url_list);
|
void downloadFromURLList(const QStringList& url_list);
|
||||||
void deleteTorrent(QString hash, bool permanent = false);
|
void deleteTorrent(QString hash, bool permanent = false);
|
||||||
|
void startUpTorrents();
|
||||||
/* Needed by Web UI */
|
/* Needed by Web UI */
|
||||||
void pauseAllTorrents();
|
void pauseAllTorrents();
|
||||||
void resumeAllTorrents();
|
|
||||||
void pauseTorrent(QString hash);
|
void pauseTorrent(QString hash);
|
||||||
void resumeTorrent(QString hash);
|
void resumeTorrent(QString hash);
|
||||||
|
void resumeAllTorrents();
|
||||||
/* End Web UI */
|
/* End Web UI */
|
||||||
void saveDHTEntry();
|
void saveDHTEntry();
|
||||||
void preAllocateAllFiles(bool b);
|
void preAllocateAllFiles(bool b);
|
||||||
|
@ -129,8 +131,6 @@ class bittorrent : public QObject {
|
||||||
void enableIPFilter(QString filter);
|
void enableIPFilter(QString filter);
|
||||||
void disableIPFilter();
|
void disableIPFilter();
|
||||||
void setQueueingEnabled(bool enable);
|
void setQueueingEnabled(bool enable);
|
||||||
void resumeUnfinishedTorrents();
|
|
||||||
void saveTorrentPriority(QString hash, int prio);
|
|
||||||
void saveTorrentSpeedLimits(QString hash);
|
void saveTorrentSpeedLimits(QString hash);
|
||||||
void loadTorrentSpeedLimits(QString hash);
|
void loadTorrentSpeedLimits(QString hash);
|
||||||
void handleDownloadFailure(QString url, QString reason);
|
void handleDownloadFailure(QString url, QString reason);
|
||||||
|
@ -164,12 +164,12 @@ class bittorrent : public QObject {
|
||||||
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
||||||
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
||||||
void processDownloadedFile(QString, QString);
|
void processDownloadedFile(QString, QString);
|
||||||
|
void saveTrackerFile(QString hash);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void scanDirectory(QString);
|
void scanDirectory(QString);
|
||||||
void readAlerts();
|
void readAlerts();
|
||||||
bool loadTrackerFile(QString hash);
|
void loadTrackerFile(QString hash);
|
||||||
void saveTrackerFile(QString hash);
|
|
||||||
void deleteBigRatios();
|
void deleteBigRatios();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "realprogressbar.h"
|
#include "realprogressbar.h"
|
||||||
#include "realprogressbarthread.h"
|
#include "realprogressbarthread.h"
|
||||||
#include "TrackersAdditionDlg.h"
|
#include "TrackersAdditionDlg.h"
|
||||||
|
#include "torrentPersistentData.h"
|
||||||
|
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
@ -86,7 +87,7 @@ properties::properties(QWidget *parent, bittorrent *BTSession, QTorrentHandle &h
|
||||||
// get Infos from torrent handle
|
// get Infos from torrent handle
|
||||||
fileName->setText(h.name());
|
fileName->setText(h.name());
|
||||||
// Torrent Infos
|
// Torrent Infos
|
||||||
save_path->setText(h.save_path());
|
save_path->setText(TorrentPersistentData::getSavePath(hash));
|
||||||
QString author = h.creator().trimmed();
|
QString author = h.creator().trimmed();
|
||||||
if(author.isEmpty())
|
if(author.isEmpty())
|
||||||
author = tr("Unknown");
|
author = tr("Unknown");
|
||||||
|
@ -115,23 +116,18 @@ properties::properties(QWidget *parent, bittorrent *BTSession, QTorrentHandle &h
|
||||||
shareRatio->setText(QString(QByteArray::number(ratio, 'f', 1)));
|
shareRatio->setText(QString(QByteArray::number(ratio, 'f', 1)));
|
||||||
std::vector<size_type> fp;
|
std::vector<size_type> fp;
|
||||||
h.file_progress(fp);
|
h.file_progress(fp);
|
||||||
int *prioritiesTab = loadPiecesPriorities();
|
std::vector<int> files_priority = loadFilesPriorities();
|
||||||
// List files in torrent
|
// List files in torrent
|
||||||
arborescence *arb = new arborescence(h.get_torrent_info(), fp, prioritiesTab);
|
arborescence *arb = new arborescence(h.get_torrent_info(), fp, files_priority);
|
||||||
addFilesToTree(arb->getRoot(), PropListModel->invisibleRootItem());
|
addFilesToTree(arb->getRoot(), PropListModel->invisibleRootItem());
|
||||||
delete arb;
|
delete arb;
|
||||||
delete prioritiesTab;
|
|
||||||
connect(PropListModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updatePriorities(QStandardItem*)));
|
connect(PropListModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updatePriorities(QStandardItem*)));
|
||||||
filesList->expandAll();
|
filesList->expandAll();
|
||||||
// List web seeds
|
// List web seeds
|
||||||
loadWebSeedsFromFile();
|
loadWebSeedsFromFile();
|
||||||
loadWebSeeds();
|
loadWebSeeds();
|
||||||
// Incremental download
|
// Incremental download
|
||||||
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")){
|
incrementalDownload->setChecked(TorrentPersistentData::isSequentialDownload(hash));
|
||||||
incrementalDownload->setChecked(true);
|
|
||||||
}else{
|
|
||||||
incrementalDownload->setChecked(false);
|
|
||||||
}
|
|
||||||
updateInfosTimer = new QTimer(this);
|
updateInfosTimer = new QTimer(this);
|
||||||
connect(updateInfosTimer, SIGNAL(timeout()), this, SLOT(updateInfos()));
|
connect(updateInfosTimer, SIGNAL(timeout()), this, SLOT(updateInfos()));
|
||||||
updateInfosTimer->start(3000);
|
updateInfosTimer->start(3000);
|
||||||
|
@ -314,41 +310,19 @@ void properties::loadWebSeeds(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int* properties::loadPiecesPriorities(){
|
std::vector<int> properties::loadFilesPriorities(){
|
||||||
unsigned int nbFiles = h.num_files();
|
std::vector<int> fp;
|
||||||
int *prioritiesTab = new int[nbFiles];
|
QVariantList files_priority = TorrentPersistentData::getFilesPriority(hash);
|
||||||
QString fileName = h.name();
|
foreach(const QVariant &var_prio, files_priority) {
|
||||||
QFile pieces_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".priorities");
|
int priority = var_prio.toInt();
|
||||||
has_filtered_files = false;
|
|
||||||
qDebug("Loading pieces priorities");
|
|
||||||
// Read saved file
|
|
||||||
if(!pieces_file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
|
||||||
qDebug("Could not find pieces file");
|
|
||||||
for(unsigned int i=0; i<nbFiles; ++i)
|
|
||||||
prioritiesTab[i] = NORMAL;
|
|
||||||
return prioritiesTab;
|
|
||||||
}
|
|
||||||
QByteArray pieces_text = pieces_file.readAll();
|
|
||||||
pieces_file.close();
|
|
||||||
QList<QByteArray> pieces_priority_list = pieces_text.split('\n');
|
|
||||||
if((unsigned int)pieces_priority_list.size() != nbFiles+1){
|
|
||||||
std::cerr << "Error: Corrupted pieces file\n";
|
|
||||||
for(unsigned int i=0; i<nbFiles; ++i)
|
|
||||||
prioritiesTab[i] = NORMAL;
|
|
||||||
return prioritiesTab;
|
|
||||||
}
|
|
||||||
for(unsigned int i=0; i<nbFiles; ++i){
|
|
||||||
int priority = pieces_priority_list.at(i).toInt();
|
|
||||||
if( priority < 0 || priority > 7){
|
if( priority < 0 || priority > 7){
|
||||||
// Normal priority as default
|
// Normal priority as default
|
||||||
priority = 1;
|
priority = 1;
|
||||||
}
|
}
|
||||||
if(!priority){
|
fp.push_back(priority);
|
||||||
has_filtered_files = true;
|
|
||||||
}
|
}
|
||||||
prioritiesTab[i] = priority;
|
|
||||||
}
|
return fp;
|
||||||
return prioritiesTab;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool properties::allFiltered() const {
|
bool properties::allFiltered() const {
|
||||||
|
@ -494,7 +468,7 @@ void properties::askWebSeed(){
|
||||||
}
|
}
|
||||||
urlSeeds << url_seed;
|
urlSeeds << url_seed;
|
||||||
h.add_url_seed(url_seed);
|
h.add_url_seed(url_seed);
|
||||||
saveWebSeeds();
|
TorrentPersistentData::saveUrlSeeds(h);
|
||||||
// Refresh the seeds list
|
// Refresh the seeds list
|
||||||
loadWebSeeds();
|
loadWebSeeds();
|
||||||
}
|
}
|
||||||
|
@ -536,7 +510,7 @@ void properties::deleteSelectedUrlSeeds(){
|
||||||
}
|
}
|
||||||
if(change){
|
if(change){
|
||||||
// Save them to disk
|
// Save them to disk
|
||||||
saveWebSeeds();
|
TorrentPersistentData::saveUrlSeeds(h);
|
||||||
// Refresh list
|
// Refresh list
|
||||||
loadWebSeeds();
|
loadWebSeeds();
|
||||||
}
|
}
|
||||||
|
@ -672,19 +646,16 @@ void properties::setAllPiecesState(unsigned short priority){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void properties::on_incrementalDownload_stateChanged(int){
|
void properties::on_incrementalDownload_stateChanged(int state){
|
||||||
qDebug("Incremental download toggled");
|
qDebug("Incremental download toggled");
|
||||||
if(incrementalDownload->isChecked()){
|
if(state == Qt::Checked){
|
||||||
if(!QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".incremental"))) {
|
if(!TorrentPersistentData::isSequentialDownload(hash)) {
|
||||||
// Create .incremental file
|
|
||||||
QFile incremental_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".incremental"));
|
|
||||||
incremental_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
incremental_file.close();
|
|
||||||
h.set_sequential_download(true);
|
h.set_sequential_download(true);
|
||||||
|
TorrentPersistentData::saveSequentialStatus(h);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental");
|
|
||||||
h.set_sequential_download(false);
|
h.set_sequential_download(false);
|
||||||
|
TorrentPersistentData::saveSequentialStatus(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,11 +677,9 @@ void properties::on_changeSavePathButton_clicked() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Save savepath
|
// Save savepath
|
||||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
TorrentPersistentData::saveSavePath(hash, savePath.path());
|
||||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
savepath_file.write(savePath.path().toLocal8Bit());
|
|
||||||
savepath_file.close();
|
|
||||||
// Actually move storage
|
// Actually move storage
|
||||||
|
if(!BTSession->useTemporaryFolder() || h.is_seed())
|
||||||
h.move_storage(savePath.path());
|
h.move_storage(savePath.path());
|
||||||
// Update save_path in dialog
|
// Update save_path in dialog
|
||||||
save_path->setText(savePath.path());
|
save_path->setText(savePath.path());
|
||||||
|
@ -723,13 +692,10 @@ void properties::on_okButton_clicked(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void properties::loadWebSeedsFromFile(){
|
void properties::loadWebSeedsFromFile(){
|
||||||
QFile urlseeds_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".urlseeds");
|
|
||||||
if(!urlseeds_file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
|
||||||
QByteArray urlseeds_lines = urlseeds_file.readAll();
|
|
||||||
urlseeds_file.close();
|
|
||||||
QList<QByteArray> url_seeds = urlseeds_lines.split('\n');
|
|
||||||
urlSeeds.clear();
|
urlSeeds.clear();
|
||||||
foreach(const QByteArray &url_seed, url_seeds){
|
QVariantList url_seeds = TorrentPersistentData::getUrlSeeds(hash);
|
||||||
|
foreach(const QVariant &var_url_seed, url_seeds){
|
||||||
|
QString url_seed = var_url_seed.toString();
|
||||||
if(!url_seed.isEmpty())
|
if(!url_seed.isEmpty())
|
||||||
urlSeeds << url_seed;
|
urlSeeds << url_seed;
|
||||||
}
|
}
|
||||||
|
@ -743,19 +709,6 @@ void properties::loadWebSeedsFromFile(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void properties::saveWebSeeds(){
|
|
||||||
QFile urlseeds_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".urlseeds"));
|
|
||||||
if(!urlseeds_file.open(QIODevice::WriteOnly | QIODevice::Text)){
|
|
||||||
std::cerr << "Error: Could not save url seeds\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach(const QString &url_seed, urlSeeds){
|
|
||||||
urlseeds_file.write((url_seed+"\n").toLocal8Bit());
|
|
||||||
}
|
|
||||||
urlseeds_file.close();
|
|
||||||
qDebug("url seeds were saved");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool properties::savePiecesPriorities() {
|
bool properties::savePiecesPriorities() {
|
||||||
if(!changedFilteredfiles) return true;
|
if(!changedFilteredfiles) return true;
|
||||||
if(allFiltered()) {
|
if(allFiltered()) {
|
||||||
|
@ -763,30 +716,15 @@ bool properties::savePiecesPriorities() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qDebug("Saving pieces priorities");
|
qDebug("Saving pieces priorities");
|
||||||
bool hasFilteredFiles = false;
|
|
||||||
QString fileName = h.name();
|
|
||||||
QFile pieces_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".priorities"));
|
|
||||||
// First, remove old file
|
|
||||||
pieces_file.remove();
|
|
||||||
int *priorities = new int[h.get_torrent_info().num_files()];
|
int *priorities = new int[h.get_torrent_info().num_files()];
|
||||||
getPriorities(PropListModel->invisibleRootItem(), priorities);
|
getPriorities(PropListModel->invisibleRootItem(), priorities);
|
||||||
// Ok, we have priorities, save them
|
|
||||||
if(!pieces_file.open(QIODevice::WriteOnly | QIODevice::Text)){
|
|
||||||
std::cerr << "Error: Could not save pieces priorities\n";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
unsigned int nbFiles = h.get_torrent_info().num_files();
|
unsigned int nbFiles = h.get_torrent_info().num_files();
|
||||||
for(unsigned int i=0; i<nbFiles; ++i) {
|
for(unsigned int i=0; i<nbFiles; ++i) {
|
||||||
if(!priorities[i]) {
|
h.file_priority(i, priorities[i]);
|
||||||
hasFilteredFiles = true;
|
|
||||||
}
|
}
|
||||||
pieces_file.write(misc::toQByteArray(priorities[i])+misc::toQByteArray("\n"));
|
|
||||||
}
|
|
||||||
pieces_file.close();
|
|
||||||
delete[] priorities;
|
delete[] priorities;
|
||||||
BTSession->loadFilesPriorities(h);
|
TorrentPersistentData::saveFilesPriority(h);
|
||||||
// Emit a signal so that the GUI updates the size
|
// Emit a signal so that the GUI updates the size
|
||||||
emit filteredFilesChanged(hash);
|
emit filteredFilesChanged(hash);
|
||||||
has_filtered_files = hasFilteredFiles;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,6 @@ class properties : public QDialog, private Ui::properties{
|
||||||
PropListDelegate *PropDelegate;
|
PropListDelegate *PropDelegate;
|
||||||
QStandardItemModel *PropListModel;
|
QStandardItemModel *PropListModel;
|
||||||
QTimer *updateInfosTimer;
|
QTimer *updateInfosTimer;
|
||||||
bool has_filtered_files;
|
|
||||||
QStringList urlSeeds;
|
QStringList urlSeeds;
|
||||||
RealProgressBar *progressBar;
|
RealProgressBar *progressBar;
|
||||||
RealProgressBarThread *progressBarUpdater;
|
RealProgressBarThread *progressBarUpdater;
|
||||||
|
@ -79,7 +78,6 @@ class properties : public QDialog, private Ui::properties{
|
||||||
void maximumSelection();
|
void maximumSelection();
|
||||||
void loadWebSeeds();
|
void loadWebSeeds();
|
||||||
void askWebSeed();
|
void askWebSeed();
|
||||||
void saveWebSeeds();
|
|
||||||
void loadWebSeedsFromFile();
|
void loadWebSeedsFromFile();
|
||||||
void deleteSelectedUrlSeeds();
|
void deleteSelectedUrlSeeds();
|
||||||
void addFilesToTree(const torrent_file *root, QStandardItem *parent);
|
void addFilesToTree(const torrent_file *root, QStandardItem *parent);
|
||||||
|
@ -103,7 +101,7 @@ class properties : public QDialog, private Ui::properties{
|
||||||
~properties();
|
~properties();
|
||||||
bool allFiltered() const;
|
bool allFiltered() const;
|
||||||
bool savePiecesPriorities();
|
bool savePiecesPriorities();
|
||||||
int* loadPiecesPriorities();
|
std::vector<int> loadFilesPriorities();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPoint screenCenter() const;
|
QPoint screenCenter() const;
|
||||||
|
|
|
@ -241,6 +241,11 @@ torrent_status::state_t QTorrentHandle::state() const {
|
||||||
return h.status().state;
|
return h.status().state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<int> QTorrentHandle::file_priorities() const {
|
||||||
|
Q_ASSERT(h.is_valid());
|
||||||
|
return h.file_priorities();
|
||||||
|
}
|
||||||
|
|
||||||
QString QTorrentHandle::creator() const {
|
QString QTorrentHandle::creator() const {
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
return misc::toQString(h.get_torrent_info().creator());
|
return misc::toQString(h.get_torrent_info().creator());
|
||||||
|
@ -325,6 +330,11 @@ int QTorrentHandle::active_time() const {
|
||||||
return h.status().active_time;
|
return h.status().active_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QTorrentHandle::is_sequential_download() const {
|
||||||
|
Q_ASSERT(h.is_valid());
|
||||||
|
return h.is_sequential_download();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setters
|
// Setters
|
||||||
//
|
//
|
||||||
|
@ -428,6 +438,11 @@ void QTorrentHandle::move_storage(QString new_path) const {
|
||||||
h.move_storage(new_path.toLocal8Bit().data());
|
h.move_storage(new_path.toLocal8Bit().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QTorrentHandle::file_priority(int index, int priority) const {
|
||||||
|
Q_ASSERT(h.is_valid());
|
||||||
|
h.file_priority(index, priority);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Operators
|
// Operators
|
||||||
//
|
//
|
||||||
|
|
|
@ -108,6 +108,8 @@ class QTorrentHandle {
|
||||||
bool is_seed() const;
|
bool is_seed() const;
|
||||||
bool is_auto_managed() const;
|
bool is_auto_managed() const;
|
||||||
int active_time() const;
|
int active_time() const;
|
||||||
|
std::vector<int> file_priorities() const;
|
||||||
|
bool is_sequential_download() const;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setters
|
// Setters
|
||||||
|
@ -122,6 +124,7 @@ class QTorrentHandle {
|
||||||
void set_max_uploads(int val);
|
void set_max_uploads(int val);
|
||||||
void set_max_connections(int val);
|
void set_max_connections(int val);
|
||||||
void prioritize_files(std::vector<int> v);
|
void prioritize_files(std::vector<int> v);
|
||||||
|
void file_priority(int index, int priority) const;
|
||||||
void set_ratio(float ratio) const;
|
void set_ratio(float ratio) const;
|
||||||
void replace_trackers(std::vector<announce_entry> const&) const;
|
void replace_trackers(std::vector<announce_entry> const&) const;
|
||||||
void force_reannounce();
|
void force_reannounce();
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "PropListDelegate.h"
|
#include "PropListDelegate.h"
|
||||||
#include "ui_addTorrentDialog.h"
|
#include "ui_addTorrentDialog.h"
|
||||||
#include "arborescence.h"
|
#include "arborescence.h"
|
||||||
|
#include "torrentPersistentData.h"
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
@ -371,22 +372,14 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{
|
||||||
|
|
||||||
void savePiecesPriorities(){
|
void savePiecesPriorities(){
|
||||||
qDebug("Saving pieces priorities");
|
qDebug("Saving pieces priorities");
|
||||||
QFile pieces_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".priorities"));
|
|
||||||
// First, remove old file
|
|
||||||
pieces_file.remove();
|
|
||||||
int *priorities = new int[nbFiles];
|
int *priorities = new int[nbFiles];
|
||||||
getPriorities(PropListModel->invisibleRootItem(), priorities);
|
getPriorities(PropListModel->invisibleRootItem(), priorities);
|
||||||
// Ok, we have priorities, save them
|
std::vector<int> vect_prio;
|
||||||
if(!pieces_file.open(QIODevice::WriteOnly | QIODevice::Text)){
|
|
||||||
std::cerr << "Error: Could not save pieces priorities\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for(unsigned int i=0; i<nbFiles; ++i) {
|
for(unsigned int i=0; i<nbFiles; ++i) {
|
||||||
qDebug("%d ", priorities[i]);
|
vect_prio.push_back(priorities[i]);
|
||||||
pieces_file.write(misc::toQByteArray(priorities[i])+misc::toQByteArray("\n"));
|
|
||||||
}
|
}
|
||||||
pieces_file.close();
|
|
||||||
delete[] priorities;
|
delete[] priorities;
|
||||||
|
TorrentTempData::setFilesPriority(hash, vect_prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_OkButton_clicked(){
|
void on_OkButton_clicked(){
|
||||||
|
@ -403,21 +396,12 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Save savepath
|
// Save savepath
|
||||||
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
|
TorrentTempData::setSavePath(hash, savePath.path());
|
||||||
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
savepath_file.write(savePath.path().toLocal8Bit());
|
|
||||||
savepath_file.close();
|
|
||||||
// Save last dir to remember it
|
// Save last dir to remember it
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
settings.setValue(QString::fromUtf8("LastDirTorrentAdd"), savePathTxt->text());
|
settings.setValue(QString::fromUtf8("LastDirTorrentAdd"), savePathTxt->text());
|
||||||
// Create .incremental file if necessary
|
// Create .incremental file if necessary
|
||||||
if(checkIncrementalDL->isChecked()){
|
TorrentTempData::setSequential(hash, checkIncrementalDL->isChecked());
|
||||||
QFile incremental_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".incremental"));
|
|
||||||
incremental_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|
||||||
incremental_file.close();
|
|
||||||
}else{
|
|
||||||
QFile::remove(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".incremental"));
|
|
||||||
}
|
|
||||||
// Check if there is at least one selected file
|
// Check if there is at least one selected file
|
||||||
if(allFiltered()){
|
if(allFiltered()){
|
||||||
QMessageBox::warning(0, tr("Invalid file selection"), tr("You must select at least one file in the torrent"));
|
QMessageBox::warning(0, tr("Invalid file selection"), tr("You must select at least one file in the torrent"));
|
||||||
|
|
339
src/torrentPersistentData.h
Normal file
339
src/torrentPersistentData.h
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
/*
|
||||||
|
* 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 TORRENTPERSISTENTDATA_H
|
||||||
|
#define TORRENTPERSISTENTDATA_H
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <libtorrent/magnet_uri.hpp>
|
||||||
|
|
||||||
|
#include "qtorrenthandle.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
class TorrentTempData {
|
||||||
|
public:
|
||||||
|
static bool hasTempData(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
return all_data.contains(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deleteTempData(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
if(all_data.contains(hash)) {
|
||||||
|
all_data.remove(hash);
|
||||||
|
settings.setValue("torrents-tmp", all_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setFilesPriority(QString hash, std::vector<int> pp) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
std::vector<int>::iterator pp_it = pp.begin();
|
||||||
|
QVariantList pieces_priority;
|
||||||
|
while(pp_it != pp.end()) {
|
||||||
|
pieces_priority << *pp_it;
|
||||||
|
pp_it++;
|
||||||
|
}
|
||||||
|
data["files_priority"] = pieces_priority;
|
||||||
|
all_data[hash] = data;
|
||||||
|
settings.setValue("torrents-tmp", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setSavePath(QString hash, QString save_path) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
data["save_path"] = save_path;
|
||||||
|
all_data[hash] = data;
|
||||||
|
settings.setValue("torrents-tmp", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setSequential(QString hash, bool sequential) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
data["sequential"] = sequential;
|
||||||
|
all_data[hash] = data;
|
||||||
|
settings.setValue("torrents-tmp", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSequential(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
if(data.contains("sequential"))
|
||||||
|
return data["sequential"].toBool();
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString getSavePath(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
if(data.contains("save_path"))
|
||||||
|
return data["save_path"].toString();
|
||||||
|
qDebug("Warning Temp::getSavePath returns null string!");
|
||||||
|
return QString::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QVariantList getFilesPriority(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents-tmp", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
if(data.contains("files_priority"))
|
||||||
|
return data["files_priority"].toList();
|
||||||
|
return QVariantList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TorrentPersistentData {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static bool isKnownTorrent(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
|
return all_data.contains(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QStringList knownTorrents() {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
|
return all_data.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deletePersistentData(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
|
if(all_data.contains(hash)) {
|
||||||
|
all_data.remove(hash);
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void saveTorrentPersistentData(QTorrentHandle h, bool is_magnet = false) {
|
||||||
|
// First, remove temp data
|
||||||
|
TorrentTempData::deleteTempData(h.hash());
|
||||||
|
Q_ASSERT(!TorrentTempData::hasTempData(h.hash()));
|
||||||
|
// Save persistent data
|
||||||
|
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;
|
||||||
|
data["hash"] = h.hash();
|
||||||
|
data["is_magnet"] = is_magnet;
|
||||||
|
if(is_magnet) {
|
||||||
|
data["magnet_uri"] = misc::toQString(make_magnet_uri(h.get_torrent_handle()));
|
||||||
|
}
|
||||||
|
data["seed"] = h.is_seed();
|
||||||
|
data["priority"] = h.queue_position();
|
||||||
|
QVariantList files_priority;
|
||||||
|
std::vector<int> fp = h.file_priorities();
|
||||||
|
std::vector<int>::iterator fp_it = fp.begin();
|
||||||
|
while(fp_it != fp.end()) {
|
||||||
|
files_priority << *fp_it;
|
||||||
|
fp_it++;
|
||||||
|
}
|
||||||
|
data["files_priority"] = files_priority;
|
||||||
|
data["save_path"] = h.save_path();
|
||||||
|
QHash<QString, QVariant> trackers;
|
||||||
|
std::vector<announce_entry> tr = h.trackers();
|
||||||
|
std::vector<announce_entry>::iterator tr_it = tr.begin();
|
||||||
|
while(tr_it != tr.end()) {
|
||||||
|
trackers[misc::toQString((*tr_it).url)] = (*tr_it).tier;
|
||||||
|
tr_it++;
|
||||||
|
}
|
||||||
|
data["trackers"] = trackers;
|
||||||
|
QVariantList url_seeds;
|
||||||
|
foreach(QString url_seed, h.url_seeds()) {
|
||||||
|
url_seeds << url_seed;
|
||||||
|
}
|
||||||
|
data["url_seeds"] = url_seeds;
|
||||||
|
data["sequential"] = h.is_sequential_download();
|
||||||
|
// Save data
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void saveTrackers(QTorrentHandle h) {
|
||||||
|
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[h.hash()].toHash();
|
||||||
|
QVariantList trackers;
|
||||||
|
std::vector<announce_entry> tr = h.trackers();
|
||||||
|
std::vector<announce_entry>::iterator tr_it = tr.begin();
|
||||||
|
while(tr_it != tr.end()) {
|
||||||
|
trackers << misc::toQString((*tr_it).url);
|
||||||
|
tr_it++;
|
||||||
|
}
|
||||||
|
data["trackers"] = trackers;
|
||||||
|
// Save data
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
|
||||||
|
static void saveFilesPriority(QTorrentHandle h) {
|
||||||
|
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[h.hash()].toHash();
|
||||||
|
std::vector<int> fp = h.file_priorities();
|
||||||
|
std::vector<int>::iterator fp_it = fp.begin();
|
||||||
|
QVariantList files_priority;
|
||||||
|
while(fp_it != fp.end()) {
|
||||||
|
files_priority << *fp_it;
|
||||||
|
fp_it++;
|
||||||
|
}
|
||||||
|
data["files_priority"] = files_priority;
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void saveSavePath(QString hash, QString save_path) {
|
||||||
|
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();
|
||||||
|
data["save_path"] = save_path;
|
||||||
|
all_data[hash] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void saveUrlSeeds(QTorrentHandle h) {
|
||||||
|
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[h.hash()].toHash();
|
||||||
|
QVariantList url_seeds;
|
||||||
|
foreach(QString url_seed, h.url_seeds()) {
|
||||||
|
url_seeds << url_seed;
|
||||||
|
}
|
||||||
|
data["url_seeds"] = url_seeds;
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void savePriority(QTorrentHandle h) {
|
||||||
|
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[h.hash()].toHash();
|
||||||
|
data["priority"] = h.queue_position();
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void saveSeedStatus(QTorrentHandle h) {
|
||||||
|
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[h.hash()].toHash();
|
||||||
|
data["seed"] = h.is_seed();
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void saveSequentialStatus(QTorrentHandle h) {
|
||||||
|
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[h.hash()].toHash();
|
||||||
|
data["sequential"] = h.is_sequential_download();
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
static QHash<QString, QVariant> getTrackers(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["trackers"].toHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QVariantList getFilesPriority(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["files_priority"].toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString getSavePath(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["save_path"].toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getPriority(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["priority"].toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QVariantList getUrlSeeds(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["url_seeds"].toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSeed(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["seed"].toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isMagnet(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["is_magnet"].toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString getMagnetUri(QString hash) {
|
||||||
|
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();
|
||||||
|
Q_ASSERT(data["is_magnet"].toBool());
|
||||||
|
return data["magnet_uri"].toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSequentialDownload(QString hash) {
|
||||||
|
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();
|
||||||
|
return data["sequential"].toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // TORRENTPERSISTENTDATA_H
|
Loading…
Reference in a new issue