mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-16 02:03:07 -07:00
parent
e4313d6651
commit
dcf3e97291
42 changed files with 933 additions and 639 deletions
|
@ -50,6 +50,7 @@
|
|||
#include <QProcess>
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
#include <QAbstractButton>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QPixmapCache>
|
||||
|
@ -63,6 +64,7 @@
|
|||
#endif // Q_OS_MACOS
|
||||
#endif
|
||||
|
||||
#include "base/addtorrentmanager.h"
|
||||
#include "base/bittorrent/infohash.h"
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/torrent.h"
|
||||
|
@ -81,7 +83,6 @@
|
|||
#include "base/search/searchpluginmanager.h"
|
||||
#include "base/settingsstorage.h"
|
||||
#include "base/torrentfileswatcher.h"
|
||||
#include "base/utils/compare.h"
|
||||
#include "base/utils/fs.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/string.h"
|
||||
|
@ -91,7 +92,7 @@
|
|||
#include "upgrade.h"
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
#include "gui/addnewtorrentdialog.h"
|
||||
#include "gui/guiaddtorrentmanager.h"
|
||||
#include "gui/desktopintegration.h"
|
||||
#include "gui/mainwindow.h"
|
||||
#include "gui/shutdownconfirmdialog.h"
|
||||
|
@ -682,6 +683,21 @@ void Application::torrentFinished(const BitTorrent::Torrent *torrent)
|
|||
LogMsg(tr("Torrent: %1, sending mail notification").arg(torrent->name()));
|
||||
sendNotificationEmail(torrent);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
if (Preferences::instance()->isRecursiveDownloadEnabled())
|
||||
{
|
||||
// Check whether it contains .torrent files
|
||||
for (const Path &torrentRelpath : asConst(torrent->filePaths()))
|
||||
{
|
||||
if (torrentRelpath.hasExtension(u".torrent"_s))
|
||||
{
|
||||
askRecursiveTorrentDownloadConfirmation(torrent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Application::allTorrentsFinished()
|
||||
|
@ -744,18 +760,15 @@ void Application::processParams(const QBtCommandLineParameters ¶ms)
|
|||
// be shown and skipTorrentDialog is undefined. The other is when
|
||||
// skipTorrentDialog is false, meaning that the application setting
|
||||
// should be overridden.
|
||||
const bool showDialog = !params.skipDialog.value_or(!AddNewTorrentDialog::isEnabled());
|
||||
if (showDialog)
|
||||
{
|
||||
for (const QString &torrentSource : params.torrentSources)
|
||||
AddNewTorrentDialog::show(torrentSource, params.addTorrentParams, m_window);
|
||||
}
|
||||
else
|
||||
AddTorrentOption addTorrentOption = AddTorrentOption::Default;
|
||||
if (params.skipDialog.has_value())
|
||||
addTorrentOption = params.skipDialog.value() ? AddTorrentOption::SkipDialog : AddTorrentOption::ShowDialog;
|
||||
for (const QString &torrentSource : params.torrentSources)
|
||||
m_addTorrentManager->addTorrent(torrentSource, params.addTorrentParams, addTorrentOption);
|
||||
#else
|
||||
for (const QString &torrentSource : params.torrentSources)
|
||||
m_addTorrentManager->addTorrent(torrentSource, params.addTorrentParams);
|
||||
#endif
|
||||
{
|
||||
for (const QString &torrentSource : params.torrentSources)
|
||||
BitTorrent::Session::instance()->addTorrent(torrentSource, params.addTorrentParams);
|
||||
}
|
||||
}
|
||||
|
||||
int Application::exec()
|
||||
|
@ -822,11 +835,13 @@ int Application::exec()
|
|||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentFinished, this, &Application::torrentFinished);
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::allTorrentsFinished, this, &Application::allTorrentsFinished, Qt::QueuedConnection);
|
||||
|
||||
m_addTorrentManager = new AddTorrentManagerImpl(this, BitTorrent::Session::instance(), this);
|
||||
|
||||
Net::GeoIPManager::initInstance();
|
||||
TorrentFilesWatcher::initInstance();
|
||||
|
||||
new RSS::Session; // create RSS::Session singleton
|
||||
new RSS::AutoDownloader; // create RSS::AutoDownloader singleton
|
||||
new RSS::AutoDownloader(this); // create RSS::AutoDownloader singleton
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
const auto *btSession = BitTorrent::Session::instance();
|
||||
|
@ -834,30 +849,25 @@ int Application::exec()
|
|||
, [this](const BitTorrent::Torrent *torrent, const QString &msg)
|
||||
{
|
||||
m_desktopIntegration->showNotification(tr("I/O Error", "i.e: Input/Output Error")
|
||||
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
|
||||
, "e.g: An error occurred for torrent 'xxx.avi'.\n Reason: disk is full.").arg(torrent->name(), msg));
|
||||
});
|
||||
connect(btSession, &BitTorrent::Session::loadTorrentFailed, this
|
||||
, [this](const QString &error)
|
||||
{
|
||||
m_desktopIntegration->showNotification(tr("Error"), tr("Failed to add torrent: %1").arg(error));
|
||||
});
|
||||
connect(btSession, &BitTorrent::Session::torrentAdded, this
|
||||
, [this](const BitTorrent::Torrent *torrent)
|
||||
{
|
||||
if (isTorrentAddedNotificationsEnabled())
|
||||
m_desktopIntegration->showNotification(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
|
||||
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
|
||||
, "e.g: An error occurred for torrent 'xxx.avi'.\n Reason: disk is full.").arg(torrent->name(), msg));
|
||||
});
|
||||
connect(btSession, &BitTorrent::Session::torrentFinished, this
|
||||
, [this](const BitTorrent::Torrent *torrent)
|
||||
{
|
||||
m_desktopIntegration->showNotification(tr("Download completed"), tr("'%1' has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(torrent->name()));
|
||||
});
|
||||
connect(btSession, &BitTorrent::Session::downloadFromUrlFailed, this
|
||||
, [this](const QString &url, const QString &reason)
|
||||
connect(m_addTorrentManager, &AddTorrentManager::torrentAdded, this
|
||||
, [this]([[maybe_unused]] const QString &source, const BitTorrent::Torrent *torrent)
|
||||
{
|
||||
m_desktopIntegration->showNotification(tr("URL download error")
|
||||
, tr("Couldn't download file at URL '%1', reason: %2.").arg(url, reason));
|
||||
if (isTorrentAddedNotificationsEnabled())
|
||||
m_desktopIntegration->showNotification(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
|
||||
});
|
||||
connect(m_addTorrentManager, &AddTorrentManager::addTorrentFailed, this
|
||||
, [this](const QString &source, const QString &reason)
|
||||
{
|
||||
m_desktopIntegration->showNotification(tr("Add torrent failed")
|
||||
, tr("Couldn't add torrent '%1', reason: %2.").arg(source, reason));
|
||||
});
|
||||
|
||||
disconnect(m_desktopIntegration, &DesktopIntegration::activationRequested, this, &Application::createStartupProgressDialog);
|
||||
|
@ -983,6 +993,57 @@ void Application::createStartupProgressDialog()
|
|||
});
|
||||
}
|
||||
|
||||
void Application::askRecursiveTorrentDownloadConfirmation(const BitTorrent::Torrent *torrent)
|
||||
{
|
||||
const auto torrentID = torrent->id();
|
||||
|
||||
QMessageBox *confirmBox = new QMessageBox(QMessageBox::Question, tr("Recursive download confirmation")
|
||||
, tr("The torrent '%1' contains .torrent files, do you want to proceed with their downloads?").arg(torrent->name())
|
||||
, (QMessageBox::Yes | QMessageBox::No | QMessageBox::NoToAll), mainWindow());
|
||||
confirmBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
const QAbstractButton *yesButton = confirmBox->button(QMessageBox::Yes);
|
||||
QAbstractButton *neverButton = confirmBox->button(QMessageBox::NoToAll);
|
||||
neverButton->setText(tr("Never"));
|
||||
|
||||
connect(confirmBox, &QMessageBox::buttonClicked, this
|
||||
, [this, torrentID, yesButton, neverButton](const QAbstractButton *button)
|
||||
{
|
||||
if (button == yesButton)
|
||||
{
|
||||
recursiveTorrentDownload(torrentID);
|
||||
}
|
||||
else if (button == neverButton)
|
||||
{
|
||||
Preferences::instance()->setRecursiveDownloadEnabled(false);
|
||||
}
|
||||
});
|
||||
confirmBox->open();
|
||||
}
|
||||
|
||||
void Application::recursiveTorrentDownload(const BitTorrent::TorrentID &torrentID)
|
||||
{
|
||||
const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->getTorrent(torrentID);
|
||||
if (!torrent)
|
||||
return;
|
||||
|
||||
for (const Path &torrentRelpath : asConst(torrent->filePaths()))
|
||||
{
|
||||
if (torrentRelpath.hasExtension(u".torrent"_s))
|
||||
{
|
||||
const Path torrentFullpath = torrent->savePath() / torrentRelpath;
|
||||
|
||||
LogMsg(tr("Recursive download .torrent file within torrent. Source torrent: \"%1\". File: \"%2\"")
|
||||
.arg(torrent->name(), torrentFullpath.toString()));
|
||||
|
||||
BitTorrent::AddTorrentParams params;
|
||||
// Passing the save path along to the sub torrent file
|
||||
params.savePath = torrent->savePath();
|
||||
addTorrentManager()->addTorrent(torrentFullpath.data(), params, AddTorrentOption::SkipDialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
bool Application::event(QEvent *ev)
|
||||
{
|
||||
|
@ -1018,7 +1079,7 @@ void Application::initializeTranslation()
|
|||
const QString localeStr = pref->getLocale();
|
||||
|
||||
if (m_qtTranslator.load((u"qtbase_" + localeStr), QLibraryInfo::path(QLibraryInfo::TranslationsPath))
|
||||
|| m_qtTranslator.load((u"qt_" + localeStr), QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
|
||||
|| m_qtTranslator.load((u"qt_" + localeStr), QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
|
||||
{
|
||||
qDebug("Qt %s locale recognized, using translation.", qUtf8Printable(localeStr));
|
||||
}
|
||||
|
@ -1262,6 +1323,7 @@ void Application::cleanup()
|
|||
delete RSS::Session::instance();
|
||||
|
||||
TorrentFilesWatcher::freeInstance();
|
||||
delete m_addTorrentManager;
|
||||
BitTorrent::Session::freeInstance();
|
||||
Net::GeoIPManager::freeInstance();
|
||||
Net::DownloadManager::freeInstance();
|
||||
|
@ -1296,3 +1358,8 @@ void Application::cleanup()
|
|||
Utils::Misc::shutdownComputer(m_shutdownAct);
|
||||
}
|
||||
}
|
||||
|
||||
AddTorrentManagerImpl *Application::addTorrentManager() const
|
||||
{
|
||||
return m_addTorrentManager;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue