File indexing completed on 2024-05-12 16:06:47
0001 /* 0002 SPDX-FileCopyrightText: 2019 Bubli <Katarina.Behrens@cib.de> 0003 SPDX-FileCopyrightText: 2020 Albert Astals Cid <albert.astals.cid@kdab.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "pdfsettingswidget.h" 0009 0010 #include "pdfsettings.h" 0011 #include "pdfsignatureutils.h" 0012 0013 #include <KLocalizedString> 0014 #include <KUrlRequester> 0015 0016 #include <QEvent> 0017 #include <QHBoxLayout> 0018 #include <QMessageBox> 0019 #include <QTreeWidget> 0020 #include <QTreeWidgetItem> 0021 0022 #if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 06, 0) 0023 QString PDFSettingsWidget::popplerEnumToSettingString(Poppler::CryptoSignBackend backend) 0024 { 0025 switch (backend) { 0026 case Poppler::CryptoSignBackend::NSS: 0027 return QStringLiteral("NSS"); 0028 case Poppler::CryptoSignBackend::GPG: 0029 return QStringLiteral("GPG"); 0030 } 0031 return {}; 0032 } 0033 0034 static QString popplerEnumToUserString(Poppler::CryptoSignBackend backend) 0035 { 0036 // I'm unsure if we want these translatable, but if so 0037 // we sholud do something here rather than forward directly to the 0038 // technical popplerEnumToSettingString 0039 return PDFSettingsWidget::popplerEnumToSettingString(backend); 0040 } 0041 0042 std::optional<Poppler::CryptoSignBackend> PDFSettingsWidget::settingStringToPopplerEnum(QStringView backend) 0043 { 0044 if (backend == QStringLiteral("NSS")) { 0045 return Poppler::CryptoSignBackend::NSS; 0046 } 0047 if (backend == QStringLiteral("GPG")) { 0048 return Poppler::CryptoSignBackend::GPG; 0049 } 0050 return std::nullopt; 0051 } 0052 #endif 0053 0054 PDFSettingsWidget::PDFSettingsWidget(QWidget *parent) 0055 : QWidget(parent) 0056 { 0057 m_pdfsw.setupUi(this); 0058 0059 #if POPPLER_VERSION_MACRO < QT_VERSION_CHECK(23, 07, 0) 0060 m_pdfsw.kcfg_OverprintPreviewEnabled->hide(); 0061 #endif 0062 0063 #if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 06, 0) 0064 auto backends = Poppler::availableCryptoSignBackends(); 0065 if (!backends.empty()) { 0066 // Let's try get the currently stored backend: 0067 auto currentBackend = settingStringToPopplerEnum(PDFSettings::self()->signatureBackend()); 0068 if (!currentBackend) { 0069 currentBackend = Poppler::activeCryptoSignBackend(); 0070 } 0071 if (currentBackend != Poppler::activeCryptoSignBackend() && currentBackend) { 0072 if (!Poppler::setActiveCryptoSignBackend(currentBackend.value())) { 0073 // erm. This must be a case of having either modified 0074 // the config file manually to something not available 0075 // in the poppler installed here or have reconfigured 0076 // their poppler to not have the previously selected one 0077 // available any longer. 0078 // Probably the safest bet is to take whatever is active 0079 currentBackend = Poppler::activeCryptoSignBackend(); 0080 } 0081 } 0082 int selected = -1; 0083 for (auto backend : backends) { 0084 if (backend == currentBackend) { 0085 selected = m_pdfsw.kcfg_SignatureBackend->count(); 0086 } 0087 m_pdfsw.kcfg_SignatureBackend->addItem(popplerEnumToUserString(backend), QVariant(popplerEnumToSettingString(backend))); 0088 } 0089 m_pdfsw.kcfg_SignatureBackend->setProperty("kcfg_property", QByteArray("currentData")); 0090 0091 m_pdfsw.kcfg_SignatureBackend->setCurrentIndex(selected); 0092 connect(m_pdfsw.kcfg_SignatureBackend, &QComboBox::currentTextChanged, this, [this](const QString &text) { 0093 auto backendEnum = settingStringToPopplerEnum(text); 0094 if (!backendEnum) { 0095 return; 0096 } 0097 Poppler::setActiveCryptoSignBackend(backendEnum.value()); 0098 m_pdfsw.certDBGroupBox->setVisible(backendEnum == Poppler::CryptoSignBackend::NSS); 0099 m_certificatesAsked = false; 0100 if (m_tree) { 0101 m_tree->clear(); 0102 } 0103 update(); 0104 }); 0105 0106 m_pdfsw.certDBGroupBox->setVisible(currentBackend == Poppler::CryptoSignBackend::NSS); 0107 #else 0108 if (Poppler::hasNSSSupport()) { 0109 // Better hide the signature backend selection; we have not really any 0110 // need for that. 0111 m_pdfsw.signatureBackendContainer->hide(); 0112 #endif 0113 0114 m_pdfsw.loadSignaturesButton->hide(); 0115 0116 KUrlRequester *pDlg = new KUrlRequester(); 0117 pDlg->setObjectName(QStringLiteral("kcfg_DBCertificatePath")); 0118 pDlg->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly); 0119 pDlg->setEnabled(false); 0120 m_pdfsw.formLayout->setWidget(1, QFormLayout::FieldRole, pDlg); 0121 0122 connect(m_pdfsw.customRadioButton, &QRadioButton::toggled, pDlg, &KUrlRequester::setEnabled); 0123 0124 if (!PDFSettings::useDefaultCertDB()) { 0125 m_pdfsw.customRadioButton->setChecked(true); 0126 m_pdfsw.defaultLabel->setVisible(false); 0127 } 0128 0129 m_tree = new QTreeWidget(this); 0130 m_tree->setHeaderLabels({i18nc("Name of the person to whom the cerficate was issued", "Issued to"), i18n("E-mail"), i18nc("Certificate expiration date", "Expiration date")}); 0131 m_tree->setRootIsDecorated(false); 0132 0133 m_pdfsw.certificatesPlaceholder->addWidget(m_tree); 0134 0135 connect(PDFSettings::self(), &PDFSettings::useDefaultDBChanged, this, &PDFSettingsWidget::warnRestartNeeded); 0136 connect(PDFSettings::self(), &PDFSettings::dBCertificatePathChanged, this, [this] { 0137 if (!PDFSettings::useDefaultCertDB()) { 0138 warnRestartNeeded(); 0139 } 0140 }); 0141 connect(m_pdfsw.loadSignaturesButton, &QPushButton::clicked, this, [this] { 0142 m_certificatesAsked = false; 0143 update(); 0144 }); 0145 } else { 0146 QHBoxLayout *lay = new QHBoxLayout(this); 0147 QLabel *l = new QLabel(i18n("You are using a Poppler library built without NSS support.\nAdding Digital Signatures isn't available for that reason")); 0148 l->setWordWrap(true); 0149 lay->addWidget(l); 0150 } 0151 } 0152 0153 bool PDFSettingsWidget::event(QEvent *e) 0154 { 0155 if (m_tree && e->type() == QEvent::Paint && !m_certificatesAsked) { 0156 m_certificatesAsked = true; 0157 0158 PopplerCertificateStore st; 0159 bool userCancelled; 0160 const QList<Okular::CertificateInfo> certs = st.signingCertificates(&userCancelled); 0161 0162 m_pdfsw.loadSignaturesButton->setVisible(userCancelled); 0163 0164 for (const auto &cert : certs) { 0165 new QTreeWidgetItem(m_tree, 0166 {cert.subjectInfo(Okular::CertificateInfo::EntityInfoKey::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable), 0167 cert.subjectInfo(Okular::CertificateInfo::EntityInfoKey::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable), 0168 cert.validityEnd().toString(QStringLiteral("yyyy-MM-dd"))}); 0169 } 0170 0171 m_pdfsw.defaultLabel->setText(Poppler::getNSSDir()); 0172 0173 m_tree->resizeColumnToContents(1); 0174 m_tree->resizeColumnToContents(0); 0175 } 0176 return QWidget::event(e); 0177 } 0178 0179 void PDFSettingsWidget::warnRestartNeeded() 0180 { 0181 if (!m_warnedAboutRestart) { 0182 #if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 06, 0) 0183 if (PDFSettings::self()->signatureBackend() != QStringLiteral("NSS")) { 0184 return; 0185 } 0186 #endif 0187 m_warnedAboutRestart = true; 0188 QMessageBox::information(this, i18n("Restart needed"), i18n("You need to restart Okular after changing the NSS directory settings")); 0189 } 0190 }