Verified Commit ef890b5c authored by Andre Heinecke's avatar Andre Heinecke
Browse files

Improve combined S/MIME and OpenPGP export

This removes the exportcertificatesdialog which required
the user to select filenames without any suggestion by opening
file dialogs for both OpenPGP and S/MIME.
Now we just query for two output files and take the PGP filename
as a name suggestion for the S/MIME filename. This is much
quicker and IMO less confusing then the other dialog which
started empty and required the user to understand what to
do next.

Additionally we save in the config which directory was choosen
for the last export so that we can reuse that directory the
next time a user exports.

GnuPG-Bug-Id: T5002
parent b440da01
Pipeline #48725 failed with stage
in 11 minutes and 54 seconds
......@@ -136,7 +136,6 @@ set(_kleopatra_SRCS
dialogs/revokecertificationdialog.cpp
dialogs/adduseriddialog.cpp
dialogs/addemaildialog.cpp
dialogs/exportcertificatesdialog.cpp
dialogs/deletecertificatesdialog.cpp
dialogs/setinitialpindialog.cpp
dialogs/certificatedetailswidget.cpp
......
......@@ -3,6 +3,7 @@
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2021 g10 Code GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -14,8 +15,6 @@
#include "command_p.h"
#include <dialogs/exportcertificatesdialog.h>
#include <utils/filedialog.h>
#include <Libkleo/Classify>
......@@ -31,12 +30,13 @@
#include <QMap>
#include <QPointer>
#include <QRegExp>
#include <QFileInfo>
#include <algorithm>
#include <vector>
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace GpgME;
using namespace QGpgME;
......@@ -163,29 +163,26 @@ void ExportCertificateCommand::doStart()
bool ExportCertificateCommand::Private::requestFileNames(GpgME::Protocol protocol)
{
if (protocol == UnknownProtocol) {
if (!fileNames[OpenPGP].isEmpty() && !fileNames[CMS].isEmpty()) {
if (!fileNames[GpgME::OpenPGP].isEmpty() && !fileNames[GpgME::CMS].isEmpty()) {
return true;
}
const QPointer<ExportCertificatesDialog> dlg(new ExportCertificatesDialog);
applyWindowID(dlg);
dlg->setOpenPgpExportFileName(fileNames[OpenPGP]);
dlg->setCmsExportFileName(fileNames[CMS]);
const bool accepted = dlg->exec() == QDialog::Accepted && dlg;
if (accepted) {
fileNames[OpenPGP] = dlg->openPgpExportFileName();
fileNames[CMS] = dlg->cmsExportFileName();
} else {
fileNames.clear();
/* Unkown protocol ask for first PGP Export file name */
if (fileNames[GpgME::OpenPGP].isEmpty() && !requestFileNames(GpgME::OpenPGP)) {
return false;
}
delete dlg;
return accepted;
/* And then for CMS */
return requestFileNames(GpgME::CMS);
}
if (!fileNames[protocol].isEmpty()) {
return true;
}
QString proposedFileName;
KConfigGroup config(KSharedConfig::openConfig(), "ExportDialog");
const auto lastDir = config.readEntry("LastDirectory", QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
QString proposedFileName = lastDir + QLatin1Char('/');
if (keys().size() == 1) {
const bool usePGPFileExt = FileOperationsPreferences().usePGPFileExt();
const auto key = keys().front();
......@@ -194,21 +191,50 @@ bool ExportCertificateCommand::Private::requestFileNames(GpgME::Protocol protoco
name = Formatting::prettyEMail(key);
}
/* Not translated so it's better to use in tutorials etc. */
proposedFileName = QStringLiteral("%1_%2_public.%3").arg(name).arg(
proposedFileName += QStringLiteral("%1_%2_public.%3").arg(name).arg(
Formatting::prettyKeyID(key.shortKeyID())).arg(
QString::fromLatin1(outputFileExtension(protocol == OpenPGP
? Class::OpenPGP | Class::Ascii | Class::Certificate
: Class::CMS | Class::Ascii | Class::Certificate, usePGPFileExt)));
}
if (protocol == GpgME::CMS) {
if (!fileNames[GpgME::OpenPGP].isEmpty()) {
/* If the user has already selected a PGP file name then use that as basis
* for a proposal for the S/MIME file. */
proposedFileName = fileNames[GpgME::OpenPGP];
proposedFileName.replace(QRegExp(QStringLiteral(".asc$")), QStringLiteral(".pem"));
proposedFileName.replace(QRegExp(QStringLiteral(".gpg$")), QStringLiteral(".der"));
proposedFileName.replace(QRegExp(QStringLiteral(".pgp$")), QStringLiteral(".der"));
}
}
const QString fname = FileDialog::getSaveFileNameEx(parentWidgetOrView(),
i18n("Export Certificates"),
if (proposedFileName.isEmpty()) {
proposedFileName = lastDir;
proposedFileName += i18nc("A generic filename for exported certificates", "certificates");
proposedFileName += protocol == GpgME::OpenPGP ? QStringLiteral(".asc") : QStringLiteral(".pem");
}
auto fname = FileDialog::getSaveFileNameEx(parentWidgetOrView(),
i18nc("1 is protocol", "Export %1 Certificates", Formatting::displayName(protocol)),
QStringLiteral("imp"),
proposedFileName,
protocol == GpgME::OpenPGP
? i18n("OpenPGP Certificates") + QLatin1String(" (*.asc *.gpg *.pgp)")
: i18n("S/MIME Certificates") + QLatin1String(" (*.pem *.der)"));
if (!fname.isEmpty() && protocol == GpgME::CMS && fileNames[GpgME::OpenPGP] == fname) {
KMessageBox::error(parentWidgetOrView(),
i18n("You have to select different filenames for different protocols."),
i18n("Export Error"));
return false;
}
const QFileInfo fi(fname);
if (fi.suffix().isEmpty()) {
fname += protocol == GpgME::OpenPGP ? QStringLiteral(".asc") : QStringLiteral(".pem");
}
fileNames[protocol] = fname;
config.writeEntry("LastDirectory", fi.absolutePath());
return !fname.isEmpty();
}
......
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/exportcertificatesdialog.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "exportcertificatesdialog.h"
#include <Libkleo/FileNameRequester>
#include <KGuiItem>
#include <KLocalizedString>
#include <QFormLayout>
#include <QLabel>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Dialogs;
class ExportCertificatesDialog::Private
{
friend class ::Kleo::Dialogs::ExportCertificatesDialog;
ExportCertificatesDialog *const q;
public:
explicit Private(ExportCertificatesDialog *qq);
~Private();
void fileNamesChanged();
private:
FileNameRequester *pgpRequester;
FileNameRequester *cmsRequester;
QPushButton *mOkButton;
};
ExportCertificatesDialog::Private::Private(ExportCertificatesDialog *qq)
: q(qq)
{
QVBoxLayout *mainLayout = new QVBoxLayout(q);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, qq);
mOkButton = buttonBox->button(QDialogButtonBox::Ok);
mOkButton->setDefault(true);
mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
connect(buttonBox, &QDialogButtonBox::accepted, q, &ExportCertificatesDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, q, &ExportCertificatesDialog::reject);
KGuiItem::assign(mOkButton, KGuiItem(i18n("Export")));
QWidget *const main = new QWidget;
mainLayout->addWidget(main);
mainLayout->addWidget(buttonBox);
QFormLayout *layout = new QFormLayout;
main->setLayout(layout);
QLabel *const pgpLabel = new QLabel;
pgpLabel->setText(i18n(" OpenPGP export file:"));
pgpRequester = new FileNameRequester;
pgpRequester->setExistingOnly(false);
connect(pgpRequester, SIGNAL(fileNameChanged(QString)), q, SLOT(fileNamesChanged()));
layout->addRow(pgpLabel, pgpRequester);
QLabel *const cmsLabel = new QLabel;
cmsLabel->setText(i18n("S/MIME export file:"));
cmsRequester = new FileNameRequester;
cmsRequester->setExistingOnly(false);
layout->addRow(cmsLabel, cmsRequester);
connect(cmsRequester, SIGNAL(fileNameChanged(QString)), q, SLOT(fileNamesChanged()));
fileNamesChanged();
}
ExportCertificatesDialog::Private::~Private() {}
ExportCertificatesDialog::ExportCertificatesDialog(QWidget *parent)
: QDialog(parent), d(new Private(this))
{
}
void ExportCertificatesDialog::Private::fileNamesChanged()
{
mOkButton->setEnabled(!pgpRequester->fileName().isEmpty() && !cmsRequester->fileName().isEmpty());
}
ExportCertificatesDialog::~ExportCertificatesDialog() {}
void ExportCertificatesDialog::setOpenPgpExportFileName(const QString &fileName)
{
d->pgpRequester->setFileName(fileName);
}
QString ExportCertificatesDialog::openPgpExportFileName() const
{
return d->pgpRequester->fileName();
}
void ExportCertificatesDialog::setCmsExportFileName(const QString &fileName)
{
d->cmsRequester->setFileName(fileName);
}
QString ExportCertificatesDialog::cmsExportFileName() const
{
return d->cmsRequester->fileName();
}
#include "moc_exportcertificatesdialog.cpp"
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/exportcertificatesdialog.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __KLEOPATRA_DIALOGS_EXPORTCERTIFICATESDIALOG_H__
#define __KLEOPATRA_DIALOGS_EXPORTCERTIFICATESDIALOG_H__
#include <QDialog>
#include <utils/pimpl_ptr.h>
class QString;
namespace Kleo
{
namespace Dialogs
{
class ExportCertificatesDialog : public QDialog
{
Q_OBJECT
public:
explicit ExportCertificatesDialog(QWidget *parent = nullptr);
~ExportCertificatesDialog();
void setOpenPgpExportFileName(const QString &fileName);
QString openPgpExportFileName() const;
void setCmsExportFileName(const QString &fileName);
QString cmsExportFileName() const;
private:
class Private;
kdtools::pimpl_ptr<Private> d;
Q_PRIVATE_SLOT(d, void fileNamesChanged())
};
}
}
#endif // __KLEOPATRA_DIALOGS_EXPORTCERTIFICATESDIALOG_H__
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