mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-02 09:55:55 +00:00
Merge pull request #13894 from glassez/find-existing
Find existing files in separate thread
This commit is contained in:
commit
0c3fe54b0b
@ -8,6 +8,7 @@ add_library(qbt_base STATIC
|
|||||||
bittorrent/common.h
|
bittorrent/common.h
|
||||||
bittorrent/customstorage.h
|
bittorrent/customstorage.h
|
||||||
bittorrent/downloadpriority.h
|
bittorrent/downloadpriority.h
|
||||||
|
bittorrent/filesearcher.h
|
||||||
bittorrent/filterparserthread.h
|
bittorrent/filterparserthread.h
|
||||||
bittorrent/infohash.h
|
bittorrent/infohash.h
|
||||||
bittorrent/ltqhash.h
|
bittorrent/ltqhash.h
|
||||||
@ -90,6 +91,7 @@ add_library(qbt_base STATIC
|
|||||||
bittorrent/bandwidthscheduler.cpp
|
bittorrent/bandwidthscheduler.cpp
|
||||||
bittorrent/customstorage.cpp
|
bittorrent/customstorage.cpp
|
||||||
bittorrent/downloadpriority.cpp
|
bittorrent/downloadpriority.cpp
|
||||||
|
bittorrent/filesearcher.cpp
|
||||||
bittorrent/filterparserthread.cpp
|
bittorrent/filterparserthread.cpp
|
||||||
bittorrent/infohash.cpp
|
bittorrent/infohash.cpp
|
||||||
bittorrent/magneturi.cpp
|
bittorrent/magneturi.cpp
|
||||||
|
@ -7,6 +7,7 @@ HEADERS += \
|
|||||||
$$PWD/bittorrent/common.h \
|
$$PWD/bittorrent/common.h \
|
||||||
$$PWD/bittorrent/customstorage.h \
|
$$PWD/bittorrent/customstorage.h \
|
||||||
$$PWD/bittorrent/downloadpriority.h \
|
$$PWD/bittorrent/downloadpriority.h \
|
||||||
|
$$PWD/bittorrent/filesearcher.h \
|
||||||
$$PWD/bittorrent/filterparserthread.h \
|
$$PWD/bittorrent/filterparserthread.h \
|
||||||
$$PWD/bittorrent/infohash.h \
|
$$PWD/bittorrent/infohash.h \
|
||||||
$$PWD/bittorrent/ltqhash.h \
|
$$PWD/bittorrent/ltqhash.h \
|
||||||
@ -90,6 +91,7 @@ SOURCES += \
|
|||||||
$$PWD/bittorrent/bandwidthscheduler.cpp \
|
$$PWD/bittorrent/bandwidthscheduler.cpp \
|
||||||
$$PWD/bittorrent/customstorage.cpp \
|
$$PWD/bittorrent/customstorage.cpp \
|
||||||
$$PWD/bittorrent/downloadpriority.cpp \
|
$$PWD/bittorrent/downloadpriority.cpp \
|
||||||
|
$$PWD/bittorrent/filesearcher.cpp \
|
||||||
$$PWD/bittorrent/filterparserthread.cpp \
|
$$PWD/bittorrent/filterparserthread.cpp \
|
||||||
$$PWD/bittorrent/infohash.cpp \
|
$$PWD/bittorrent/infohash.cpp \
|
||||||
$$PWD/bittorrent/magneturi.cpp \
|
$$PWD/bittorrent/magneturi.cpp \
|
||||||
|
69
src/base/bittorrent/filesearcher.cpp
Normal file
69
src/base/bittorrent/filesearcher.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "filesearcher.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "base/bittorrent/common.h"
|
||||||
|
#include "base/bittorrent/infohash.h"
|
||||||
|
|
||||||
|
void FileSearcher::search(const BitTorrent::InfoHash &id, const QStringList &originalFileNames
|
||||||
|
, const QString &completeSavePath, const QString &incompleteSavePath)
|
||||||
|
{
|
||||||
|
const auto findInDir = [](const QString &dirPath, QStringList &fileNames) -> bool
|
||||||
|
{
|
||||||
|
const QDir dir {dirPath};
|
||||||
|
bool found = false;
|
||||||
|
for (QString &fileName : fileNames)
|
||||||
|
{
|
||||||
|
if (dir.exists(fileName))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else if (dir.exists(fileName + QB_EXT))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
fileName += QB_EXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
};
|
||||||
|
|
||||||
|
QString savePath = completeSavePath;
|
||||||
|
QStringList adjustedFileNames = originalFileNames;
|
||||||
|
const bool found = findInDir(savePath, adjustedFileNames);
|
||||||
|
if (!found && !incompleteSavePath.isEmpty())
|
||||||
|
{
|
||||||
|
savePath = incompleteSavePath;
|
||||||
|
findInDir(savePath, adjustedFileNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit searchFinished(id, savePath, adjustedFileNames);
|
||||||
|
}
|
52
src/base/bittorrent/filesearcher.h
Normal file
52
src/base/bittorrent/filesearcher.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace BitTorrent
|
||||||
|
{
|
||||||
|
class InfoHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileSearcher final : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(FileSearcher)
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileSearcher() = default;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void search(const BitTorrent::InfoHash &id, const QStringList &originalFileNames
|
||||||
|
, const QString &completeSavePath, const QString &incompleteSavePath);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void searchFinished(const BitTorrent::InfoHash &id, const QString &savePath, const QStringList &fileNames);
|
||||||
|
};
|
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
|
|
||||||
|
const int InfoHashTypeId = qRegisterMetaType<InfoHash>();
|
||||||
|
|
||||||
InfoHash::InfoHash()
|
InfoHash::InfoHash()
|
||||||
: m_valid(false)
|
: m_valid(false)
|
||||||
{
|
{
|
||||||
|
@ -26,11 +26,11 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_INFOHASH_H
|
#pragma once
|
||||||
#define BITTORRENT_INFOHASH_H
|
|
||||||
|
|
||||||
#include <libtorrent/sha1_hash.hpp>
|
#include <libtorrent/sha1_hash.hpp>
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
@ -64,4 +64,4 @@ namespace BitTorrent
|
|||||||
uint qHash(const InfoHash &key, uint seed);
|
uint qHash(const InfoHash &key, uint seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_INFOHASH_H
|
Q_DECLARE_METATYPE(BitTorrent::InfoHash)
|
||||||
|
@ -88,6 +88,7 @@
|
|||||||
#include "bandwidthscheduler.h"
|
#include "bandwidthscheduler.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "customstorage.h"
|
#include "customstorage.h"
|
||||||
|
#include "filesearcher.h"
|
||||||
#include "filterparserthread.h"
|
#include "filterparserthread.h"
|
||||||
#include "ltunderlyingtype.h"
|
#include "ltunderlyingtype.h"
|
||||||
#include "magneturi.h"
|
#include "magneturi.h"
|
||||||
@ -509,6 +510,12 @@ Session::Session(QObject *parent)
|
|||||||
m_resumeDataSavingManager = new ResumeDataSavingManager {m_resumeFolderPath};
|
m_resumeDataSavingManager = new ResumeDataSavingManager {m_resumeFolderPath};
|
||||||
m_resumeDataSavingManager->moveToThread(m_ioThread);
|
m_resumeDataSavingManager->moveToThread(m_ioThread);
|
||||||
connect(m_ioThread, &QThread::finished, m_resumeDataSavingManager, &QObject::deleteLater);
|
connect(m_ioThread, &QThread::finished, m_resumeDataSavingManager, &QObject::deleteLater);
|
||||||
|
|
||||||
|
m_fileSearcher = new FileSearcher;
|
||||||
|
m_fileSearcher->moveToThread(m_ioThread);
|
||||||
|
connect(m_ioThread, &QThread::finished, m_fileSearcher, &QObject::deleteLater);
|
||||||
|
connect(m_fileSearcher, &FileSearcher::searchFinished, this, &Session::fileSearchFinished);
|
||||||
|
|
||||||
m_ioThread->start();
|
m_ioThread->start();
|
||||||
|
|
||||||
// Regular saving of fastresume data
|
// Regular saving of fastresume data
|
||||||
@ -593,11 +600,11 @@ void Session::setAppendExtensionEnabled(const bool enabled)
|
|||||||
{
|
{
|
||||||
if (isAppendExtensionEnabled() != enabled)
|
if (isAppendExtensionEnabled() != enabled)
|
||||||
{
|
{
|
||||||
|
m_isAppendExtensionEnabled = enabled;
|
||||||
|
|
||||||
// append or remove .!qB extension for incomplete files
|
// append or remove .!qB extension for incomplete files
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
||||||
torrent->handleAppendExtensionToggled();
|
torrent->handleAppendExtensionToggled();
|
||||||
|
|
||||||
m_isAppendExtensionEnabled = enabled;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1765,6 +1772,24 @@ void Session::handleDownloadFinished(const Net::DownloadResult &result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames)
|
||||||
|
{
|
||||||
|
const auto loadingTorrentsIter = m_loadingTorrents.find(id);
|
||||||
|
if (loadingTorrentsIter != m_loadingTorrents.end())
|
||||||
|
{
|
||||||
|
LoadTorrentParams params = loadingTorrentsIter.value();
|
||||||
|
m_loadingTorrents.erase(loadingTorrentsIter);
|
||||||
|
|
||||||
|
lt::add_torrent_params &p = params.ltAddTorrentParams;
|
||||||
|
|
||||||
|
p.save_path = Utils::Fs::toNativePath(savePath).toStdString();
|
||||||
|
for (int i = 0; i < fileNames.size(); ++i)
|
||||||
|
p.renamed_files[lt::file_index_t {i}] = fileNames[i].toStdString();
|
||||||
|
|
||||||
|
loadTorrent(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return the torrent handle, given its hash
|
// Return the torrent handle, given its hash
|
||||||
TorrentHandle *Session::findTorrent(const InfoHash &hash) const
|
TorrentHandle *Session::findTorrent(const InfoHash &hash) const
|
||||||
{
|
{
|
||||||
@ -1892,12 +1917,12 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::cancelLoadMetadata(const InfoHash &hash)
|
bool Session::cancelDownloadMetadata(const InfoHash &hash)
|
||||||
{
|
{
|
||||||
const auto loadedMetadataIter = m_loadedMetadata.find(hash);
|
const auto downloadedMetadataIter = m_downloadedMetadata.find(hash);
|
||||||
if (loadedMetadataIter == m_loadedMetadata.end()) return false;
|
if (downloadedMetadataIter == m_downloadedMetadata.end()) return false;
|
||||||
|
|
||||||
m_loadedMetadata.erase(loadedMetadataIter);
|
m_downloadedMetadata.erase(downloadedMetadataIter);
|
||||||
--m_extraLimit;
|
--m_extraLimit;
|
||||||
adjustLimits();
|
adjustLimits();
|
||||||
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(hash), lt::session::delete_files);
|
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(hash), lt::session::delete_files);
|
||||||
@ -1951,7 +1976,7 @@ void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
for (auto i = m_downloadedMetadata.cbegin(); i != m_downloadedMetadata.cend(); ++i)
|
||||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(*i));
|
torrentQueuePositionBottom(m_nativeSession->find_torrent(*i));
|
||||||
|
|
||||||
saveTorrentsQueue();
|
saveTorrentsQueue();
|
||||||
@ -2004,7 +2029,7 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
for (auto i = m_downloadedMetadata.cbegin(); i != m_downloadedMetadata.cend(); ++i)
|
||||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(*i));
|
torrentQueuePositionBottom(m_nativeSession->find_torrent(*i));
|
||||||
|
|
||||||
saveTorrentsQueue();
|
saveTorrentsQueue();
|
||||||
@ -2058,21 +2083,6 @@ bool Session::addTorrent(const MagnetUri &magnetUri, const AddTorrentParams &par
|
|||||||
{
|
{
|
||||||
if (!magnetUri.isValid()) return false;
|
if (!magnetUri.isValid()) return false;
|
||||||
|
|
||||||
const InfoHash hash = magnetUri.hash();
|
|
||||||
|
|
||||||
const auto it = m_loadedMetadata.constFind(hash);
|
|
||||||
if (it != m_loadedMetadata.constEnd())
|
|
||||||
{
|
|
||||||
// It looks illogical that we don't just use an existing handle,
|
|
||||||
// but as previous experience has shown, it actually creates unnecessary
|
|
||||||
// problems and unwanted behavior due to the fact that it was originally
|
|
||||||
// added with parameters other than those provided by the user.
|
|
||||||
m_loadedMetadata.erase(it);
|
|
||||||
--m_extraLimit;
|
|
||||||
adjustLimits();
|
|
||||||
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(hash), lt::session::delete_files);
|
|
||||||
}
|
|
||||||
|
|
||||||
return addTorrent_impl(params, magnetUri);
|
return addTorrent_impl(params, magnetUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2113,7 +2123,7 @@ LoadTorrentParams Session::initLoadTorrentParams(const AddTorrentParams &addTorr
|
|||||||
|
|
||||||
const QString category = addTorrentParams.category;
|
const QString category = addTorrentParams.category;
|
||||||
if (!category.isEmpty() && !m_categories.contains(category) && !addCategory(category))
|
if (!category.isEmpty() && !m_categories.contains(category) && !addCategory(category))
|
||||||
loadTorrentParams.category = "";
|
loadTorrentParams.category = "";
|
||||||
else
|
else
|
||||||
loadTorrentParams.category = addTorrentParams.category;
|
loadTorrentParams.category = addTorrentParams.category;
|
||||||
|
|
||||||
@ -2126,9 +2136,15 @@ bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const Ma
|
|||||||
const bool hasMetadata = metadata.isValid();
|
const bool hasMetadata = metadata.isValid();
|
||||||
const InfoHash hash = (hasMetadata ? metadata.hash() : magnetUri.hash());
|
const InfoHash hash = (hasMetadata ? metadata.hash() : magnetUri.hash());
|
||||||
|
|
||||||
|
// It looks illogical that we don't just use an existing handle,
|
||||||
|
// but as previous experience has shown, it actually creates unnecessary
|
||||||
|
// problems and unwanted behavior due to the fact that it was originally
|
||||||
|
// added with parameters other than those provided by the user.
|
||||||
|
cancelDownloadMetadata(hash);
|
||||||
|
|
||||||
// We should not add the torrent if it is already
|
// We should not add the torrent if it is already
|
||||||
// processed or is pending to add to session
|
// processed or is pending to add to session
|
||||||
if (m_loadingTorrents.contains(hash) || m_loadedMetadata.contains(hash))
|
if (m_loadingTorrents.contains(hash))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(hash);
|
TorrentHandleImpl *const torrent = m_torrents.value(hash);
|
||||||
@ -2146,15 +2162,20 @@ bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const Ma
|
|||||||
LoadTorrentParams loadTorrentParams = initLoadTorrentParams(addTorrentParams);
|
LoadTorrentParams loadTorrentParams = initLoadTorrentParams(addTorrentParams);
|
||||||
lt::add_torrent_params &p = loadTorrentParams.ltAddTorrentParams;
|
lt::add_torrent_params &p = loadTorrentParams.ltAddTorrentParams;
|
||||||
|
|
||||||
|
bool isFindingIncompleteFiles = false;
|
||||||
|
|
||||||
// If empty then Automatic mode, otherwise Manual mode
|
// If empty then Automatic mode, otherwise Manual mode
|
||||||
QString actualSavePath = loadTorrentParams.savePath.isEmpty() ? categorySavePath(loadTorrentParams.category) : loadTorrentParams.savePath;
|
const QString actualSavePath = loadTorrentParams.savePath.isEmpty() ? categorySavePath(loadTorrentParams.category) : loadTorrentParams.savePath;
|
||||||
if (hasMetadata)
|
if (hasMetadata)
|
||||||
{
|
{
|
||||||
if (!loadTorrentParams.hasRootFolder)
|
if (!loadTorrentParams.hasRootFolder)
|
||||||
metadata.stripRootFolder();
|
metadata.stripRootFolder();
|
||||||
|
|
||||||
if (!loadTorrentParams.hasSeedStatus)
|
if (!loadTorrentParams.hasSeedStatus)
|
||||||
findIncompleteFiles(metadata, actualSavePath); // if needed points savePath to incomplete folder too
|
{
|
||||||
|
findIncompleteFiles(metadata, actualSavePath);
|
||||||
|
isFindingIncompleteFiles = true;
|
||||||
|
}
|
||||||
|
|
||||||
// if torrent name wasn't explicitly set we handle the case of
|
// if torrent name wasn't explicitly set we handle the case of
|
||||||
// initial renaming of torrent content and rename torrent accordingly
|
// initial renaming of torrent content and rename torrent accordingly
|
||||||
@ -2184,9 +2205,6 @@ bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const Ma
|
|||||||
|
|
||||||
if (loadTorrentParams.name.isEmpty() && !p.name.empty())
|
if (loadTorrentParams.name.isEmpty() && !p.name.empty())
|
||||||
loadTorrentParams.name = QString::fromStdString(p.name);
|
loadTorrentParams.name = QString::fromStdString(p.name);
|
||||||
|
|
||||||
if (isTempPathEnabled())
|
|
||||||
actualSavePath = tempPath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p.save_path = Utils::Fs::toNativePath(actualSavePath).toStdString();
|
p.save_path = Utils::Fs::toNativePath(actualSavePath).toStdString();
|
||||||
@ -2218,7 +2236,11 @@ bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const Ma
|
|||||||
else
|
else
|
||||||
p.flags |= lt::torrent_flags::auto_managed;
|
p.flags |= lt::torrent_flags::auto_managed;
|
||||||
|
|
||||||
return loadTorrent(loadTorrentParams);
|
if (!isFindingIncompleteFiles)
|
||||||
|
return loadTorrent(loadTorrentParams);
|
||||||
|
|
||||||
|
m_loadingTorrents.insert(hash, loadTorrentParams);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a torrent to the BitTorrent session
|
// Add a torrent to the BitTorrent session
|
||||||
@ -2243,42 +2265,27 @@ bool Session::loadTorrent(LoadTorrentParams params)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const
|
void Session::findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const
|
||||||
{
|
{
|
||||||
auto findInDir = [](const QString &dirPath, TorrentInfo &torrentInfo) -> bool
|
const InfoHash searchId = torrentInfo.hash();
|
||||||
|
const QStringList originalFileNames = torrentInfo.filePaths();
|
||||||
|
const QString completeSavePath = savePath;
|
||||||
|
const QString incompleteSavePath = (isTempPathEnabled() ? torrentTempPath(torrentInfo) : QString {});
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||||
|
QMetaObject::invokeMethod(m_fileSearcher, [=]()
|
||||||
{
|
{
|
||||||
const QDir dir(dirPath);
|
m_fileSearcher->search(searchId, originalFileNames, completeSavePath, incompleteSavePath);
|
||||||
bool found = false;
|
});
|
||||||
for (int i = 0; i < torrentInfo.filesCount(); ++i)
|
#else
|
||||||
{
|
QMetaObject::invokeMethod(m_fileSearcher, "search"
|
||||||
const QString filePath = torrentInfo.filePath(i);
|
, Q_ARG(InfoHash, searchId), Q_ARG(QStringList, originalFileNames)
|
||||||
if (dir.exists(filePath))
|
, Q_ARG(QString, completeSavePath), Q_ARG(QString, incompleteSavePath));
|
||||||
{
|
#endif
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
else if (dir.exists(filePath + QB_EXT))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
torrentInfo.renameFile(i, filePath + QB_EXT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool found = findInDir(savePath, torrentInfo);
|
|
||||||
if (!found && isTempPathEnabled())
|
|
||||||
{
|
|
||||||
savePath = torrentTempPath(torrentInfo);
|
|
||||||
found = findInDir(savePath, torrentInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a torrent to the BitTorrent session in hidden mode
|
// Add a torrent to libtorrent session in hidden mode
|
||||||
// and force it to load its metadata
|
// and force it to download its metadata
|
||||||
bool Session::loadMetadata(const MagnetUri &magnetUri)
|
bool Session::downloadMetadata(const MagnetUri &magnetUri)
|
||||||
{
|
{
|
||||||
if (!magnetUri.isValid()) return false;
|
if (!magnetUri.isValid()) return false;
|
||||||
|
|
||||||
@ -2289,7 +2296,7 @@ bool Session::loadMetadata(const MagnetUri &magnetUri)
|
|||||||
// processed or adding to session
|
// processed or adding to session
|
||||||
if (m_torrents.contains(hash)) return false;
|
if (m_torrents.contains(hash)) return false;
|
||||||
if (m_loadingTorrents.contains(hash)) return false;
|
if (m_loadingTorrents.contains(hash)) return false;
|
||||||
if (m_loadedMetadata.contains(hash)) return false;
|
if (m_downloadedMetadata.contains(hash)) return false;
|
||||||
|
|
||||||
qDebug("Adding torrent to preload metadata...");
|
qDebug("Adding torrent to preload metadata...");
|
||||||
qDebug(" -> Hash: %s", qUtf8Printable(hash));
|
qDebug(" -> Hash: %s", qUtf8Printable(hash));
|
||||||
@ -2322,13 +2329,13 @@ bool Session::loadMetadata(const MagnetUri &magnetUri)
|
|||||||
p.storage = customStorageConstructor;
|
p.storage = customStorageConstructor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Adding torrent to BitTorrent session
|
// Adding torrent to libtorrent session
|
||||||
lt::error_code ec;
|
lt::error_code ec;
|
||||||
lt::torrent_handle h = m_nativeSession->add_torrent(p, ec);
|
lt::torrent_handle h = m_nativeSession->add_torrent(p, ec);
|
||||||
if (ec) return false;
|
if (ec) return false;
|
||||||
|
|
||||||
// waiting for metadata...
|
// waiting for metadata...
|
||||||
m_loadedMetadata.insert(h.info_hash());
|
m_downloadedMetadata.insert(h.info_hash());
|
||||||
++m_extraLimit;
|
++m_extraLimit;
|
||||||
adjustLimits();
|
adjustLimits();
|
||||||
|
|
||||||
@ -3775,7 +3782,7 @@ bool Session::isKnownTorrent(const InfoHash &hash) const
|
|||||||
{
|
{
|
||||||
return (m_torrents.contains(hash)
|
return (m_torrents.contains(hash)
|
||||||
|| m_loadingTorrents.contains(hash)
|
|| m_loadingTorrents.contains(hash)
|
||||||
|| m_loadedMetadata.contains(hash));
|
|| m_downloadedMetadata.contains(hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::updateSeedingLimitTimer()
|
void Session::updateSeedingLimitTimer()
|
||||||
@ -3879,8 +3886,6 @@ void Session::handleTorrentUrlSeedsRemoved(TorrentHandleImpl *const torrent, con
|
|||||||
|
|
||||||
void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
|
||||||
|
|
||||||
// Save metadata
|
// Save metadata
|
||||||
const QDir resumeDataDir {m_resumeFolderPath};
|
const QDir resumeDataDir {m_resumeFolderPath};
|
||||||
const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->hash())};
|
const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->hash())};
|
||||||
@ -3897,7 +3902,7 @@ void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
|
|||||||
.arg(torrentFileName, err.message()), Log::CRITICAL);
|
.arg(torrentFileName, err.message()), Log::CRITICAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit torrentMetadataLoaded(torrent);
|
emit torrentMetadataReceived(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentPaused(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentPaused(TorrentHandleImpl *const torrent)
|
||||||
@ -4724,18 +4729,18 @@ void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_ale
|
|||||||
void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
|
void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
|
||||||
{
|
{
|
||||||
const InfoHash hash {p->handle.info_hash()};
|
const InfoHash hash {p->handle.info_hash()};
|
||||||
const auto loadedMetadataIter = m_loadedMetadata.find(hash);
|
const auto downloadedMetadataIter = m_downloadedMetadata.find(hash);
|
||||||
|
|
||||||
if (loadedMetadataIter != m_loadedMetadata.end())
|
if (downloadedMetadataIter != m_downloadedMetadata.end())
|
||||||
{
|
{
|
||||||
TorrentInfo metadata {p->handle.torrent_file()};
|
TorrentInfo metadata {p->handle.torrent_file()};
|
||||||
|
|
||||||
m_loadedMetadata.erase(loadedMetadataIter);
|
m_downloadedMetadata.erase(downloadedMetadataIter);
|
||||||
--m_extraLimit;
|
--m_extraLimit;
|
||||||
adjustLimits();
|
adjustLimits();
|
||||||
m_nativeSession->remove_torrent(p->handle, lt::session::delete_files);
|
m_nativeSession->remove_torrent(p->handle, lt::session::delete_files);
|
||||||
|
|
||||||
emit metadataLoaded(metadata);
|
emit metadataDownloaded(metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ class QTimer;
|
|||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
class BandwidthScheduler;
|
class BandwidthScheduler;
|
||||||
|
class FileSearcher;
|
||||||
class FilterParserThread;
|
class FilterParserThread;
|
||||||
class ResumeDataSavingManager;
|
class ResumeDataSavingManager;
|
||||||
class Statistics;
|
class Statistics;
|
||||||
@ -453,8 +454,8 @@ namespace BitTorrent
|
|||||||
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = Torrent);
|
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = Torrent);
|
||||||
bool loadMetadata(const MagnetUri &magnetUri);
|
bool downloadMetadata(const MagnetUri &magnetUri);
|
||||||
bool cancelLoadMetadata(const InfoHash &hash);
|
bool cancelDownloadMetadata(const InfoHash &hash);
|
||||||
|
|
||||||
void recursiveTorrentDownload(const InfoHash &hash);
|
void recursiveTorrentDownload(const InfoHash &hash);
|
||||||
void increaseTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
void increaseTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
||||||
@ -488,6 +489,8 @@ namespace BitTorrent
|
|||||||
|
|
||||||
bool addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, MoveStorageMode mode);
|
bool addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, MoveStorageMode mode);
|
||||||
|
|
||||||
|
void findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void allTorrentsFinished();
|
void allTorrentsFinished();
|
||||||
void categoryAdded(const QString &categoryName);
|
void categoryAdded(const QString &categoryName);
|
||||||
@ -497,7 +500,7 @@ namespace BitTorrent
|
|||||||
void fullDiskError(TorrentHandle *torrent, const QString &msg);
|
void fullDiskError(TorrentHandle *torrent, const QString &msg);
|
||||||
void IPFilterParsed(bool error, int ruleCount);
|
void IPFilterParsed(bool error, int ruleCount);
|
||||||
void loadTorrentFailed(const QString &error);
|
void loadTorrentFailed(const QString &error);
|
||||||
void metadataLoaded(const TorrentInfo &info);
|
void metadataDownloaded(const TorrentInfo &info);
|
||||||
void recursiveTorrentDownloadPossible(TorrentHandle *torrent);
|
void recursiveTorrentDownloadPossible(TorrentHandle *torrent);
|
||||||
void speedLimitModeChanged(bool alternative);
|
void speedLimitModeChanged(bool alternative);
|
||||||
void statsUpdated();
|
void statsUpdated();
|
||||||
@ -510,7 +513,7 @@ namespace BitTorrent
|
|||||||
void torrentFinished(TorrentHandle *torrent);
|
void torrentFinished(TorrentHandle *torrent);
|
||||||
void torrentFinishedChecking(TorrentHandle *torrent);
|
void torrentFinishedChecking(TorrentHandle *torrent);
|
||||||
void torrentLoaded(TorrentHandle *torrent);
|
void torrentLoaded(TorrentHandle *torrent);
|
||||||
void torrentMetadataLoaded(TorrentHandle *torrent);
|
void torrentMetadataReceived(TorrentHandle *torrent);
|
||||||
void torrentPaused(TorrentHandle *torrent);
|
void torrentPaused(TorrentHandle *torrent);
|
||||||
void torrentResumed(TorrentHandle *torrent);
|
void torrentResumed(TorrentHandle *torrent);
|
||||||
void torrentSavePathChanged(TorrentHandle *torrent);
|
void torrentSavePathChanged(TorrentHandle *torrent);
|
||||||
@ -537,6 +540,7 @@ namespace BitTorrent
|
|||||||
void handleIPFilterParsed(int ruleCount);
|
void handleIPFilterParsed(int ruleCount);
|
||||||
void handleIPFilterError();
|
void handleIPFilterError();
|
||||||
void handleDownloadFinished(const Net::DownloadResult &result);
|
void handleDownloadFinished(const Net::DownloadResult &result);
|
||||||
|
void fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames);
|
||||||
|
|
||||||
// Session reconfiguration triggers
|
// Session reconfiguration triggers
|
||||||
void networkOnlineStateChanged(bool online);
|
void networkOnlineStateChanged(bool online);
|
||||||
@ -593,7 +597,6 @@ namespace BitTorrent
|
|||||||
bool loadTorrent(LoadTorrentParams params);
|
bool loadTorrent(LoadTorrentParams params);
|
||||||
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
|
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
|
||||||
bool addTorrent_impl(const AddTorrentParams &addTorrentParams, const MagnetUri &magnetUri, TorrentInfo torrentInfo = TorrentInfo());
|
bool addTorrent_impl(const AddTorrentParams &addTorrentParams, const MagnetUri &magnetUri, TorrentInfo torrentInfo = TorrentInfo());
|
||||||
bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const;
|
|
||||||
|
|
||||||
void updateSeedingLimitTimer();
|
void updateSeedingLimitTimer();
|
||||||
void exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
void exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
||||||
@ -763,8 +766,9 @@ namespace BitTorrent
|
|||||||
// fastresume data writing thread
|
// fastresume data writing thread
|
||||||
QThread *m_ioThread = nullptr;
|
QThread *m_ioThread = nullptr;
|
||||||
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
|
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
|
||||||
|
FileSearcher *m_fileSearcher = nullptr;
|
||||||
|
|
||||||
QSet<InfoHash> m_loadedMetadata;
|
QSet<InfoHash> m_downloadedMetadata;
|
||||||
|
|
||||||
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
|
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
|
||||||
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
|
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
|
||||||
|
@ -123,8 +123,10 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle
|
|||||||
if (m_useAutoTMM)
|
if (m_useAutoTMM)
|
||||||
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
|
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
|
||||||
|
|
||||||
|
m_hash = InfoHash {m_nativeHandle.info_hash()};
|
||||||
|
m_torrentInfo = TorrentInfo {m_nativeHandle.torrent_file()};
|
||||||
|
|
||||||
updateStatus();
|
updateStatus();
|
||||||
m_hash = InfoHash(m_nativeStatus.info_hash);
|
|
||||||
|
|
||||||
if (hasMetadata())
|
if (hasMetadata())
|
||||||
{
|
{
|
||||||
@ -792,7 +794,7 @@ void TorrentHandleImpl::updateState()
|
|||||||
|
|
||||||
bool TorrentHandleImpl::hasMetadata() const
|
bool TorrentHandleImpl::hasMetadata() const
|
||||||
{
|
{
|
||||||
return m_nativeStatus.has_metadata;
|
return m_torrentInfo.isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentHandleImpl::hasMissingFiles() const
|
bool TorrentHandleImpl::hasMissingFiles() const
|
||||||
@ -1560,12 +1562,8 @@ void TorrentHandleImpl::handleFastResumeRejectedAlert(const lt::fastresume_rejec
|
|||||||
|
|
||||||
void TorrentHandleImpl::handleFileRenamedAlert(const lt::file_renamed_alert *p)
|
void TorrentHandleImpl::handleFileRenamedAlert(const lt::file_renamed_alert *p)
|
||||||
{
|
{
|
||||||
// We don't really need to call updateStatus() in this place.
|
// Remove empty leftover folders
|
||||||
// All we need to do is make sure we have a valid instance of the TorrentInfo object.
|
// For example renaming "a/b/c" to "d/b/c", then folders "a/b" and "a" will
|
||||||
m_torrentInfo = TorrentInfo {m_nativeHandle.torrent_file()};
|
|
||||||
|
|
||||||
// remove empty leftover folders
|
|
||||||
// for example renaming "a/b/c" to "d/b/c", then folders "a/b" and "a" will
|
|
||||||
// be removed if they are empty
|
// be removed if they are empty
|
||||||
const QString oldFilePath = m_oldPath[p->index].takeFirst();
|
const QString oldFilePath = m_oldPath[p->index].takeFirst();
|
||||||
const QString newFilePath = Utils::Fs::toUniformPath(p->new_name());
|
const QString newFilePath = Utils::Fs::toUniformPath(p->new_name());
|
||||||
@ -1626,10 +1624,6 @@ void TorrentHandleImpl::handleFileRenameFailedAlert(const lt::file_rename_failed
|
|||||||
|
|
||||||
void TorrentHandleImpl::handleFileCompletedAlert(const lt::file_completed_alert *p)
|
void TorrentHandleImpl::handleFileCompletedAlert(const lt::file_completed_alert *p)
|
||||||
{
|
{
|
||||||
// We don't really need to call updateStatus() in this place.
|
|
||||||
// All we need to do is make sure we have a valid instance of the TorrentInfo object.
|
|
||||||
m_torrentInfo = TorrentInfo {m_nativeHandle.torrent_file()};
|
|
||||||
|
|
||||||
qDebug("A file completed download in torrent \"%s\"", qUtf8Printable(name()));
|
qDebug("A file completed download in torrent \"%s\"", qUtf8Printable(name()));
|
||||||
if (m_session->isAppendExtensionEnabled())
|
if (m_session->isAppendExtensionEnabled())
|
||||||
{
|
{
|
||||||
@ -1647,8 +1641,10 @@ void TorrentHandleImpl::handleFileCompletedAlert(const lt::file_completed_alert
|
|||||||
void TorrentHandleImpl::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
|
void TorrentHandleImpl::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
|
|
||||||
qDebug("Metadata received for torrent %s.", qUtf8Printable(name()));
|
qDebug("Metadata received for torrent %s.", qUtf8Printable(name()));
|
||||||
updateStatus();
|
m_torrentInfo = TorrentInfo {m_nativeHandle.torrent_file()};
|
||||||
|
|
||||||
if (m_session->isAppendExtensionEnabled())
|
if (m_session->isAppendExtensionEnabled())
|
||||||
manageIncompleteFiles();
|
manageIncompleteFiles();
|
||||||
if (!m_hasRootFolder)
|
if (!m_hasRootFolder)
|
||||||
@ -1814,13 +1810,6 @@ lt::torrent_handle TorrentHandleImpl::nativeHandle() const
|
|||||||
return m_nativeHandle;
|
return m_nativeHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandleImpl::updateTorrentInfo()
|
|
||||||
{
|
|
||||||
if (!hasMetadata()) return;
|
|
||||||
|
|
||||||
m_torrentInfo = TorrentInfo(m_nativeStatus.torrent_file.lock());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TorrentHandleImpl::isMoveInProgress() const
|
bool TorrentHandleImpl::isMoveInProgress() const
|
||||||
{
|
{
|
||||||
return m_storageIsMoving;
|
return m_storageIsMoving;
|
||||||
@ -1841,7 +1830,6 @@ void TorrentHandleImpl::updateStatus(const lt::torrent_status &nativeStatus)
|
|||||||
m_nativeStatus = nativeStatus;
|
m_nativeStatus = nativeStatus;
|
||||||
|
|
||||||
updateState();
|
updateState();
|
||||||
updateTorrentInfo();
|
|
||||||
|
|
||||||
// NOTE: Don't change the order of these conditionals!
|
// NOTE: Don't change the order of these conditionals!
|
||||||
// Otherwise it will not work properly since torrent can be CheckingDownloading.
|
// Otherwise it will not work properly since torrent can be CheckingDownloading.
|
||||||
|
@ -250,7 +250,6 @@ namespace BitTorrent
|
|||||||
void updateStatus();
|
void updateStatus();
|
||||||
void updateStatus(const lt::torrent_status &nativeStatus);
|
void updateStatus(const lt::torrent_status &nativeStatus);
|
||||||
void updateState();
|
void updateState();
|
||||||
void updateTorrentInfo();
|
|
||||||
|
|
||||||
void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p);
|
void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p);
|
||||||
void handleFileCompletedAlert(const lt::file_completed_alert *p);
|
void handleFileCompletedAlert(const lt::file_completed_alert *p);
|
||||||
|
@ -347,7 +347,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataDownloaded, this, &AddNewTorrentDialog::updateMetadata);
|
||||||
|
|
||||||
// Set dialog title
|
// Set dialog title
|
||||||
const QString torrentName = magnetUri.name();
|
const QString torrentName = magnetUri.name();
|
||||||
@ -356,7 +356,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
|
|||||||
setupTreeview();
|
setupTreeview();
|
||||||
TMMChanged(m_ui->comboTTM->currentIndex());
|
TMMChanged(m_ui->comboTTM->currentIndex());
|
||||||
|
|
||||||
BitTorrent::Session::instance()->loadMetadata(magnetUri);
|
BitTorrent::Session::instance()->downloadMetadata(magnetUri);
|
||||||
setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
|
setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
|
||||||
m_ui->labelHashData->setText(infoHash);
|
m_ui->labelHashData->setText(infoHash);
|
||||||
|
|
||||||
@ -613,7 +613,7 @@ void AddNewTorrentDialog::reject()
|
|||||||
if (!m_hasMetadata)
|
if (!m_hasMetadata)
|
||||||
{
|
{
|
||||||
setMetadataProgressIndicator(false);
|
setMetadataProgressIndicator(false);
|
||||||
BitTorrent::Session::instance()->cancelLoadMetadata(m_magnetURI.hash());
|
BitTorrent::Session::instance()->cancelDownloadMetadata(m_magnetURI.hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::reject();
|
QDialog::reject();
|
||||||
@ -623,7 +623,7 @@ void AddNewTorrentDialog::updateMetadata(const BitTorrent::TorrentInfo &metadata
|
|||||||
{
|
{
|
||||||
if (metadata.hash() != m_magnetURI.hash()) return;
|
if (metadata.hash() != m_magnetURI.hash()) return;
|
||||||
|
|
||||||
disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata);
|
disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataDownloaded, this, &AddNewTorrentDialog::updateMetadata);
|
||||||
|
|
||||||
if (!metadata.isValid())
|
if (!metadata.isValid())
|
||||||
{
|
{
|
||||||
|
@ -104,7 +104,7 @@ PropertiesWidget::PropertiesWidget(QWidget *parent)
|
|||||||
connect(m_propListDelegate, &PropListDelegate::filteredFilesChanged, this, &PropertiesWidget::filteredFilesChanged);
|
connect(m_propListDelegate, &PropListDelegate::filteredFilesChanged, this, &PropertiesWidget::filteredFilesChanged);
|
||||||
connect(m_ui->stackedProperties, &QStackedWidget::currentChanged, this, &PropertiesWidget::loadDynamicData);
|
connect(m_ui->stackedProperties, &QStackedWidget::currentChanged, this, &PropertiesWidget::loadDynamicData);
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentSavePathChanged, this, &PropertiesWidget::updateSavePath);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentSavePathChanged, this, &PropertiesWidget::updateSavePath);
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentMetadataLoaded, this, &PropertiesWidget::updateTorrentInfos);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentMetadataReceived, this, &PropertiesWidget::updateTorrentInfos);
|
||||||
connect(m_ui->filesList, &QAbstractItemView::clicked
|
connect(m_ui->filesList, &QAbstractItemView::clicked
|
||||||
, m_ui->filesList, qOverload<const QModelIndex &>(&QAbstractItemView::edit));
|
, m_ui->filesList, qOverload<const QModelIndex &>(&QAbstractItemView::edit));
|
||||||
connect(m_ui->filesList, &QWidget::customContextMenuRequested, this, &PropertiesWidget::displayFilesListMenu);
|
connect(m_ui->filesList, &QWidget::customContextMenuRequested, this, &PropertiesWidget::displayFilesListMenu);
|
||||||
@ -404,7 +404,7 @@ void PropertiesWidget::loadDynamicData()
|
|||||||
switch (m_ui->stackedProperties->currentIndex())
|
switch (m_ui->stackedProperties->currentIndex())
|
||||||
{
|
{
|
||||||
case PropTabBar::MainTab:
|
case PropTabBar::MainTab:
|
||||||
{
|
{
|
||||||
m_ui->labelWastedVal->setText(Utils::Misc::friendlyUnit(m_torrent->wastedSize()));
|
m_ui->labelWastedVal->setText(Utils::Misc::friendlyUnit(m_torrent->wastedSize()));
|
||||||
|
|
||||||
m_ui->labelUpTotalVal->setText(tr("%1 (%2 this session)").arg(Utils::Misc::friendlyUnit(m_torrent->totalUpload())
|
m_ui->labelUpTotalVal->setText(tr("%1 (%2 this session)").arg(Utils::Misc::friendlyUnit(m_torrent->totalUpload())
|
||||||
|
@ -142,7 +142,7 @@ TransferListModel::TransferListModel(QObject *parent)
|
|||||||
connect(Session::instance(), &Session::torrentsUpdated, this, &TransferListModel::handleTorrentsUpdated);
|
connect(Session::instance(), &Session::torrentsUpdated, this, &TransferListModel::handleTorrentsUpdated);
|
||||||
|
|
||||||
connect(Session::instance(), &Session::torrentFinished, this, &TransferListModel::handleTorrentStatusUpdated);
|
connect(Session::instance(), &Session::torrentFinished, this, &TransferListModel::handleTorrentStatusUpdated);
|
||||||
connect(Session::instance(), &Session::torrentMetadataLoaded, this, &TransferListModel::handleTorrentStatusUpdated);
|
connect(Session::instance(), &Session::torrentMetadataReceived, this, &TransferListModel::handleTorrentStatusUpdated);
|
||||||
connect(Session::instance(), &Session::torrentResumed, this, &TransferListModel::handleTorrentStatusUpdated);
|
connect(Session::instance(), &Session::torrentResumed, this, &TransferListModel::handleTorrentStatusUpdated);
|
||||||
connect(Session::instance(), &Session::torrentPaused, this, &TransferListModel::handleTorrentStatusUpdated);
|
connect(Session::instance(), &Session::torrentPaused, this, &TransferListModel::handleTorrentStatusUpdated);
|
||||||
connect(Session::instance(), &Session::torrentFinishedChecking, this, &TransferListModel::handleTorrentStatusUpdated);
|
connect(Session::instance(), &Session::torrentFinishedChecking, this, &TransferListModel::handleTorrentStatusUpdated);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user