diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 79cbf8bf0..9e463c2de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,332 +1,333 @@ add_subdirectory(icons) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) if (NOT DISABLE_KWATCHGNUPG) add_subdirectory(kwatchgnupg) endif() add_subdirectory(libkleopatraclient) add_subdirectory(conf) add_subdirectory(kconf_update) if(WIN32) set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_win.cpp) set(_kleopatra_extra_SRCS utils/gnupg-registry.c selftest/registrycheck.cpp utils/windowsprocessdevice.cpp ) else() set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_unix.cpp) set(_kleopatra_extra_SRCS) endif() set(_kleopatra_uiserver_SRCS uiserver/sessiondata.cpp uiserver/uiserver.cpp ${_kleopatra_extra_uiserver_SRCS} uiserver/assuanserverconnection.cpp uiserver/echocommand.cpp uiserver/decryptverifycommandemailbase.cpp uiserver/decryptverifycommandfilesbase.cpp uiserver/signcommand.cpp uiserver/signencryptfilescommand.cpp uiserver/prepencryptcommand.cpp uiserver/prepsigncommand.cpp uiserver/encryptcommand.cpp uiserver/selectcertificatecommand.cpp uiserver/importfilescommand.cpp uiserver/createchecksumscommand.cpp uiserver/verifychecksumscommand.cpp selftest/uiservercheck.cpp ) if(ASSUAN2_FOUND) include_directories(${ASSUAN2_INCLUDES}) set(_kleopatra_uiserver_extra_libs ${ASSUAN2_LIBRARIES}) else() include_directories(${ASSUAN_INCLUDES}) if(WIN32) set(_kleopatra_uiserver_extra_libs ${ASSUAN_VANILLA_LIBRARIES}) else() set(_kleopatra_uiserver_extra_libs ${ASSUAN_PTHREAD_LIBRARIES}) endif() endif() if(HAVE_GPG_ERR_SOURCE_KLEO) add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO) else() add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1) endif() ki18n_wrap_ui(_kleopatra_uiserver_SRCS crypto/gui/signingcertificateselectionwidget.ui) set(_kleopatra_SRCS utils/gnupg-helper.cpp utils/gui-helper.cpp utils/filedialog.cpp utils/kdpipeiodevice.cpp utils/headerview.cpp utils/scrollarea.cpp utils/dragqueen.cpp utils/multivalidator.cpp utils/systemtrayicon.cpp utils/hex.cpp utils/path-helper.cpp utils/input.cpp utils/output.cpp utils/validation.cpp utils/wsastarter.cpp utils/iodevicelogger.cpp utils/log.cpp utils/action_data.cpp utils/types.cpp utils/archivedefinition.cpp utils/auditlog.cpp utils/clipboardmenu.cpp utils/kuniqueservice.cpp selftest/selftest.cpp selftest/enginecheck.cpp selftest/gpgconfcheck.cpp selftest/gpgagentcheck.cpp selftest/libkleopatrarccheck.cpp ${_kleopatra_extra_SRCS} view/keylistcontroller.cpp view/keytreeview.cpp view/searchbar.cpp view/smartcardwidget.cpp view/padwidget.cpp view/pgpcardwidget.cpp view/netkeywidget.cpp view/nullpinwidget.cpp view/tabwidget.cpp view/keycacheoverlay.cpp view/waitwidget.cpp view/welcomewidget.cpp dialogs/certificateselectiondialog.cpp dialogs/expirydialog.cpp dialogs/lookupcertificatesdialog.cpp dialogs/ownertrustdialog.cpp dialogs/selftestdialog.cpp dialogs/certifycertificatedialog.cpp dialogs/adduseriddialog.cpp + dialogs/addemaildialog.cpp dialogs/exportcertificatesdialog.cpp dialogs/deletecertificatesdialog.cpp dialogs/setinitialpindialog.cpp dialogs/certificatedetailswidget.cpp dialogs/trustchainwidget.cpp dialogs/weboftrustwidget.cpp dialogs/weboftrustdialog.cpp dialogs/exportdialog.cpp dialogs/subkeyswidget.cpp dialogs/gencardkeydialog.cpp dialogs/updatenotification.cpp crypto/controller.cpp crypto/certificateresolver.cpp crypto/sender.cpp crypto/recipient.cpp crypto/task.cpp crypto/taskcollection.cpp crypto/decryptverifytask.cpp crypto/decryptverifyemailcontroller.cpp crypto/decryptverifyfilescontroller.cpp crypto/autodecryptverifyfilescontroller.cpp crypto/encryptemailtask.cpp crypto/encryptemailcontroller.cpp crypto/newsignencryptemailcontroller.cpp crypto/signencrypttask.cpp crypto/signencryptfilescontroller.cpp crypto/signemailtask.cpp crypto/signemailcontroller.cpp crypto/createchecksumscontroller.cpp crypto/verifychecksumscontroller.cpp crypto/gui/wizard.cpp crypto/gui/wizardpage.cpp crypto/gui/certificateselectionline.cpp crypto/gui/certificatelineedit.cpp crypto/gui/signingcertificateselectionwidget.cpp crypto/gui/signingcertificateselectiondialog.cpp crypto/gui/resultitemwidget.cpp crypto/gui/resultlistwidget.cpp crypto/gui/resultpage.cpp crypto/gui/newresultpage.cpp crypto/gui/signencryptfileswizard.cpp crypto/gui/signencryptemailconflictdialog.cpp crypto/gui/decryptverifyoperationwidget.cpp crypto/gui/decryptverifyfileswizard.cpp crypto/gui/decryptverifyfilesdialog.cpp crypto/gui/objectspage.cpp crypto/gui/resolverecipientspage.cpp crypto/gui/signerresolvepage.cpp crypto/gui/encryptemailwizard.cpp crypto/gui/signemailwizard.cpp crypto/gui/signencryptwidget.cpp crypto/gui/signencryptwizard.cpp crypto/gui/unknownrecipientwidget.cpp crypto/gui/verifychecksumsdialog.cpp commands/command.cpp commands/gnupgprocesscommand.cpp commands/detailscommand.cpp commands/exportcertificatecommand.cpp commands/importcertificatescommand.cpp commands/importcertificatefromfilecommand.cpp commands/importcertificatefromclipboardcommand.cpp commands/importcertificatefromdatacommand.cpp commands/lookupcertificatescommand.cpp commands/reloadkeyscommand.cpp commands/refreshx509certscommand.cpp commands/refreshopenpgpcertscommand.cpp commands/deletecertificatescommand.cpp commands/decryptverifyfilescommand.cpp commands/signencryptfilescommand.cpp commands/signencryptfoldercommand.cpp commands/encryptclipboardcommand.cpp commands/signclipboardcommand.cpp commands/decryptverifyclipboardcommand.cpp commands/clearcrlcachecommand.cpp commands/dumpcrlcachecommand.cpp commands/dumpcertificatecommand.cpp commands/importcrlcommand.cpp commands/changeexpirycommand.cpp commands/changeownertrustcommand.cpp commands/changeroottrustcommand.cpp commands/changepassphrasecommand.cpp commands/certifycertificatecommand.cpp commands/selftestcommand.cpp commands/exportsecretkeycommand.cpp commands/exportopenpgpcertstoservercommand.cpp commands/adduseridcommand.cpp commands/newcertificatecommand.cpp commands/setinitialpincommand.cpp commands/learncardkeyscommand.cpp commands/checksumcreatefilescommand.cpp commands/checksumverifyfilescommand.cpp commands/exportpaperkeycommand.cpp commands/importpaperkeycommand.cpp commands/genrevokecommand.cpp commands/keytocardcommand.cpp ${_kleopatra_uiserver_files} conf/configuredialog.cpp newcertificatewizard/listwidget.cpp newcertificatewizard/newcertificatewizard.cpp smartcard/readerstatus.cpp smartcard/card.cpp smartcard/openpgpcard.cpp smartcard/netkeycard.cpp aboutdata.cpp systrayicon.cpp kleopatraapplication.cpp mainwindow.cpp main.cpp ) if(WIN32) configure_file (versioninfo.rc.in versioninfo.rc) set(_kleopatra_SRCS ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc ${_kleopatra_SRCS}) endif() if(HAVE_KCMUTILS) set (_kleopatra_extra_libs KF5::KCMUtils) else() set (_kleopatra_SRCS conf/kleopageconfigdialog.cpp ${_kleopatra_SRCS}) endif() ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME org.kde.pim.kleopatra) if(KLEO_MODEL_TEST) add_definitions(-DKLEO_MODEL_TEST) set(_kleopatra_SRCS ${_kleopatra_SRCS} models/modeltest.cpp) endif() ki18n_wrap_ui(_kleopatra_SRCS dialogs/certificationoptionswidget.ui dialogs/expirydialog.ui dialogs/lookupcertificatesdialog.ui dialogs/ownertrustdialog.ui dialogs/selectchecklevelwidget.ui dialogs/selftestdialog.ui dialogs/adduseriddialog.ui dialogs/setinitialpindialog.ui dialogs/certificatedetailswidget.ui dialogs/trustchainwidget.ui dialogs/subkeyswidget.ui newcertificatewizard/listwidget.ui newcertificatewizard/chooseprotocolpage.ui newcertificatewizard/enterdetailspage.ui newcertificatewizard/overviewpage.ui newcertificatewizard/keycreationpage.ui newcertificatewizard/resultpage.ui newcertificatewizard/advancedsettingsdialog.ui ) kconfig_add_kcfg_files(_kleopatra_SRCS kcfg/tooltippreferences.kcfgc kcfg/emailoperationspreferences.kcfgc kcfg/fileoperationspreferences.kcfgc kcfg/smimevalidationpreferences.kcfgc ) file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-kleopatra.png") ecm_add_app_icon(_kleopatra_SRCS ICONS ${ICONS_SRCS}) qt5_add_resources(_kleopatra_SRCS kleopatra.qrc) add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_uiserver_SRCS}) set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra) target_link_libraries(kleopatra_bin Gpgmepp QGpgme ${_kleopatra_extra_libs} KF5::Libkleo KF5::Mime KF5::I18n KF5::XmlGui KF5::IconThemes KF5::WindowSystem KF5::CoreAddons KF5::ItemModels KF5::Crash Qt5::Network Qt5::PrintSupport # Printing secret keys ${_kleopatra_uiserver_extra_libs} ${_kleopatra_dbusaddons_libs} kleopatraclientcore ) install(TARGETS kleopatra_bin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install( PROGRAMS data/org.kde.kleopatra.desktop data/kleopatra_import.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) install(FILES data/org.kde.kleopatra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install( FILES data/kleopatra_signencryptfiles.desktop data/kleopatra_signencryptfolders.desktop data/kleopatra_decryptverifyfiles.desktop data/kleopatra_decryptverifyfolders.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) diff --git a/src/commands/adduseridcommand.cpp b/src/commands/adduseridcommand.cpp index a4c53a0b3..212bba6ab 100644 --- a/src/commands/adduseridcommand.cpp +++ b/src/commands/adduseridcommand.cpp @@ -1,260 +1,295 @@ /* -*- mode: c++; c-basic-offset:4 -*- commands/adduseridcommand.cpp This file is part of Kleopatra, the KDE keymanager Copyright (c) 2008 Klarälvdalens Datakonsult AB Kleopatra 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. Kleopatra 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 the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include #include "adduseridcommand.h" #include "command_p.h" -#include +#include "dialogs/adduseriddialog.h" +#include "dialogs/addemaildialog.h" #include #include #include #include #include #include "kleopatra_debug.h" using namespace Kleo; using namespace Kleo::Commands; using namespace Kleo::Dialogs; 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(); void init(); private: void slotDialogAccepted(); + void slotSimpleDialogAccepted(); 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 simpleDialog; 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; + } + if (simpleDialog) { + delete simpleDialog; + } } 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->simpleDialog->setEmail(Formatting::prettyEMail(uid.email(), uid.id())); + d->dialog->setName(QString::fromUtf8(uid.name())); d->dialog->setEmail(Formatting::prettyEMail(uid.email(), uid.id())); d->dialog->setComment(QString::fromUtf8(uid.comment())); - d->dialog->show(); + d->simpleDialog->show(); +} + +void AddUserIDCommand::Private::slotSimpleDialogAccepted() +{ + if (simpleDialog->advancedSelected()) { + qDebug() << "thinking advanced selected"; + dialog->show(); + return; + } + + createJob(); + if (!job) { + finished(); + return; + } + if (const Error err = job->start(key, QString(), simpleDialog->email(), QString())) { + showErrorDialog(err); + finished(); + } } void AddUserIDCommand::Private::slotDialogAccepted() { Q_ASSERT(dialog); createJob(); if (!job) { finished(); } else if (const Error err = job->start(key, dialog->name(), dialog->email(), dialog->comment())) { showErrorDialog(err); finished(); } } 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); - dialog->setAttribute(Qt::WA_DeleteOnClose); connect(dialog, SIGNAL(accepted()), q, SLOT(slotDialogAccepted())); connect(dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected())); + + simpleDialog = new AddEmailDialog; + applyWindowID(simpleDialog); + + connect(simpleDialog, SIGNAL(accepted()), q, SLOT(slotSimpleDialogAccepted())); + connect(simpleDialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected())); } void AddUserIDCommand::Private::createJob() { Q_ASSERT(!job); const auto backend = (key.protocol() == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime(); if (!backend) { return; } QGpgME::AddUserIDJob *const j = backend->addUserIDJob(); 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/commands/adduseridcommand.h b/src/commands/adduseridcommand.h index 13506b311..78cdae3bb 100644 --- a/src/commands/adduseridcommand.h +++ b/src/commands/adduseridcommand.h @@ -1,82 +1,83 @@ /* -*- mode: c++; c-basic-offset:4 -*- commands/adduseridcommand.h This file is part of Kleopatra, the KDE keymanager Copyright (c) 2008 Klarälvdalens Datakonsult AB Kleopatra 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. Kleopatra 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 the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__ #define __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__ #include namespace Kleo { namespace Commands { class AddUserIDCommand : public Command { Q_OBJECT public: explicit AddUserIDCommand(QAbstractItemView *view, KeyListController *parent); explicit AddUserIDCommand(KeyListController *parent); explicit AddUserIDCommand(const GpgME::Key &key); ~AddUserIDCommand() override; /* reimp */ static Restrictions restrictions() { return OnlyOneKey | MustBeOpenPGP | NeedSecretKey; } void setName(const QString &name); const QString &name() const; void setEmail(const QString &email); const QString &email() const; void setComment(const QString &comment); const QString &comment() const; private: void doStart() override; void doCancel() override; private: class Private; inline Private *d_func(); inline const Private *d_func() const; Q_PRIVATE_SLOT(d_func(), void slotResult(GpgME::Error)) Q_PRIVATE_SLOT(d_func(), void slotDialogAccepted()) Q_PRIVATE_SLOT(d_func(), void slotDialogRejected()) + Q_PRIVATE_SLOT(d_func(), void slotSimpleDialogAccepted()) }; } } #endif // __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__ diff --git a/src/dialogs/addemaildialog.cpp b/src/dialogs/addemaildialog.cpp new file mode 100644 index 000000000..bc6822272 --- /dev/null +++ b/src/dialogs/addemaildialog.cpp @@ -0,0 +1,130 @@ +/* -*- mode: c++; c-basic-offset:4 -*- + dialogs/addemaildialog.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2019 g10 Code GmbH + + Kleopatra 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. + + Kleopatra 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 the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include + +#include "addemaildialog.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "kleopatra_debug.h" + +using namespace Kleo; +using namespace Kleo::Dialogs; + +class AddEmailDialog::Private +{ +public: + Private(AddEmailDialog *qq): + q(qq), + mAdvancedSelected(false) + { + auto mainLay = new QVBoxLayout(q); + + auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = btnBox->button(QDialogButtonBox::Ok); + QObject::connect (btnBox, &QDialogButtonBox::accepted, q, [this] () { + q->accept(); + }); + QObject::connect (btnBox, &QDialogButtonBox::rejected, q, &QDialog::reject); + + btnBox->addButton(i18n("Advanced"), QDialogButtonBox::HelpRole); + QObject::connect (btnBox, &QDialogButtonBox::helpRequested, q, [this] () { + mAdvancedSelected = true; + q->accept(); + }); + + + mainLay->addStretch(-1); + + auto emailLay = new QHBoxLayout; + auto emailLbl = new QLabel(i18n("EMail") + QLatin1Char(':')); + mEmailEdit = new QLineEdit; + mEmailEdit->setValidator(Validation::email()); + + connect(mEmailEdit, &QLineEdit::textChanged, q, [this] () { + mOkButton->setEnabled(!mEmailEdit->text().isEmpty() && mEmailEdit->hasAcceptableInput()); + }); + + emailLbl->setBuddy(mEmailEdit); + + emailLay->addWidget(emailLbl); + emailLay->addWidget(mEmailEdit); + + mainLay->addLayout(emailLay); + mainLay->addWidget(btnBox); + mOkButton->setEnabled(!mEmailEdit->text().isEmpty() && mEmailEdit->hasAcceptableInput()); + } + + AddEmailDialog *q; + QPushButton *mOkButton; + QLineEdit *mEmailEdit; + bool mAdvancedSelected; +}; + +AddEmailDialog::AddEmailDialog(QWidget *parent): + QDialog(parent), + d(new Private(this)) +{ + setWindowTitle(i18n("Add New EMail")); +} + +AddEmailDialog::~AddEmailDialog() +{ +} + +void AddEmailDialog::setEmail(const QString &email) +{ + return d->mEmailEdit->setText(email); +} + +QString AddEmailDialog::email() const +{ + return d->mEmailEdit->text().trimmed(); +} + +bool AddEmailDialog::advancedSelected() +{ + return d->mAdvancedSelected; +} diff --git a/src/commands/adduseridcommand.h b/src/dialogs/addemaildialog.h similarity index 57% copy from src/commands/adduseridcommand.h copy to src/dialogs/addemaildialog.h index 13506b311..258767046 100644 --- a/src/commands/adduseridcommand.h +++ b/src/dialogs/addemaildialog.h @@ -1,82 +1,65 @@ /* -*- mode: c++; c-basic-offset:4 -*- - commands/adduseridcommand.h + dialogs/addemaildialog.h This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2008 Klarälvdalens Datakonsult AB + Copyright (c) 2019 g10 Code GmbH Kleopatra 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. Kleopatra 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 the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__ -#define __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__ +#ifndef __KLEOPATRA_DIALOGS_ADDEMAILDIALOG_H__ +#define __KLEOPATRA_DIALOGS_ADDEMAILDIALOG_H__ -#include +#include + +#include + +class QString; namespace Kleo { -namespace Commands +namespace Dialogs { -class AddUserIDCommand : public Command +class AddEmailDialog : public QDialog { Q_OBJECT public: - explicit AddUserIDCommand(QAbstractItemView *view, KeyListController *parent); - explicit AddUserIDCommand(KeyListController *parent); - explicit AddUserIDCommand(const GpgME::Key &key); - ~AddUserIDCommand() override; - - /* reimp */ static Restrictions restrictions() - { - return OnlyOneKey | MustBeOpenPGP | NeedSecretKey; - } - - void setName(const QString &name); - const QString &name() const; + explicit AddEmailDialog(QWidget *parent = nullptr); + ~AddEmailDialog(); void setEmail(const QString &email); - const QString &email() const; - - void setComment(const QString &comment); - const QString &comment() const; - -private: - void doStart() override; - void doCancel() override; + QString email() const; + bool advancedSelected(); private: class Private; - inline Private *d_func(); - inline const Private *d_func() const; - Q_PRIVATE_SLOT(d_func(), void slotResult(GpgME::Error)) - Q_PRIVATE_SLOT(d_func(), void slotDialogAccepted()) - Q_PRIVATE_SLOT(d_func(), void slotDialogRejected()) + std::shared_ptr d; }; } } - -#endif // __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__ +#endif diff --git a/src/dialogs/adduseriddialog.cpp b/src/dialogs/adduseriddialog.cpp index 17da3020c..b7767a9b1 100644 --- a/src/dialogs/adduseriddialog.cpp +++ b/src/dialogs/adduseriddialog.cpp @@ -1,357 +1,359 @@ /* -*- mode: c++; c-basic-offset:4 -*- dialogs/adduseriddialog.cpp This file is part of Kleopatra, the KDE keymanager Copyright (c) 2008 Klarälvdalens Datakonsult AB Kleopatra 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. Kleopatra 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 the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include #include "adduseriddialog.h" #include "ui_adduseriddialog.h" #include #include #include #include #include #include #include #include #include "kleopatra_debug.h" #include using namespace Kleo; using namespace Kleo::Dialogs; namespace { struct Line { QString attr; QString label; QString regex; QLineEdit *edit; }; } static QString pgpLabel(const QString &attr) { if (attr == QLatin1String("NAME")) { return i18n("Name"); } else if (attr == QLatin1String("COMMENT")) { return i18n("Comment"); } else if (attr == QLatin1String("EMAIL")) { return i18n("EMail"); } return QString(); } static QString attributeLabel(const QString &attr, bool pgp) { if (attr.isEmpty()) { return QString(); } const QString label = /*pgp ?*/ pgpLabel(attr) /*: Kleo::DNAttributeMapper::instance()->name2label( attr )*/; if (!label.isEmpty()) if (pgp) { return label; } else return i18nc("Format string for the labels in the \"Your Personal Data\" page", "%1 (%2)", label, attr); else { return attr; } } static QString attributeFromKey(QString key) { return key.remove(QLatin1Char('!')); } static int row_index_of(QWidget *w, QGridLayout *l) { const int idx = l->indexOf(w); int r, c, rs, cs; l->getItemPosition(idx, &r, &c, &rs, &cs); return r; } static QLineEdit *adjust_row(QGridLayout *l, int row, const QString &label, const QString &preset, QValidator *validator, bool readonly, bool required) { Q_ASSERT(l); Q_ASSERT(row >= 0); Q_ASSERT(row < l->rowCount()); QLabel *lb = qobject_cast(l->itemAtPosition(row, 0)->widget()); Q_ASSERT(lb); QLineEdit *le = qobject_cast(l->itemAtPosition(row, 1)->widget()); Q_ASSERT(le); QLabel *reqLB = qobject_cast(l->itemAtPosition(row, 2)->widget()); Q_ASSERT(reqLB); lb->setText(i18nc("interpunctation for labels", "%1:", label)); le->setText(preset); reqLB->setText(required ? i18n("(required)") : i18n("(optional)")); delete le->validator(); if (validator) { if (!validator->parent()) { validator->setParent(le); } le->setValidator(validator); } le->setReadOnly(readonly && le->hasAcceptableInput()); lb->show(); le->show(); reqLB->show(); return le; } class AddUserIDDialog::Private { friend class ::Kleo::Dialogs::AddUserIDDialog; AddUserIDDialog *const q; public: explicit Private(AddUserIDDialog *qq) : q(qq), ui(q) { } private: void slotUserIDChanged(); private: bool isComplete() const; private: struct UI : public Ui_AddUserIDDialog { QVector lineList; explicit UI(AddUserIDDialog *qq) : Ui_AddUserIDDialog() { setupUi(qq); // ### this code is mostly the same as the one in // ### newcertificatewizard. Find some time to factor them // ### into a single copy. // hide the stuff nameLB->hide(); nameLE->hide(); nameRequiredLB->hide(); emailLB->hide(); emailLE->hide(); emailRequiredLB->hide(); commentLB->hide(); commentLE->hide(); commentRequiredLB->hide(); // set errorLB to have a fixed height of two lines: errorLB->setText(QStringLiteral("2
1")); errorLB->setFixedHeight(errorLB->minimumSizeHint().height()); errorLB->clear(); const KConfigGroup config(KSharedConfig::openConfig(), "CertificateCreationWizard"); const QStringList attrOrder = config.readEntry("OpenPGPAttributeOrder", - QStringList() << QStringLiteral("NAME!") << QStringLiteral("EMAIL!") << QStringLiteral("COMMENT")); + QStringList() << QStringLiteral("NAME") << QStringLiteral("EMAIL") << QStringLiteral("COMMENT")); QMap lines; for (const QString &rawKey : attrOrder) { const QString key = rawKey.trimmed().toUpper(); const QString attr = attributeFromKey(key); if (attr.isEmpty()) { continue; } const QString preset = config.readEntry(attr); const bool required = key.endsWith(QLatin1Char('!')); const bool readonly = config.isEntryImmutable(attr); const QString label = config.readEntry(attr + QLatin1String("_label"), attributeLabel(attr, true)); const QString regex = config.readEntry(attr + QLatin1String("_regex")); int row; QValidator *validator = nullptr; if (attr == QLatin1String("EMAIL")) { validator = regex.isEmpty() ? Validation::email() : Validation::email(QRegExp(regex)); row = row_index_of(emailLE, gridLayout); } else if (attr == QLatin1String("NAME")) { validator = regex.isEmpty() ? Validation::pgpName() : Validation::pgpName(QRegExp(regex)); row = row_index_of(nameLE, gridLayout); } else if (attr == QLatin1String("COMMENT")) { validator = regex.isEmpty() ? Validation::pgpComment() : Validation::pgpComment(QRegExp(regex)); row = row_index_of(commentLE, gridLayout); } else { continue; } QLineEdit *le = adjust_row(gridLayout, row, label, preset, validator, readonly, required); const Line line = { key, label, regex, le }; lines[row] = line; } std::copy(lines.begin(), lines.end(), std::back_inserter(lineList)); } QPushButton *okPB() const { return buttonBox->button(QDialogButtonBox::Ok); } } ui; }; AddUserIDDialog::AddUserIDDialog(QWidget *p) : QDialog(p), d(new Private(this)) { } AddUserIDDialog::~AddUserIDDialog() {} void AddUserIDDialog::setName(const QString &name) { d->ui.nameLE->setText(name); } QString AddUserIDDialog::name() const { return d->ui.nameLE->text().trimmed(); } void AddUserIDDialog::setEmail(const QString &email) { d->ui.emailLE->setText(email); } QString AddUserIDDialog::email() const { return d->ui.emailLE->text().trimmed(); } void AddUserIDDialog::setComment(const QString &comment) { d->ui.commentLE->setText(comment); } QString AddUserIDDialog::comment() const { return d->ui.commentLE->text().trimmed(); } static bool has_intermediate_input(const QLineEdit *le) { QString text = le->text(); int pos = le->cursorPosition(); const QValidator *const v = le->validator(); return !v || v->validate(text, pos) == QValidator::Intermediate; } static bool requirementsAreMet(const QVector &list, QString &error) { + bool allEmpty = true; for (const Line &line : list) { const QLineEdit *le = line.edit; if (!le) { continue; } const QString key = line.attr; qCDebug(KLEOPATRA_LOG) << "requirementsAreMet(): checking \"" << key << "\" against \"" << le->text() << "\":"; if (le->text().trimmed().isEmpty()) { if (key.endsWith(QLatin1Char('!'))) { if (line.regex.isEmpty()) { error = xi18nc("@info", "%1 is required, but empty.", line.label); } else error = xi18nc("@info", "%1 is required, but empty." "Local Admin rule: %2", line.label, line.regex); return false; } } else if (has_intermediate_input(le)) { if (line.regex.isEmpty()) { error = xi18nc("@info", "%1 is incomplete.", line.label); } else error = xi18nc("@info", "%1 is incomplete." "Local Admin rule: %2", line.label, line.regex); return false; } else if (!le->hasAcceptableInput()) { if (line.regex.isEmpty()) { error = xi18nc("@info", "%1 is invalid.", line.label); } else error = xi18nc("@info", "%1 is invalid." "Local Admin rule: %2", line.label, line.regex); return false; + } else { + allEmpty = false; } - qCDebug(KLEOPATRA_LOG) << "ok"; } - return true; + return !allEmpty; } bool AddUserIDDialog::Private::isComplete() const { QString error; const bool ok = requirementsAreMet(ui.lineList, error); ui.errorLB->setText(error); return ok; } void AddUserIDDialog::Private::slotUserIDChanged() { ui.okPB()->setEnabled(isComplete()); const QString name = q->name(); const QString email = q->email(); const QString comment = q->comment(); QStringList parts; if (!name.isEmpty()) { parts.push_back(name); } if (!comment.isEmpty()) { parts.push_back(QLatin1Char('(') + comment + QLatin1Char(')')); } if (!email.isEmpty()) { parts.push_back(QLatin1Char('<') + email + QLatin1Char('>')); } ui.resultLB->setText(parts.join(QLatin1Char(' '))); } #include "moc_adduseriddialog.cpp"