Warning, file /utilities/kgpg/kgpgfirstassistant.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2008, 2010, 2012 Rolf Eike Beer <kde@opensource.sf-tec.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "kgpgfirstassistant.h"
0008 
0009 #include "gpgproc.h"
0010 #include "kgpginterface.h"
0011 #include "core/kgpgkey.h"
0012 
0013 #include <KLocalizedString>
0014 #include <KMessageBox>
0015 #include <KUrlRequester>
0016 #include <kio_version.h>
0017 
0018 #include <QCheckBox>
0019 #include <QComboBox>
0020 #include <QGridLayout>
0021 #include <QHBoxLayout>
0022 #include <QLabel>
0023 #include <QSpacerItem>
0024 #include <QStandardPaths>
0025 #include <QTextStream>
0026 #include <QWidget>
0027 #include <QUrl>
0028 #include <kmessagebox.h>
0029 
0030 using namespace KgpgCore;
0031 
0032 KGpgFirstAssistant::KGpgFirstAssistant(QWidget *parent)
0033         : KAssistantDialog(parent)
0034 {
0035     setWindowTitle(i18n("KGpg Assistant"));
0036 
0037     QWidget *page = new QWidget(this);
0038     QGridLayout *gridLayout = new QGridLayout(page);
0039     gridLayout->setSpacing(6);
0040     gridLayout->setContentsMargins(0, 0, 0, 0);
0041 
0042     QLabel *label = new QLabel(page);
0043     QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
0044     sizePolicy.setHorizontalStretch(0);
0045     sizePolicy.setVerticalStretch(0);
0046     sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
0047     label->setSizePolicy(sizePolicy);
0048     label->setFrameShape(QFrame::NoFrame);
0049     label->setFrameShadow(QFrame::Plain);
0050     label->setScaledContents(false);
0051     label->setAlignment(Qt::AlignTop);
0052     label->setWordWrap(false);
0053 
0054     gridLayout->addWidget(label, 0, 0, 3, 1);
0055 
0056     label = new QLabel(page);
0057     label->setAlignment(Qt::AlignTop);
0058     label->setWordWrap(true);
0059     label->setText(i18n("This assistant will first setup some basic configuration options required for KGpg to work properly. Next, it will allow you to create your own key pair, enabling you to encrypt your files and emails."));
0060 
0061     gridLayout->addWidget(label, 0, 1, 1, 1);
0062 
0063     QSpacerItem *spacerItem = new QSpacerItem(20, 41, QSizePolicy::Minimum, QSizePolicy::Expanding);
0064 
0065     gridLayout->addItem(spacerItem, 1, 1, 1, 1);
0066 
0067     page_welcome = addPage(page, i18n("Welcome to the KGpg Assistant"));
0068 
0069     page = new QWidget(this);
0070 
0071     gridLayout = new QGridLayout(page);
0072     gridLayout->setSpacing(6);
0073     gridLayout->setContentsMargins(0, 0, 0, 0);
0074 
0075     label = new QLabel(page);
0076     label->setAlignment(Qt::AlignTop);
0077     label->setWordWrap(true);
0078     label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
0079     label->setText(i18n("KGpg needs to know which GnuPG binary to use."));
0080 
0081     gridLayout->addWidget(label, 0, 1, 1, 1);
0082 
0083     label = new QLabel(page);
0084     label->setAlignment(Qt::AlignTop);
0085     label->setWordWrap(true);
0086     label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
0087     label->setText(i18n("Unless you want to try some unusual settings, just click on the \"next\" button."));
0088 
0089     gridLayout->addWidget(label, 1, 1, 1, 1);
0090 
0091     spacerItem = new QSpacerItem(20, 60, QSizePolicy::Minimum, QSizePolicy::Expanding);
0092 
0093     gridLayout->addItem(spacerItem, 4, 1, 1, 1);
0094 
0095     txtGpgVersion = new QLabel(page);
0096     txtGpgVersion->setWordWrap(true);
0097 
0098     gridLayout->addWidget(txtGpgVersion, 3, 1, 1, 1);
0099 
0100     binURL = new KUrlRequester(page);
0101     binURL->setNameFilters({
0102         i18nc("search filter name for gpg binary", "GnuPG binary") + QLatin1String(" (gpg)"),
0103         i18n("All files") + QLatin1String(" (*)"),
0104     });
0105     QString gpgBin = QStandardPaths::findExecutable(QLatin1String("gpg2"));
0106     if (gpgBin.isEmpty())
0107         gpgBin = QStandardPaths::findExecutable(QLatin1String("gpg"));
0108     if (gpgBin.isEmpty())
0109         gpgBin = QLatin1String("gpg");
0110     binURL->setUrl(QUrl::fromLocalFile(gpgBin));
0111 
0112     connect(binURL, &KUrlRequester::textChanged, this, &KGpgFirstAssistant::slotBinaryChanged);
0113     slotBinaryChanged(gpgBin);
0114 
0115     gridLayout->addWidget(binURL, 2, 1, 1, 1);
0116 
0117     page_binary = addPage(page, i18n("GnuPG Binary"));
0118 
0119     page = new QWidget(this);
0120 
0121     gridLayout = new QGridLayout(page);
0122     gridLayout->setSpacing(6);
0123     gridLayout->setContentsMargins(0, 0, 0, 0);
0124     text_optionsfound = new QLabel(page);
0125     text_optionsfound->setAlignment(Qt::AlignTop);
0126     text_optionsfound->setWordWrap(true);
0127     text_optionsfound->setText(i18n("Unless you want to try some unusual settings, just click on the \"next\" button."));
0128 
0129     gridLayout->addWidget(text_optionsfound, 1, 1, 1, 1);
0130 
0131     label = new QLabel(page);
0132     label->setAlignment(Qt::AlignTop);
0133     label->setWordWrap(true);
0134     label->setText(i18n("KGpg needs to know where your GnuPG configuration file is stored."));
0135 
0136     gridLayout->addWidget(label, 0, 1, 1, 1);
0137 
0138     spacerItem = new QSpacerItem(20, 60, QSizePolicy::Minimum, QSizePolicy::Expanding);
0139 
0140     gridLayout->addItem(spacerItem, 4, 1, 1, 1);
0141 
0142     pathURL = new KUrlRequester(page);
0143 
0144     gridLayout->addWidget(pathURL, 3, 1, 1, 1);
0145 
0146     label = new QLabel(page);
0147     label->setAlignment(Qt::AlignVCenter);
0148     label->setWordWrap(true);
0149     label->setText(i18n("Path to your GnuPG configuration file:"));
0150 
0151     gridLayout->addWidget(label, 2, 1, 1, 1);
0152 
0153     label = new QLabel(page);
0154     sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
0155     label->setSizePolicy(sizePolicy);
0156     label->setFrameShape(QFrame::NoFrame);
0157     label->setFrameShadow(QFrame::Plain);
0158     label->setScaledContents(false);
0159     label->setAlignment(Qt::AlignTop);
0160     label->setWordWrap(false);
0161 
0162     gridLayout->addWidget(label, 0, 0, 5, 1);
0163     page_config = addPage(page, i18n("Configuration File"));
0164 
0165     page = new QWidget(this);
0166     gridLayout = new QGridLayout(page);
0167     gridLayout->setSpacing(6);
0168     gridLayout->setContentsMargins(0, 0, 0, 0);
0169 
0170     QHBoxLayout *hboxLayout = new QHBoxLayout();
0171     hboxLayout->setSpacing(6);
0172     label = new QLabel(page);
0173     label->setText(i18n("Your default key:"));
0174 
0175     hboxLayout->addWidget(label);
0176 
0177     CBdefault = new QComboBox(page);
0178     QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed);
0179     sizePolicy1.setHorizontalStretch(0);
0180     sizePolicy1.setVerticalStretch(0);
0181     sizePolicy1.setHeightForWidth(CBdefault->sizePolicy().hasHeightForWidth());
0182     CBdefault->setSizePolicy(sizePolicy1);
0183 
0184     hboxLayout->addWidget(CBdefault);
0185 
0186     gridLayout->addLayout(hboxLayout, 0, 1, 1, 1);
0187 
0188     spacerItem = new QSpacerItem(20, 30, QSizePolicy::Minimum, QSizePolicy::Expanding);
0189 
0190     gridLayout->addItem(spacerItem, 1, 1, 1, 1);
0191 
0192     page_defaultkey = addPage(page, i18n("Default Key"));
0193 
0194     page = new QWidget(this);
0195 
0196     gridLayout = new QGridLayout(page);
0197     gridLayout->setSpacing(6);
0198     gridLayout->setContentsMargins(0, 0, 0, 0);
0199 
0200     binlabel = new QLabel(page);
0201 
0202     gridLayout->addWidget(binlabel, 0, 1, 1, 1);
0203 
0204     versionLabel = new QLabel(page);
0205 
0206     gridLayout->addWidget(versionLabel, 1, 1, 1, 1);
0207 
0208     defaultkeylabel = new QLabel(page);
0209 
0210     gridLayout->addWidget(defaultkeylabel, 2, 1, 1, 1);
0211 
0212     generateCB = new QCheckBox(page);
0213     generateCB->setText(i18n("Generate new key"));
0214 
0215     gridLayout->addWidget(generateCB, 3, 1, 1, 1);
0216 
0217     spacerItem = new QSpacerItem(20, 30, QSizePolicy::Minimum, QSizePolicy::Expanding);
0218 
0219     gridLayout->addItem(spacerItem, 4, 1, 1, 1);
0220 
0221     autostartCB = new QCheckBox(page);
0222     autostartCB->setChecked(true);
0223     autostartCB->setText(i18n("Start KGpg automatically at KDE startup."));
0224 
0225     gridLayout->addWidget(autostartCB, 5, 1, 1, 1);
0226 
0227     page_done = addPage(page, i18n("Done"));
0228 }
0229 
0230 void
0231 KGpgFirstAssistant::findConfigPath(const QString &gpgBinary)
0232 {
0233     const QString gpgHome = GPGProc::getGpgHome(gpgBinary);
0234     QString confPath = gpgHome + QLatin1String( "gpg.conf" );
0235 
0236     if (!QFile(confPath).exists()) {
0237         const QString confPathOpt = gpgHome + QLatin1String("options");
0238         if (QFile(confPathOpt).exists()) {
0239             confPath = confPathOpt;
0240         } else {
0241             if (KMessageBox::questionTwoActions(nullptr, i18n("<qt><b>The GnuPG configuration file was not found</b>. Should KGpg try to create a config file ?</qt>"), QString(), KGuiItem(i18n("Create Config")), KGuiItem(i18n("Do Not Create"))) == KMessageBox::PrimaryAction) {
0242                 QFile file(confPath);
0243                 if (file.open(QIODevice::WriteOnly)) {
0244                     QTextStream stream(&file);
0245                     stream << "# GnuPG config file created by KGpg\n";
0246                     file.close();
0247                 }
0248             } else {
0249                 text_optionsfound->setText(i18n("<qt><b>The GnuPG configuration file was not found</b>.</qt>"));
0250                 confPath.clear();
0251             }
0252         }
0253     }
0254 
0255     pathURL->setUrl(QUrl::fromLocalFile(confPath));
0256 
0257     const QStringList secids = KgpgInterface::readSecretKeys();
0258 
0259     bool noSecKeys = secids.isEmpty();
0260     generateCB->setChecked(noSecKeys);
0261     setAppropriate(page_defaultkey, !noSecKeys);
0262 
0263     if (noSecKeys) {
0264         defaultkeylabel->setVisible(false);
0265         return;
0266     }
0267 
0268     const KgpgKeyList publiclist = KgpgInterface::readPublicKeys(secids);
0269 
0270     CBdefault->clear();
0271 
0272     for (const KgpgKey &k : publiclist) {
0273         QString s;
0274 
0275         if (k.email().isEmpty())
0276             s = i18nc("Name: ID", "%1: %2", k.name(), k.id());
0277         else
0278             s = i18nc("Name (Email): ID", "%1 (%2): %3", k.name(), k.email(), k.id());
0279 
0280         CBdefault->addItem(s, k.fingerprint());
0281     }
0282 
0283     CBdefault->setCurrentIndex(0);
0284 }
0285 
0286 void
0287 KGpgFirstAssistant::next()
0288 {
0289     if (currentPage() == page_binary) {
0290         const QString &gpgbin = binURL->url().path();
0291         binlabel->setText(i18n("Your GnuPG binary is: %1", gpgbin));
0292         findConfigPath(gpgbin);
0293     } else if (currentPage() == page_config) {
0294         m_confPath = pathURL->url().path();
0295 
0296         const QString defaultID = KgpgInterface::getGpgSetting(QLatin1String( "default-key" ), m_confPath);
0297 
0298         if (!defaultID.isEmpty()) {
0299             for (int i = 0; i < CBdefault->count(); i++) {
0300                 if (QStringView(CBdefault->itemData(i).toString()).right(defaultID.length()).compare(defaultID) == 0) {
0301                     CBdefault->setCurrentIndex(i);
0302                     break;
0303                 }
0304             }
0305         }
0306         versionLabel->setText(i18n("You have GnuPG version: %1", m_gpgVersion));
0307     } else if (currentPage() == page_defaultkey) {
0308         defaultkeylabel->setVisible(true);
0309         defaultkeylabel->setText(i18n("Your default key is: %1", CBdefault->currentText()));
0310         int i = CBdefault->currentIndex();
0311         if (i >= 0) {
0312             defaultkeylabel->setToolTip(CBdefault->itemData(i).toString());
0313         }
0314     }
0315     KAssistantDialog::next();
0316 }
0317 
0318 bool
0319 KGpgFirstAssistant::runKeyGenerate() const
0320 {
0321     return generateCB->isChecked();
0322 }
0323 
0324 QString
0325 KGpgFirstAssistant::getConfigPath() const
0326 {
0327     return m_confPath;
0328 }
0329 
0330 QString
0331 KGpgFirstAssistant::getDefaultKey() const
0332 {
0333     int i = CBdefault->currentIndex();
0334     if (i < 0)
0335         return QString();
0336     else
0337         return CBdefault->itemData(i).toString();
0338 }
0339 
0340 bool
0341 KGpgFirstAssistant::getAutoStart() const
0342 {
0343     return autostartCB->isChecked();
0344 }
0345 
0346 void
0347 KGpgFirstAssistant::slotBinaryChanged(const QString &binary)
0348 {
0349     if (binary.isEmpty()) {
0350         setValid(page_binary, false);
0351         return;
0352     }
0353 
0354     m_gpgVersion = GPGProc::gpgVersionString(binary);
0355     setValid(page_binary, !m_gpgVersion.isEmpty());
0356     if (!m_gpgVersion.isEmpty()) {
0357         const int gpgver = GPGProc::gpgVersion(m_gpgVersion);
0358 
0359         if (gpgver < 0x10400) {
0360             txtGpgVersion->setText(i18n("Your GnuPG version (%1) seems to be too old.<br />Compatibility with versions before 1.4.0 is no longer guaranteed.", m_gpgVersion));
0361         } else {
0362             txtGpgVersion->setText(i18n("You have GnuPG version: %1", m_gpgVersion));
0363         }
0364     }
0365 }