File indexing completed on 2024-06-16 04:56:18
0001 /* view/welcomewidget.cpp 0002 0003 This file is part of Kleopatra, the KDE keymanager 0004 SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik 0005 SPDX-FileContributor: Intevation GmbH 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "welcomewidget.h" 0013 0014 #include "htmllabel.h" 0015 0016 #include <KAboutData> 0017 0018 #include <QAction> 0019 #include <QHBoxLayout> 0020 #include <QKeyEvent> 0021 #include <QToolButton> 0022 #include <QVBoxLayout> 0023 0024 #include "commands/importcertificatefromfilecommand.h" 0025 #include "commands/newopenpgpcertificatecommand.h" 0026 0027 #include <KConfigGroup> 0028 #include <KLocalizedString> 0029 #include <KSharedConfig> 0030 0031 static const QString templ = QStringLiteral( 0032 "<h3>%1</h3>" // Welcome 0033 "<p>%2<p/><p>%3</p>" // Intro + Explanation 0034 "<ul><li>%4</li><li>%5</li></ul>" // 0035 "<p>%6</p>" // More info 0036 ""); 0037 0038 using namespace Kleo; 0039 0040 namespace 0041 { 0042 /** 0043 * A tool button that can be activated with the Enter and Return keys additionally to the Space key. 0044 */ 0045 class ToolButton : public QToolButton 0046 { 0047 Q_OBJECT 0048 public: 0049 using QToolButton::QToolButton; 0050 0051 protected: 0052 void keyPressEvent(QKeyEvent *e) override 0053 { 0054 switch (e->key()) { 0055 case Qt::Key_Enter: 0056 case Qt::Key_Return: { 0057 // forward as key press of Key_Select to QToolButton 0058 QKeyEvent alternateEvent{e->type(), 0059 Qt::Key_Select, 0060 e->modifiers(), 0061 e->nativeScanCode(), 0062 e->nativeVirtualKey(), 0063 e->nativeModifiers(), 0064 e->text(), 0065 e->isAutoRepeat(), 0066 static_cast<ushort>(e->count())}; 0067 QToolButton::keyPressEvent(&alternateEvent); 0068 if (!alternateEvent.isAccepted()) { 0069 e->ignore(); 0070 } 0071 break; 0072 } 0073 default: 0074 QToolButton::keyPressEvent(e); 0075 } 0076 } 0077 0078 void keyReleaseEvent(QKeyEvent *e) override 0079 { 0080 switch (e->key()) { 0081 case Qt::Key_Enter: 0082 case Qt::Key_Return: { 0083 // forward as key release of Key_Select to QToolButton 0084 QKeyEvent alternateEvent{e->type(), 0085 Qt::Key_Select, 0086 e->modifiers(), 0087 e->nativeScanCode(), 0088 e->nativeVirtualKey(), 0089 e->nativeModifiers(), 0090 e->text(), 0091 e->isAutoRepeat(), 0092 static_cast<ushort>(e->count())}; 0093 QToolButton::keyReleaseEvent(&alternateEvent); 0094 if (!alternateEvent.isAccepted()) { 0095 e->ignore(); 0096 } 0097 break; 0098 } 0099 default: 0100 QToolButton::keyReleaseEvent(e); 0101 } 0102 } 0103 }; 0104 } 0105 0106 class WelcomeWidget::Private 0107 { 0108 public: 0109 Private(WelcomeWidget *qq) 0110 : q(qq) 0111 { 0112 auto vLay = new QVBoxLayout(q); 0113 auto hLay = new QHBoxLayout; 0114 0115 const QString welcome = i18nc("%1 is version", "Welcome to Kleopatra %1", KAboutData::applicationData().version()); 0116 const QString introduction = i18n("Kleopatra is a front-end for the crypto software <a href=\"https://gnupg.org\">GnuPG</a>."); 0117 0118 const QString keyExplanation = i18n("For most actions you need either a public key (certificate) or your own private key."); 0119 0120 const QString privateKeyExplanation = i18n("The private key is needed to decrypt or sign."); 0121 const QString publicKeyExplanation = i18n("The public key can be used by others to verify your identity or encrypt to you."); 0122 0123 const QString wikiUrl = i18nc("More info about public key cryptography, please link to your local version of Wikipedia", 0124 "https://en.wikipedia.org/wiki/Public-key_cryptography"); 0125 const QString learnMore = i18nc("%1 is link a wiki article", "You can learn more about this on <a href=\"%1\">Wikipedia</a>.", wikiUrl); 0126 0127 const auto labelText = templ.arg(welcome).arg(introduction).arg(keyExplanation).arg(privateKeyExplanation).arg(publicKeyExplanation).arg(learnMore); 0128 mLabel = new HtmlLabel{labelText, q}; 0129 mLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); 0130 mLabel->setOpenExternalLinks(true); 0131 0132 auto genKeyAction = new QAction(q); 0133 genKeyAction->setText(i18n("New Key Pair...")); 0134 genKeyAction->setIcon(QIcon::fromTheme(QStringLiteral("view-certificate-add"))); 0135 0136 auto importAction = new QAction(q); 0137 importAction->setText(i18n("Import...")); 0138 importAction->setIcon(QIcon::fromTheme(QStringLiteral("view-certificate-import"))); 0139 0140 connect(importAction, &QAction::triggered, q, [this]() { 0141 import(); 0142 }); 0143 connect(genKeyAction, &QAction::triggered, q, [this]() { 0144 generate(); 0145 }); 0146 0147 mGenerateBtn = new ToolButton{q}; 0148 mGenerateBtn->setDefaultAction(genKeyAction); 0149 mGenerateBtn->setIconSize(QSize(64, 64)); 0150 mGenerateBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 0151 const auto generateBtnDescription = kxi18nc("@info", 0152 "Create a new OpenPGP key pair.<nl/>" 0153 "To create an S/MIME certificate request use " 0154 "<interface>New S/MIME Certification Request</interface> " 0155 "from the <interface>File</interface> menu instead."); 0156 mGenerateBtn->setToolTip(generateBtnDescription.toString()); 0157 mGenerateBtn->setAccessibleDescription(generateBtnDescription.toString(Kuit::PlainText)); 0158 0159 KConfigGroup restrictions(KSharedConfig::openConfig(), QStringLiteral("KDE Action Restrictions")); 0160 mGenerateBtn->setEnabled(restrictions.readEntry("action/file_new_certificate", true)); 0161 0162 mImportBtn = new ToolButton{q}; 0163 mImportBtn->setDefaultAction(importAction); 0164 mImportBtn->setIconSize(QSize(64, 64)); 0165 mImportBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 0166 const auto importBtnDescription = kxi18nc("@info", 0167 "Import certificate from a file.<nl/>" 0168 "To import from a public keyserver use <interface>Lookup on Server</interface> instead."); 0169 mImportBtn->setToolTip(importBtnDescription.toString()); 0170 mImportBtn->setAccessibleDescription(importBtnDescription.toString(Kuit::PlainText)); 0171 mImportBtn->setEnabled(restrictions.readEntry("action/file_import_certificate", true)); 0172 0173 auto btnLayout = new QHBoxLayout; 0174 btnLayout->addStretch(-1); 0175 btnLayout->addWidget(mGenerateBtn); 0176 btnLayout->addWidget(mImportBtn); 0177 btnLayout->addStretch(-1); 0178 0179 vLay->addStretch(-1); 0180 vLay->addLayout(hLay); 0181 vLay->addLayout(btnLayout); 0182 vLay->addStretch(-1); 0183 0184 hLay->addStretch(-1); 0185 hLay->addWidget(mLabel); 0186 hLay->addStretch(-1); 0187 } 0188 0189 void import() 0190 { 0191 mImportBtn->setEnabled(false); 0192 auto cmd = new Kleo::ImportCertificateFromFileCommand(); 0193 cmd->setParentWidget(q); 0194 0195 QObject::connect(cmd, &Kleo::ImportCertificateFromFileCommand::finished, q, [this]() { 0196 mImportBtn->setEnabled(true); 0197 }); 0198 cmd->start(); 0199 } 0200 0201 void generate() 0202 { 0203 mGenerateBtn->setEnabled(false); 0204 auto cmd = new NewOpenPGPCertificateCommand; 0205 cmd->setParentWidget(q); 0206 0207 QObject::connect(cmd, &NewOpenPGPCertificateCommand::finished, q, [this]() { 0208 mGenerateBtn->setEnabled(true); 0209 }); 0210 cmd->start(); 0211 } 0212 0213 WelcomeWidget *const q; 0214 HtmlLabel *mLabel = nullptr; 0215 ToolButton *mGenerateBtn = nullptr; 0216 ToolButton *mImportBtn = nullptr; 0217 }; 0218 0219 WelcomeWidget::WelcomeWidget(QWidget *parent) 0220 : QWidget(parent) 0221 , d(new Private(this)) 0222 { 0223 } 0224 0225 void WelcomeWidget::focusFirstChild(Qt::FocusReason reason) 0226 { 0227 d->mLabel->setFocus(reason); 0228 } 0229 0230 #include "welcomewidget.moc" 0231 0232 #include "moc_welcomewidget.cpp"