File indexing completed on 2024-04-28 15:51:59

0001 /*
0002     SPDX-FileCopyrightText: 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "signaturepropertiesdialog.h"
0008 
0009 #include <KColumnResizer>
0010 #include <KLocalizedString>
0011 
0012 #include <QDialogButtonBox>
0013 #include <QFormLayout>
0014 #include <QGroupBox>
0015 #include <QLabel>
0016 #include <QProcess>
0017 #include <QPushButton>
0018 #include <QStandardPaths>
0019 #include <QVBoxLayout>
0020 #include <QVector>
0021 
0022 #include "core/document.h"
0023 #include "core/form.h"
0024 
0025 #include "certificateviewer.h"
0026 #include "gui/signatureguiutils.h"
0027 #include "revisionviewer.h"
0028 
0029 static QString getValidDisplayString(const QString &str)
0030 {
0031     return !str.isEmpty() ? str : i18n("Not Available");
0032 }
0033 
0034 SignaturePropertiesDialog::SignaturePropertiesDialog(Okular::Document *doc, const Okular::FormFieldSignature *form, QWidget *parent)
0035     : QDialog(parent)
0036     , m_doc(doc)
0037     , m_signatureForm(form)
0038 {
0039     setModal(true);
0040     setWindowTitle(i18n("Signature Properties"));
0041 
0042     m_kleopatraPath = QStandardPaths::findExecutable(QStringLiteral("kleopatra"));
0043 
0044     const Okular::SignatureInfo &signatureInfo = form->signatureInfo();
0045     const Okular::SignatureInfo::SignatureStatus signatureStatus = signatureInfo.signatureStatus();
0046     const QString readableSignatureStatus = SignatureGuiUtils::getReadableSignatureStatus(signatureStatus);
0047     const QString modificationSummary = SignatureGuiUtils::getReadableModificationSummary(signatureInfo);
0048     const QString signerName = getValidDisplayString(signatureInfo.signerName());
0049     const QString signingTime = getValidDisplayString(QLocale().toString(signatureInfo.signingTime(), QLocale::LongFormat));
0050     const QString signingLocation = getValidDisplayString(signatureInfo.location());
0051     const QString signingReason = signatureInfo.reason();
0052 
0053     auto signatureStatusBox = new QGroupBox(i18n("Validity Status"));
0054     auto signatureStatusFormLayout = new QFormLayout(signatureStatusBox);
0055     signatureStatusFormLayout->setLabelAlignment(Qt::AlignLeft);
0056     signatureStatusFormLayout->addRow(i18n("Signature Validity:"), new QLabel(readableSignatureStatus));
0057     signatureStatusFormLayout->addRow(i18n("Document Modifications:"), new QLabel(modificationSummary));
0058 
0059     // additional information
0060     auto extraInfoBox = new QGroupBox(i18n("Additional Information"));
0061     auto extraInfoFormLayout = new QFormLayout(extraInfoBox);
0062     extraInfoFormLayout->setLabelAlignment(Qt::AlignLeft);
0063     extraInfoFormLayout->addRow(i18n("Signed By:"), new QLabel(signerName));
0064     extraInfoFormLayout->addRow(i18n("Signing Time:"), new QLabel(signingTime));
0065     if (!signingReason.isEmpty()) {
0066         extraInfoFormLayout->addRow(i18n("Reason:"), new QLabel(signingReason));
0067     }
0068     extraInfoFormLayout->addRow(i18n("Location:"), new QLabel(signingLocation));
0069 
0070     // keep width of column 1 same
0071     auto resizer = new KColumnResizer(this);
0072     resizer->addWidgetsFromLayout(signatureStatusFormLayout->layout(), 0);
0073     resizer->addWidgetsFromLayout(extraInfoFormLayout->layout(), 0);
0074 
0075     // document revision info
0076     QGroupBox *revisionBox = nullptr;
0077     if (signatureStatus != Okular::SignatureInfo::SignatureStatusUnknown && !signatureInfo.signsTotalDocument()) {
0078         revisionBox = new QGroupBox(i18n("Document Version"));
0079         auto revisionLayout = new QHBoxLayout(revisionBox);
0080         const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(m_doc);
0081         revisionLayout->addWidget(new QLabel(i18nc("Document Revision <current> of <total>", "Document Revision %1 of %2", signatureFormFields.indexOf(m_signatureForm) + 1, signatureFormFields.size())));
0082         revisionLayout->addStretch();
0083         auto revisionBtn = new QPushButton(i18n("View Signed Version..."));
0084         connect(revisionBtn, &QPushButton::clicked, this, &SignaturePropertiesDialog::viewSignedVersion);
0085         revisionLayout->addWidget(revisionBtn);
0086     }
0087 
0088     // button box
0089     auto btnBox = new QDialogButtonBox(QDialogButtonBox::Close, this);
0090     auto certPropBtn = new QPushButton(i18n("View Certificate..."));
0091     certPropBtn->setEnabled(!signatureInfo.certificateInfo().isNull());
0092     auto certManagerBtn = new QPushButton(i18n("View in Certificate Manager"));
0093     certManagerBtn->setVisible(signatureInfo.certificateInfo().backend() == Okular::CertificateInfo::Backend::Gpg);
0094     certManagerBtn->setEnabled(!m_kleopatraPath.isEmpty());
0095     if (m_kleopatraPath.isEmpty()) {
0096         certManagerBtn->setToolTip(i18n("KDE Certificate Manager (kleopatra) not found"));
0097     }
0098     btnBox->addButton(certPropBtn, QDialogButtonBox::ActionRole);
0099     btnBox->addButton(certManagerBtn, QDialogButtonBox::ActionRole);
0100     connect(btnBox, &QDialogButtonBox::rejected, this, &SignaturePropertiesDialog::reject);
0101     connect(certPropBtn, &QPushButton::clicked, this, &SignaturePropertiesDialog::viewCertificateProperties);
0102     connect(certManagerBtn, &QPushButton::clicked, this, [this]() {
0103         QStringList args;
0104         args << QStringLiteral("--parent-windowid") << QString::number(static_cast<qlonglong>(window()->winId())) << QStringLiteral("--query") << m_signatureForm->signatureInfo().certificateInfo().nickName();
0105         QProcess::startDetached(m_kleopatraPath, args);
0106     });
0107 
0108     auto mainLayout = new QVBoxLayout(this);
0109     mainLayout->addWidget(signatureStatusBox);
0110     mainLayout->addWidget(extraInfoBox);
0111     if (revisionBox) {
0112         mainLayout->addWidget(revisionBox);
0113     }
0114     mainLayout->addWidget(btnBox);
0115 
0116     resize(mainLayout->sizeHint());
0117 }
0118 
0119 void SignaturePropertiesDialog::viewCertificateProperties()
0120 {
0121     CertificateViewer certViewer(m_signatureForm->signatureInfo().certificateInfo(), this);
0122     certViewer.exec();
0123 }
0124 
0125 void SignaturePropertiesDialog::viewSignedVersion()
0126 {
0127     const QByteArray data = m_doc->requestSignedRevisionData(m_signatureForm->signatureInfo());
0128     RevisionViewer revViewer(data, this);
0129     revViewer.viewRevision();
0130 }
0131 
0132 #include "moc_signaturepropertiesdialog.cpp"