2015-09-08 17:05:59 +02:00
|
|
|
#include "./downloadinteraction.h"
|
|
|
|
#include "./settings.h"
|
2015-04-22 19:32:04 +02:00
|
|
|
|
2015-09-08 17:05:59 +02:00
|
|
|
#include "../network/download.h"
|
|
|
|
#include "../network/permissionstatus.h"
|
2015-04-22 19:32:04 +02:00
|
|
|
|
|
|
|
#include <qtutilities/enterpassworddialog/enterpassworddialog.h>
|
|
|
|
|
2017-05-01 03:22:50 +02:00
|
|
|
#include <QCoreApplication>
|
2015-04-22 19:32:04 +02:00
|
|
|
#include <QFileDialog>
|
2017-05-01 03:22:50 +02:00
|
|
|
#include <QMessageBox>
|
2015-04-22 19:32:04 +02:00
|
|
|
#include <QPushButton>
|
2016-02-08 21:21:46 +01:00
|
|
|
#include <QStringBuilder>
|
2015-04-22 19:32:04 +02:00
|
|
|
|
|
|
|
using namespace Network;
|
2019-06-10 22:50:15 +02:00
|
|
|
using namespace QtUtilities;
|
2015-04-22 19:32:04 +02:00
|
|
|
|
|
|
|
namespace QtGui {
|
|
|
|
|
2017-05-01 03:22:50 +02:00
|
|
|
DownloadInteraction::DownloadInteraction(QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, m_parentWidget(nullptr)
|
|
|
|
{
|
|
|
|
}
|
2015-04-22 19:32:04 +02:00
|
|
|
|
2017-05-01 03:22:50 +02:00
|
|
|
DownloadInteraction::DownloadInteraction(QWidget *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, m_parentWidget(parent)
|
|
|
|
{
|
|
|
|
}
|
2015-04-22 19:32:04 +02:00
|
|
|
|
|
|
|
void DownloadInteraction::connectDownload(Download *download)
|
|
|
|
{
|
2017-05-01 03:22:50 +02:00
|
|
|
connect(download, &Download::outputDeviceRequired, this,
|
|
|
|
static_cast<void (DownloadInteraction::*)(Download *, size_t)>(&DownloadInteraction::downloadRequiresOutputDevice));
|
2015-04-22 19:32:04 +02:00
|
|
|
connect(download, &Download::overwriteingPermissionRequired, this, &DownloadInteraction::downloadRequriesOverwritePermission);
|
|
|
|
connect(download, &Download::appendingPermissionRequired, this, &DownloadInteraction::downloadRequriesAppendingPermission);
|
|
|
|
connect(download, &Download::redirectionPermissonRequired, this, &DownloadInteraction::downloadRequiresRedirectionPermission);
|
|
|
|
connect(download, &Download::authenticationRequired, this, &DownloadInteraction::downloadRequiresAuthentication);
|
|
|
|
connect(download, &Download::sslErrors, this, &DownloadInteraction::downloadHasSslErrors);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadInteraction::disconnectDownload(Download *download)
|
|
|
|
{
|
|
|
|
download->disconnect(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadInteraction::downloadRequiresOutputDevice(Download *download, size_t optionIndex)
|
|
|
|
{
|
|
|
|
downloadRequiresOutputDevice(download, optionIndex, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadInteraction::downloadRequiresOutputDevice(Download *download, size_t optionIndex, bool forceFileDialog)
|
|
|
|
{
|
|
|
|
QString fileName = download->suitableFilename();
|
|
|
|
// use default directory and the "suitable file name" to determine the target path
|
2017-05-01 03:22:50 +02:00
|
|
|
if (TargetPage::determineTargetFileWithoutAsking() // if correspondent option is set
|
|
|
|
&& !forceFileDialog // and the caller don't wants to force the file dialog
|
|
|
|
&& (TargetPage::targetDirectory().isEmpty() || QDir(TargetPage::targetDirectory()).exists()) // and the default directory exists or is empty
|
|
|
|
&& !fileName.isEmpty()) { // and the file name is not empty
|
2016-04-04 14:51:51 +02:00
|
|
|
download->provideOutputDevice(optionIndex, new QFile(TargetPage::targetDirectory() % QChar('/') % fileName), true);
|
2021-07-03 19:54:06 +02:00
|
|
|
} else { // ask the user for the target path otherwise
|
2015-04-22 19:32:04 +02:00
|
|
|
QFileDialog *dlg = new QFileDialog(m_parentWidget);
|
2016-02-08 21:21:46 +01:00
|
|
|
#ifndef Q_OS_WIN
|
|
|
|
// the native dialog can only be shown modal under Windows
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->setModal(false);
|
2016-02-08 21:21:46 +01:00
|
|
|
#endif
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->setFileMode(QFileDialog::AnyFile);
|
|
|
|
dlg->setAcceptMode(QFileDialog::AcceptSave);
|
2016-04-04 14:51:51 +02:00
|
|
|
dlg->setDirectory(TargetPage::targetDirectory());
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->selectFile(fileName);
|
|
|
|
dlg->setOption(QFileDialog::DontConfirmOverwrite, true);
|
2017-05-01 03:22:50 +02:00
|
|
|
if (!download->title().isEmpty()) {
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->setWindowTitle(tr("Where to save »%1«?").arg(download->title()));
|
|
|
|
}
|
2017-05-01 03:22:50 +02:00
|
|
|
connect(dlg, &QFileDialog::finished, [download, optionIndex, dlg](int result) {
|
|
|
|
if (result == QFileDialog::Accepted && dlg->selectedFiles().size() == 1) {
|
2016-02-08 21:21:46 +01:00
|
|
|
download->provideOutputDevice(optionIndex, new QFile(dlg->selectedFiles().front()), true);
|
2015-04-22 19:32:04 +02:00
|
|
|
} else {
|
|
|
|
download->provideOutputDevice(optionIndex, nullptr);
|
|
|
|
}
|
|
|
|
dlg->deleteLater();
|
|
|
|
});
|
|
|
|
dlg->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadInteraction::downloadRequriesOverwritePermission(Download *download, size_t optionIndex, const QString &file)
|
|
|
|
{
|
2017-05-01 03:22:50 +02:00
|
|
|
if (TargetPage::overwriteWithoutAsking()) {
|
2015-04-22 19:32:04 +02:00
|
|
|
download->setOverwritePermission(optionIndex, PermissionStatus::Allowed);
|
|
|
|
} else {
|
|
|
|
QString message = tr("<p>The output file <i>%1</i> already exists.</p><p>Do you want to overwrite the existing file?</p>").arg(file);
|
|
|
|
QMessageBox *dlg = new QMessageBox(m_parentWidget);
|
|
|
|
dlg->setModal(false);
|
|
|
|
dlg->setTextFormat(Qt::RichText);
|
|
|
|
dlg->setText(message);
|
|
|
|
dlg->setIcon(QMessageBox::Warning);
|
|
|
|
QPushButton *overwriteButton = dlg->addButton(tr("Overwrite (only this time)"), QMessageBox::YesRole);
|
|
|
|
QPushButton *overwriteAlwaysButton = dlg->addButton(tr("Overwrite (always)"), QMessageBox::YesRole);
|
|
|
|
QPushButton *selectOtherButton = dlg->addButton(tr("Select other download target"), QMessageBox::ActionRole);
|
|
|
|
QPushButton *abortButton = dlg->addButton(tr("Abort"), QMessageBox::NoRole);
|
|
|
|
dlg->setEscapeButton(abortButton);
|
|
|
|
// show warning message
|
2017-05-01 03:22:50 +02:00
|
|
|
connect(dlg, &QMessageBox::finished,
|
|
|
|
[download, optionIndex, dlg, overwriteButton, overwriteAlwaysButton, selectOtherButton, abortButton, this](int) {
|
|
|
|
if (dlg->clickedButton() == overwriteAlwaysButton) {
|
|
|
|
// set dontAskBeforeOverwriting to true if the user clicked yes to all
|
|
|
|
TargetPage::overwriteWithoutAsking() = true;
|
|
|
|
}
|
|
|
|
if (dlg->clickedButton() == overwriteButton || dlg->clickedButton() == overwriteAlwaysButton) {
|
|
|
|
download->setOverwritePermission(optionIndex, PermissionStatus::Allowed);
|
|
|
|
} else if (dlg->clickedButton() == selectOtherButton) {
|
|
|
|
downloadRequiresOutputDevice(download, optionIndex, true);
|
|
|
|
} else {
|
|
|
|
download->setOverwritePermission(optionIndex, PermissionStatus::Refused);
|
|
|
|
}
|
|
|
|
dlg->deleteLater();
|
|
|
|
});
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-01 03:22:50 +02:00
|
|
|
void DownloadInteraction::downloadRequriesAppendingPermission(
|
|
|
|
Download *download, size_t optionIndex, const QString &file, quint64 offset, quint64 fileSize)
|
2015-04-22 19:32:04 +02:00
|
|
|
{
|
2017-05-01 03:22:50 +02:00
|
|
|
if (TargetPage::overwriteWithoutAsking()) {
|
2015-04-22 19:32:04 +02:00
|
|
|
download->setAppendPermission(optionIndex, PermissionStatus::Allowed);
|
|
|
|
} else {
|
2017-05-01 03:22:50 +02:00
|
|
|
QString message = tr("<p>The output file <i>%1</i> already exists. The downloader assumes it contains previously downloaded data.</p><p>Do "
|
|
|
|
"you want to <b>append</b> the received data to the existing file?</p>")
|
|
|
|
.arg(file);
|
|
|
|
if (offset != fileSize) {
|
|
|
|
message.append(
|
|
|
|
tr("<p><b>The current download offset (%1) does not match the size of the existing file (%2).</b></p>").arg(offset).arg(fileSize));
|
2015-04-22 19:32:04 +02:00
|
|
|
}
|
|
|
|
QMessageBox *dlg = new QMessageBox(m_parentWidget);
|
|
|
|
dlg->setModal(false);
|
|
|
|
dlg->setTextFormat(Qt::RichText);
|
|
|
|
dlg->setText(message);
|
|
|
|
dlg->setIcon(QMessageBox::Warning);
|
|
|
|
QPushButton *appendButton = dlg->addButton(tr("Append"), QMessageBox::YesRole);
|
|
|
|
QPushButton *abortButton = dlg->addButton(tr("Abort"), QMessageBox::NoRole);
|
|
|
|
dlg->setEscapeButton(abortButton);
|
|
|
|
// show warning message
|
2017-05-01 03:22:50 +02:00
|
|
|
connect(dlg, &QMessageBox::finished, [download, optionIndex, dlg, appendButton, abortButton, this](int) {
|
|
|
|
if (dlg->clickedButton() == appendButton) {
|
2015-04-22 19:32:04 +02:00
|
|
|
download->setAppendPermission(optionIndex, PermissionStatus::Allowed);
|
|
|
|
} else {
|
|
|
|
download->setAppendPermission(optionIndex, PermissionStatus::Refused);
|
|
|
|
}
|
|
|
|
dlg->deleteLater();
|
|
|
|
});
|
|
|
|
dlg->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadInteraction::downloadRequiresRedirectionPermission(Download *download, size_t optionIndex)
|
|
|
|
{
|
2017-05-01 03:22:50 +02:00
|
|
|
if (MiscPage::redirectWithoutAsking()) {
|
2015-04-22 19:32:04 +02:00
|
|
|
download->setRedirectPermission(optionIndex, PermissionStatus::Allowed);
|
|
|
|
} else {
|
|
|
|
const QUrl &originalUrl = download->downloadUrl(download->options().at(optionIndex).redirectionOf());
|
2017-05-01 03:22:50 +02:00
|
|
|
const QUrl &newUrl = download->downloadUrl(optionIndex);
|
|
|
|
QString message = tr(
|
|
|
|
"<p>Do you want to redirect form <i>%1</i> to <i>%2</i>?</p><p>The redirection URL will be added to the options so you can it select "
|
2019-07-20 20:20:58 +02:00
|
|
|
"later, too.</p>")
|
|
|
|
.arg(originalUrl.toString(), newUrl.toString());
|
2015-04-22 19:32:04 +02:00
|
|
|
QMessageBox *dlg = new QMessageBox(m_parentWidget);
|
|
|
|
dlg->setModal(false);
|
|
|
|
dlg->setTextFormat(Qt::RichText);
|
|
|
|
dlg->setText(message);
|
|
|
|
dlg->setIcon(QMessageBox::Question);
|
|
|
|
dlg->setStandardButtons(QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No);
|
2017-05-01 03:22:50 +02:00
|
|
|
connect(dlg, &QMessageBox::finished, [download, optionIndex, dlg, this](int result) {
|
|
|
|
switch (result) {
|
2015-04-22 19:32:04 +02:00
|
|
|
case QMessageBox::YesToAll:
|
2016-04-04 14:51:51 +02:00
|
|
|
MiscPage::redirectWithoutAsking() = true;
|
2015-04-22 19:32:04 +02:00
|
|
|
download->setRedirectPermission(optionIndex, PermissionStatus::AlwaysAllowed);
|
|
|
|
break;
|
|
|
|
case QMessageBox::Yes:
|
|
|
|
download->setRedirectPermission(optionIndex, PermissionStatus::Allowed);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
download->setRedirectPermission(optionIndex, PermissionStatus::Refused);
|
|
|
|
}
|
|
|
|
dlg->deleteLater();
|
|
|
|
});
|
|
|
|
connect(download, &Download::destroyed, dlg, &QMessageBox::deleteLater);
|
|
|
|
dlg->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadInteraction::downloadRequiresAuthentication(Download *download, size_t optionIndex, const QString &realm)
|
|
|
|
{
|
2019-06-10 22:50:15 +02:00
|
|
|
auto *const dlg = new EnterPasswordDialog(m_parentWidget);
|
2015-04-22 19:32:04 +02:00
|
|
|
QString downloadName = download->downloadUrl().isEmpty() ? download->id() : download->downloadUrl().toString();
|
|
|
|
dlg->setModal(false);
|
|
|
|
dlg->setPromptForUserName(true);
|
|
|
|
dlg->setPasswordRequired(true);
|
|
|
|
dlg->setInstruction(tr("<p>Enter authentication credentials for the download <i>%1</i>.</p>").arg(downloadName));
|
2017-05-01 03:22:50 +02:00
|
|
|
if (!realm.isEmpty()) {
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->setDescription(tr("Realm: %1").arg(realm));
|
|
|
|
}
|
2019-06-10 22:50:15 +02:00
|
|
|
connect(dlg, &EnterPasswordDialog::accepted, [download, optionIndex, dlg] {
|
2015-04-22 19:32:04 +02:00
|
|
|
download->provideAuthenticationCredentials(optionIndex, AuthenticationCredentials(dlg->userName(), dlg->password()));
|
|
|
|
dlg->deleteLater();
|
|
|
|
});
|
|
|
|
connect(download, &Download::destroyed, dlg, &QMessageBox::deleteLater);
|
|
|
|
dlg->adjustSize();
|
|
|
|
dlg->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadInteraction::downloadHasSslErrors(Download *download, size_t optionIndex, const QList<QSslError> &sslErrors)
|
|
|
|
{
|
|
|
|
QString downloadName = download->downloadUrl().isEmpty() ? download->id() : download->downloadUrl().toString();
|
2016-04-09 00:52:21 +02:00
|
|
|
QString details;
|
2019-12-30 22:27:20 +01:00
|
|
|
for (const QSslError &error : sslErrors) {
|
2017-05-01 03:22:50 +02:00
|
|
|
if (!details.isEmpty()) {
|
2016-04-09 00:52:21 +02:00
|
|
|
details.append(QStringLiteral("\n\n"));
|
|
|
|
}
|
|
|
|
details.append(error.errorString());
|
2017-05-01 03:22:50 +02:00
|
|
|
if (!error.certificate().isNull()) {
|
2016-04-09 00:52:21 +02:00
|
|
|
details.append(QChar('\n'));
|
|
|
|
details.append(error.certificate().toText());
|
2015-04-22 19:32:04 +02:00
|
|
|
}
|
|
|
|
}
|
2016-09-12 21:53:36 +02:00
|
|
|
auto *dlg = new QMessageBox(m_parentWidget);
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->setModal(false);
|
2021-07-03 19:54:06 +02:00
|
|
|
dlg->setWindowTitle(tr("SSL errors occurred") % QStringLiteral(" - ") % QCoreApplication::applicationName());
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->setTextFormat(Qt::RichText);
|
2016-04-09 00:52:21 +02:00
|
|
|
dlg->setText(tr("The download <i>%1</i> has SSL errors.").arg(downloadName));
|
|
|
|
dlg->setInformativeText(tr("Do you want to ignore the SSL errors for this download?"));
|
|
|
|
dlg->setDetailedText(details);
|
2015-04-22 19:32:04 +02:00
|
|
|
dlg->setIcon(QMessageBox::Warning);
|
|
|
|
dlg->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
2017-05-01 03:22:50 +02:00
|
|
|
connect(dlg, &QMessageBox::finished, [download, optionIndex, dlg](int result) {
|
|
|
|
switch (result) {
|
2015-04-22 19:32:04 +02:00
|
|
|
case QMessageBox::Yes:
|
|
|
|
download->setIgnoreSslErrorsPermission(optionIndex, PermissionStatus::Allowed);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
download->setIgnoreSslErrorsPermission(optionIndex, PermissionStatus::Refused);
|
|
|
|
}
|
|
|
|
dlg->deleteLater();
|
|
|
|
});
|
|
|
|
connect(download, &Download::destroyed, dlg, &QMessageBox::deleteLater);
|
|
|
|
dlg->show();
|
|
|
|
}
|
2019-07-20 20:20:58 +02:00
|
|
|
} // namespace QtGui
|