diff --git a/src/commands/adduseridcommand.cpp b/src/commands/adduseridcommand.cpp index 6e8e62e1b..b7b2555cf 100644 --- a/src/commands/adduseridcommand.cpp +++ b/src/commands/adduseridcommand.cpp @@ -1,236 +1,233 @@ /* -*- mode: c++; c-basic-offset:4 -*- commands/adduseridcommand.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "adduseridcommand.h" #include "command_p.h" #include "dialogs/adduseriddialog.h" #include #include -#include +#include #include #include #include "kleopatra_debug.h" using namespace Kleo; using namespace Kleo::Commands; using namespace GpgME; class AddUserIDCommand::Private : public Command::Private { friend class ::Kleo::Commands::AddUserIDCommand; AddUserIDCommand *q_func() const { return static_cast(q); } public: explicit Private(AddUserIDCommand *qq, KeyListController *c); ~Private() override; void init(); private: void slotDialogAccepted(); void slotDialogRejected(); void slotResult(const Error &err); private: void ensureDialogCreated(); void createJob(); void showErrorDialog(const Error &error); void showSuccessDialog(); private: GpgME::Key key; QPointer dialog; - QPointer job; + QPointer job; }; AddUserIDCommand::Private *AddUserIDCommand::d_func() { return static_cast(d.get()); } const AddUserIDCommand::Private *AddUserIDCommand::d_func() const { return static_cast(d.get()); } #define d d_func() #define q q_func() AddUserIDCommand::Private::Private(AddUserIDCommand *qq, KeyListController *c) : Command::Private(qq, c), key(), dialog(), job() { } AddUserIDCommand::Private::~Private() { qCDebug(KLEOPATRA_LOG); if (dialog) { delete dialog; } } AddUserIDCommand::AddUserIDCommand(KeyListController *c) : Command(new Private(this, c)) { d->init(); } AddUserIDCommand::AddUserIDCommand(QAbstractItemView *v, KeyListController *c) : Command(v, new Private(this, c)) { d->init(); } AddUserIDCommand::AddUserIDCommand(const GpgME::Key &key) : Command(key, new Private(this, nullptr)) { d->init(); } void AddUserIDCommand::Private::init() { } AddUserIDCommand::~AddUserIDCommand() { qCDebug(KLEOPATRA_LOG); } void AddUserIDCommand::doStart() { - const std::vector keys = d->keys(); if (keys.size() != 1 || keys.front().protocol() != GpgME::OpenPGP || !keys.front().hasSecret()) { d->finished(); return; } d->key = keys.front(); d->ensureDialogCreated(); Q_ASSERT(d->dialog); const UserID uid = d->key.userID(0); d->dialog->setName(QString::fromUtf8(uid.name())); d->dialog->setEmail(Formatting::prettyEMail(uid.email(), uid.id())); d->dialog->show(); } void AddUserIDCommand::Private::slotDialogAccepted() { Q_ASSERT(dialog); createJob(); if (!job) { finished(); + return; } - else if (const Error err = job->start(key, dialog->name(), dialog->email())) { - showErrorDialog(err); - finished(); - } + job->startAddUid(key, dialog->userID()); } void AddUserIDCommand::Private::slotDialogRejected() { Q_EMIT q->canceled(); finished(); } void AddUserIDCommand::Private::slotResult(const Error &err) { if (err.isCanceled()) ; else if (err) { showErrorDialog(err); } else { showSuccessDialog(); } finished(); } void AddUserIDCommand::doCancel() { qCDebug(KLEOPATRA_LOG); if (d->job) { d->job->slotCancel(); } } void AddUserIDCommand::Private::ensureDialogCreated() { if (dialog) { return; } dialog = new AddUserIDDialog; applyWindowID(dialog); connect(dialog, SIGNAL(accepted()), q, SLOT(slotDialogAccepted())); connect(dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected())); } void AddUserIDCommand::Private::createJob() { Q_ASSERT(!job); - const auto backend = (key.protocol() == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime(); + const auto backend = QGpgME::openpgp(); if (!backend) { return; } - QGpgME::AddUserIDJob *const j = backend->addUserIDJob(); + const auto j = backend->quickJob(); if (!j) { return; } connect(j, &QGpgME::Job::progress, q, &Command::progress); connect(j, SIGNAL(result(GpgME::Error)), q, SLOT(slotResult(GpgME::Error))); job = j; } void AddUserIDCommand::Private::showErrorDialog(const Error &err) { error(xi18nc("@info", "An error occurred while trying to add the user-id: " "%1", QString::fromLocal8Bit(err.asString())), i18nc("@title:window", "Add User-ID Error")); } void AddUserIDCommand::Private::showSuccessDialog() { information(i18nc("@info", "User-ID successfully added."), i18nc("@title:window", "Add User-ID Succeeded")); } #undef d #undef q #include "moc_adduseridcommand.cpp" diff --git a/src/dialogs/adduseriddialog.cpp b/src/dialogs/adduseriddialog.cpp index 63eec70eb..a69db08ce 100644 --- a/src/dialogs/adduseriddialog.cpp +++ b/src/dialogs/adduseriddialog.cpp @@ -1,227 +1,232 @@ /* -*- mode: c++; c-basic-offset:4 -*- dialogs/adduseriddialog.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB SPDX-FileCopyrightText: 2022 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "adduseriddialog.h" #include "view/errorlabel.h" #include "view/formtextinput.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kleopatra_debug.h" using namespace Kleo; namespace { QString buildUserId(const QString &name, const QString &email) { if (name.isEmpty()) { return email; } else if (email.isEmpty()) { return name; } else { return QStringLiteral("%1 <%2>").arg(name, email); } } } class AddUserIDDialog::Private { friend class ::Kleo::AddUserIDDialog; AddUserIDDialog *const q; struct { std::unique_ptr> nameInput; std::unique_ptr> emailInput; QLabel *resultLabel; QDialogButtonBox *buttonBox; } ui; public: explicit Private(AddUserIDDialog *qq) : q{qq} { q->setWindowTitle(i18nc("title:window", "Add User ID")); auto mainLayout = new QVBoxLayout{q}; mainLayout->addWidget(new QLabel{i18n("Enter a name and/or an email address to use for the user ID."), q}); auto gridLayout = new QGridLayout; int row = -1; const KConfigGroup config{KSharedConfig::openConfig(), "CertificateCreationWizard"}; { ui.nameInput = FormTextInput::create(q); ui.nameInput->label()->setText(i18nc("@label", "Name:")); const auto regexp = config.readEntry(QLatin1String("NAME_regex")); ui.nameInput->setValidator(regexp.isEmpty() ? Validation::pgpName(Validation::Optional, q) : Validation::pgpName(regexp, Validation::Optional, q)); const auto additionalRule = regexp.isEmpty() ? QString{} : i18n("Additionally, the name must adhere to rules set by your organization."); ui.nameInput->setToolTip(xi18n( "If a name is given, then it has to satisfy the following rules:" "" "The name must be at least 5 characters long." "The first character must not be a digit." "The name must not contain any of the following characters: <, >, @." "" "%1" "", additionalRule)); ui.nameInput->setErrorMessage(i18n("Error: The entered name is not valid.")); row++; gridLayout->addWidget(ui.nameInput->label(), row, 0, 1, 1); gridLayout->addWidget(ui.nameInput->widget(), row, 1, 1, 1); row++; gridLayout->addWidget(ui.nameInput->errorLabel(), row, 0, 1, 2); } connect(ui.nameInput->widget(), &QLineEdit::textChanged, q, [this]() { updateResultLabel(); }); { ui.emailInput = FormTextInput::create(q); ui.emailInput->label()->setText(i18nc("@label", "Email:")); const auto regexp = config.readEntry(QLatin1String("EMAIL_regex")); ui.emailInput->setValidator(regexp.isEmpty() ? Validation::email(Validation::Optional, q) : Validation::email(regexp, Validation::Optional, q)); if (regexp.isEmpty()) { ui.emailInput->setToolTip(xi18n("If an email address is given, then it has to be a valid address.")); } else { ui.emailInput->setToolTip(xi18n("If an email address is given, then it has to be a valid address " "and it must satisfy to rules set by your organization.")); } ui.emailInput->setErrorMessage(i18n("Error: The entered email address is not valid.")); row++; gridLayout->addWidget(ui.emailInput->label(), row, 0, 1, 1); gridLayout->addWidget(ui.emailInput->widget(), row, 1, 1, 1); row++; gridLayout->addWidget(ui.emailInput->errorLabel(), row, 0, 1, 2); } connect(ui.emailInput->widget(), &QLineEdit::textChanged, q, [this]() { updateResultLabel(); }); mainLayout->addLayout(gridLayout); mainLayout->addWidget(new KSeparator{Qt::Horizontal, q}); { auto label = new QLabel{i18n("This is how the new user ID will be stored in the certificate:"), q}; mainLayout->addWidget(label); } { ui.resultLabel = new QLabel{q}; ui.resultLabel->setMinimumSize(300, 0); ui.resultLabel->setAlignment(Qt::AlignCenter); ui.resultLabel->setTextFormat(Qt::PlainText); QFont font; font.setBold(true); font.setWeight(75); ui.resultLabel->setFont(font); mainLayout->addWidget(ui.resultLabel); } mainLayout->addWidget(new KSeparator{Qt::Horizontal, q}); mainLayout->addStretch(1); ui.buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok | QDialogButtonBox::Cancel, q}; mainLayout->addWidget(ui.buttonBox); connect(ui.buttonBox, &QDialogButtonBox::accepted, q, [this]() { checkAccept(); }); connect(ui.buttonBox, &QDialogButtonBox::rejected, q, &QDialog::reject); updateResultLabel(); } QString name() const { return ui.nameInput->widget()->text().trimmed(); } QString email() const { return ui.emailInput->widget()->text().trimmed(); } private: void checkAccept() { QStringList errors; if (ui.resultLabel->text().isEmpty()) { errors.push_back(i18n("Name and email address cannot both be empty.")); } if (!ui.nameInput->hasAcceptableInput()) { errors.push_back(i18n("The entered name is not valid.")); } if (!ui.emailInput->hasAcceptableInput()) { errors.push_back(i18n("The entered email address is not valid.")); } if (errors.size() > 1) { KMessageBox::errorList(q, i18n("Sorry, the entered data is not acceptable."), errors); } else if (!errors.empty()) { KMessageBox::sorry(q, errors.first()); } else { q->accept(); } } void updateResultLabel() { ui.resultLabel->setText(buildUserId(name(), email())); } }; AddUserIDDialog::AddUserIDDialog(QWidget *parent, Qt::WindowFlags f) : QDialog{parent, f} , d(new Private{this}) { } AddUserIDDialog::~AddUserIDDialog() = default; void AddUserIDDialog::setName(const QString &name) { d->ui.nameInput->widget()->setText(name); } QString AddUserIDDialog::name() const { return d->name(); } void AddUserIDDialog::setEmail(const QString &email) { d->ui.emailInput->widget()->setText(email); } QString AddUserIDDialog::email() const { return d->email(); } + +QString AddUserIDDialog::userID() const +{ + return d->ui.resultLabel->text(); +} diff --git a/src/dialogs/adduseriddialog.h b/src/dialogs/adduseriddialog.h index 92778e4f2..d4645118e 100644 --- a/src/dialogs/adduseriddialog.h +++ b/src/dialogs/adduseriddialog.h @@ -1,39 +1,44 @@ /* -*- mode: c++; c-basic-offset:4 -*- dialogs/adduseriddialog.h This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB SPDX-FileCopyrightText: 2022 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include #include namespace Kleo { class AddUserIDDialog : public QDialog { Q_OBJECT public: explicit AddUserIDDialog(QWidget *parent = nullptr, Qt::WindowFlags f = {}); ~AddUserIDDialog() override; void setName(const QString &name); QString name() const; void setEmail(const QString &email); QString email() const; + /** + * Returns the user ID built from the entered name and/or email address. + */ + QString userID() const; + private: class Private; const std::unique_ptr d; }; } // namespace Kleo