Commit 6f32ff81 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Allow canceling all longer running imports

Move the progress dialog to the base class of all import commands. The
progress dialog is shown after 1 second. Reorder the postprocessing tasks,
so that the progress dialog is closed after tasks that do not show dialogs
but before tasks that may show other dialogs.

GnuPG-bug-id: 5805
parent d38ca481
......@@ -121,6 +121,11 @@ void ImportCertificateFromFileCommand::doStart()
return;
}
d->setProgressWindowTitle(i18nc("@title:window", "Importing Certificates"));
d->setProgressLabelText(i18np("Importing certificates from 1 file...",
"Importing certificates from %1 files...",
d->files.size()));
//TODO: use KIO here
d->setWaitForMoreJobs(true);
for (const QString &fn : std::as_const(d->files)) {
......
......@@ -14,8 +14,6 @@
#include <KLocalizedString>
#include <QProgressDialog>
#include "kleopatra_debug.h"
using namespace Kleo;
......@@ -64,14 +62,10 @@ ImportCertificateFromKeyserverCommand::Private::~Private() = default;
void ImportCertificateFromKeyserverCommand::Private::start()
{
const auto progressDialog = new QProgressDialog{parentWidgetOrView()};
progressDialog->setAttribute(Qt::WA_DeleteOnClose);
progressDialog->setModal(true);
progressDialog->setRange(0, 0);
progressDialog->setWindowTitle(i18nc("@title:window", "Fetching Keys"));
progressDialog->setLabelText(i18np("Fetching 1 key... (this can take a while)", "Fetching %1 keys... (this can take a while)", mKeyIds.size()));
connect(progressDialog, &QProgressDialog::canceled, q, &Command::cancel);
connect(q, &Command::finished, progressDialog, [progressDialog]() { progressDialog->accept(); });
setProgressWindowTitle(i18nc("@title:window", "Fetching Keys"));
setProgressLabelText(i18np("Fetching 1 key... (this can take a while)",
"Fetching %1 keys... (this can take a while)",
mKeyIds.size()));
setWaitForMoreJobs(true);
// start one import per key id to allow canceling the key retrieval without
......@@ -80,8 +74,6 @@ void ImportCertificateFromKeyserverCommand::Private::start()
startImport(GpgME::OpenPGP, {keyId}, mId);
}
setWaitForMoreJobs(false);
progressDialog->show();
}
ImportCertificateFromKeyserverCommand::ImportCertificateFromKeyserverCommand(const QStringList &keyIds, const QString &id)
......
......@@ -48,6 +48,7 @@
#include <QByteArray>
#include <QEventLoop>
#include <QProgressDialog>
#include <QString>
#include <QWidget>
#include <QTreeView>
......@@ -178,10 +179,17 @@ bool importWasCanceled(const ImportResultData &r)
ImportCertificatesCommand::Private::Private(ImportCertificatesCommand *qq, KeyListController *c)
: Command::Private(qq, c)
, progressWindowTitle{i18nc("@title:window", "Importing Certificates")}
, progressLabelText{i18n("Importing certificates... (this can take a while)")}
{
}
ImportCertificatesCommand::Private::~Private() = default;
ImportCertificatesCommand::Private::~Private()
{
if (progressDialog) {
delete progressDialog;
}
}
#define d d_func()
#define q q_func()
......@@ -487,6 +495,7 @@ void ImportCertificatesCommand::Private::importResult(const ImportResult &result
const auto job = *it;
jobs.erase(std::remove(std::begin(jobs), std::end(jobs), job), std::end(jobs));
increaseProgressValue();
importResult({job.id, job.protocol, job.type, result});
}
......@@ -589,11 +598,14 @@ static void handleExternalCMSImports(const std::vector<ImportResultData> &result
void ImportCertificatesCommand::Private::processResults()
{
importGroups();
handleExternalCMSImports(results);
handleOwnerTrust(results);
// ensure that the progress dialog is closed before we show any other dialogs
setProgressToMaximum();
importGroups();
handleOwnerTrust(results);
showDetails(results, importedGroups);
......@@ -652,6 +664,8 @@ void ImportCertificatesCommand::Private::keyCacheUpdated()
}
if (std::any_of(std::cbegin(results), std::cend(results), &importFailed)) {
// ensure that the progress dialog is closed before we show any other dialogs
setProgressToMaximum();
setImportResultProxyModel(results);
for (const auto &r : results) {
if (importFailed(r)) {
......@@ -695,6 +709,7 @@ void ImportCertificatesCommand::Private::importGroups()
return storeGroup(group, path);
});
}
increaseProgressValue();
}
}
......@@ -745,6 +760,7 @@ void ImportCertificatesCommand::Private::startImport(GpgME::Protocol protocol, c
if (err.code()) {
importResult({id, protocol, ImportType::Local, ImportResult{err}});
} else {
increaseProgressMaximum();
jobs.push_back({id, protocol, ImportType::Local, job.release(), connections});
}
}
......@@ -790,6 +806,7 @@ void ImportCertificatesCommand::Private::startImport(GpgME::Protocol protocol, c
if (err.code()) {
importResult({id, protocol, ImportType::External, ImportResult{err}});
} else {
increaseProgressMaximum();
jobs.push_back({id, protocol, ImportType::External, job.release(), connections});
}
}
......@@ -834,6 +851,7 @@ void ImportCertificatesCommand::Private::startImport(GpgME::Protocol protocol, c
if (err.code()) {
importResult({id, protocol, ImportType::External, ImportResult{err}});
} else {
increaseProgressMaximum();
jobs.push_back({id, protocol, ImportType::External, job.release(), connections});
}
#endif
......@@ -841,9 +859,63 @@ void ImportCertificatesCommand::Private::startImport(GpgME::Protocol protocol, c
void ImportCertificatesCommand::Private::importGroupsFromFile(const QString &filename)
{
increaseProgressMaximum();
filesToImportGroupsFrom.push_back(filename);
}
void ImportCertificatesCommand::Private::setUpProgressDialog()
{
if (progressDialog) {
return;
}
progressDialog = new QProgressDialog{parentWidgetOrView()};
progressDialog->setModal(true);
progressDialog->setWindowTitle(progressWindowTitle);
progressDialog->setLabelText(progressLabelText);
progressDialog->setMinimumDuration(1000);
progressDialog->setMaximum(1);
progressDialog->setValue(0);
connect(progressDialog, &QProgressDialog::canceled, q, &Command::cancel);
connect(q, &Command::finished, progressDialog, [this]() { progressDialog->accept(); });
}
void ImportCertificatesCommand::Private::setProgressWindowTitle(const QString &title)
{
if (progressDialog) {
progressDialog->setWindowTitle(title);
} else {
progressWindowTitle = title;
}
}
void ImportCertificatesCommand::Private::setProgressLabelText(const QString &text)
{
if (progressDialog) {
progressDialog->setLabelText(text);
} else {
progressLabelText = text;
}
}
void ImportCertificatesCommand::Private::increaseProgressMaximum()
{
setUpProgressDialog();
progressDialog->setMaximum(progressDialog->maximum() + 1);
qCDebug(KLEOPATRA_LOG) << __func__ << "progress:" << progressDialog->value() << "/" << progressDialog->maximum();
}
void ImportCertificatesCommand::Private::increaseProgressValue()
{
progressDialog->setValue(progressDialog->value() + 1);
qCDebug(KLEOPATRA_LOG) << __func__ << "progress:" << progressDialog->value() << "/" << progressDialog->maximum();
}
void ImportCertificatesCommand::Private::setProgressToMaximum()
{
qCDebug(KLEOPATRA_LOG) << __func__;
progressDialog->setValue(progressDialog->maximum());
}
void ImportCertificatesCommand::doCancel()
{
const auto jobsToCancel = d->jobs;
......
......@@ -40,6 +40,7 @@ class KeyCacheAutoRefreshSuspension;
}
class QByteArray;
class QProgressDialog;
enum class ImportType
{
......@@ -98,6 +99,8 @@ public:
~Private() override;
void setWaitForMoreJobs(bool waiting);
void setProgressWindowTitle(const QString &title);
void setProgressLabelText(const QString &text);
void startImport(GpgME::Protocol proto, const QByteArray &data, const QString &id = QString(), const ImportOptions &options = {});
void startImport(GpgME::Protocol proto, const std::vector<GpgME::Key> &keys, const QString &id = QString());
......@@ -126,6 +129,11 @@ private:
void keyCacheUpdated();
void importGroups();
void setUpProgressDialog();
void increaseProgressMaximum();
void increaseProgressValue();
void setProgressToMaximum();
private:
bool waitForMoreJobs = false;
std::vector<GpgME::Protocol> nonWorkingProtocols;
......@@ -135,6 +143,10 @@ private:
std::vector<ImportedGroup> importedGroups;
std::shared_ptr<KeyCacheAutoRefreshSuspension> keyCacheAutoRefreshSuspension;
QMetaObject::Connection keyListConnection;
QString progressWindowTitle;
QString progressLabelText;
QPointer<QProgressDialog> progressDialog;
};
inline Kleo::ImportCertificatesCommand::Private *Kleo::ImportCertificatesCommand::d_func()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment