mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-02 14:14:10 +00:00
Better dialog for selecting certificates
Instead of just a simple list of "nickname"'s which is kind of like the signing backend's internal ID for a given certificate, provide some more context to each key. This is a slight improvement, not a complete overhaul.
This commit is contained in:
parent
d3e1c32ff7
commit
763328a6ba
|
@ -5,8 +5,24 @@
|
|||
*/
|
||||
|
||||
#include "signatureutils.h"
|
||||
#include <KLocalizedString>
|
||||
|
||||
using namespace Okular;
|
||||
|
||||
static QString handleEmpty(const QString &string, CertificateInfo::EmptyString empty)
|
||||
{
|
||||
if (string.isEmpty()) {
|
||||
switch (empty) {
|
||||
case CertificateInfo::EmptyString::Empty:
|
||||
return {};
|
||||
case CertificateInfo::EmptyString::TranslatedNotAvailable:
|
||||
return i18n("Not Available");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
class EntityInfo
|
||||
{
|
||||
public:
|
||||
|
@ -77,17 +93,17 @@ void CertificateInfo::setSerialNumber(const QByteArray &serialNumber)
|
|||
d->serialNumber = serialNumber;
|
||||
}
|
||||
|
||||
QString CertificateInfo::issuerInfo(EntityInfoKey key) const
|
||||
QString CertificateInfo::issuerInfo(EntityInfoKey key, EmptyString empty) const
|
||||
{
|
||||
switch (key) {
|
||||
case EntityInfoKey::CommonName:
|
||||
return d->issuerInfo.commonName;
|
||||
return handleEmpty(d->issuerInfo.commonName, empty);
|
||||
case EntityInfoKey::DistinguishedName:
|
||||
return d->issuerInfo.distinguishedName;
|
||||
return handleEmpty(d->issuerInfo.distinguishedName, empty);
|
||||
case EntityInfoKey::EmailAddress:
|
||||
return d->issuerInfo.emailAddress;
|
||||
return handleEmpty(d->issuerInfo.emailAddress, empty);
|
||||
case EntityInfoKey::Organization:
|
||||
return d->issuerInfo.organization;
|
||||
return handleEmpty(d->issuerInfo.organization, empty);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
@ -110,17 +126,17 @@ void CertificateInfo::setIssuerInfo(EntityInfoKey key, const QString &value)
|
|||
}
|
||||
}
|
||||
|
||||
QString CertificateInfo::subjectInfo(EntityInfoKey key) const
|
||||
QString CertificateInfo::subjectInfo(EntityInfoKey key, EmptyString empty) const
|
||||
{
|
||||
switch (key) {
|
||||
case EntityInfoKey::CommonName:
|
||||
return d->subjectInfo.commonName;
|
||||
return handleEmpty(d->subjectInfo.commonName, empty);
|
||||
case EntityInfoKey::DistinguishedName:
|
||||
return d->subjectInfo.distinguishedName;
|
||||
return handleEmpty(d->subjectInfo.distinguishedName, empty);
|
||||
case EntityInfoKey::EmailAddress:
|
||||
return d->subjectInfo.emailAddress;
|
||||
return handleEmpty(d->subjectInfo.emailAddress, empty);
|
||||
case EntityInfoKey::Organization:
|
||||
return d->subjectInfo.organization;
|
||||
return handleEmpty(d->subjectInfo.organization, empty);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
|
|
@ -45,6 +45,11 @@ public:
|
|||
EmailAddress,
|
||||
Organization,
|
||||
};
|
||||
/**
|
||||
* How should certain empty strings be treated
|
||||
* @since 23.08
|
||||
*/
|
||||
enum class EmptyString { /** Empty strings should just be empty*/ Empty, TranslatedNotAvailable /** Empty strings should be a localized version of "Not available" */ };
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
@ -91,7 +96,7 @@ public:
|
|||
* Information about the issuer.
|
||||
* @since 23.08
|
||||
*/
|
||||
QString issuerInfo(EntityInfoKey key) const;
|
||||
QString issuerInfo(EntityInfoKey key, EmptyString empty) const;
|
||||
|
||||
/**
|
||||
* Sets information about the issuer.
|
||||
|
@ -103,7 +108,7 @@ public:
|
|||
* Information about the subject
|
||||
* @since 23.08
|
||||
*/
|
||||
QString subjectInfo(EntityInfoKey key) const;
|
||||
QString subjectInfo(EntityInfoKey key, EmptyString empty) const;
|
||||
|
||||
/**
|
||||
* Sets information about the subject
|
||||
|
|
|
@ -76,7 +76,9 @@ bool PDFSettingsWidget::event(QEvent *e)
|
|||
|
||||
for (const auto &cert : certs) {
|
||||
new QTreeWidgetItem(m_tree,
|
||||
{cert.subjectInfo(Okular::CertificateInfo::EntityInfoKey::CommonName), cert.subjectInfo(Okular::CertificateInfo::EntityInfoKey::EmailAddress), cert.validityEnd().toString(QStringLiteral("yyyy-MM-dd"))});
|
||||
{cert.subjectInfo(Okular::CertificateInfo::EntityInfoKey::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable),
|
||||
cert.subjectInfo(Okular::CertificateInfo::EntityInfoKey::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable),
|
||||
cert.validityEnd().toString(QStringLiteral("yyyy-MM-dd"))});
|
||||
}
|
||||
|
||||
m_pdfsw.defaultLabel->setText(Poppler::getNSSDir());
|
||||
|
|
|
@ -10,14 +10,6 @@
|
|||
#include <QDebug>
|
||||
#include <QInputDialog>
|
||||
|
||||
static QString notAvailableIfEmpty(const QString &string)
|
||||
{
|
||||
if (string.isEmpty()) {
|
||||
return i18n("Not Available");
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
static Okular::CertificateInfo::KeyUsageExtensions fromPoppler(Poppler::CertificateInfo::KeyUsageExtensions popplerKu)
|
||||
{
|
||||
using namespace Okular;
|
||||
|
@ -75,8 +67,8 @@ Okular::CertificateInfo fromPoppler(const Poppler::CertificateInfo &pInfo)
|
|||
oInfo.setSerialNumber(pInfo.serialNumber());
|
||||
for (auto key :
|
||||
{Poppler::CertificateInfo::EntityInfoKey::CommonName, Poppler::CertificateInfo::EntityInfoKey::DistinguishedName, Poppler::CertificateInfo::EntityInfoKey::EmailAddress, Poppler::CertificateInfo::EntityInfoKey::Organization}) {
|
||||
oInfo.setIssuerInfo(static_cast<Okular::CertificateInfo::EntityInfoKey>(key), notAvailableIfEmpty(pInfo.issuerInfo(key)));
|
||||
oInfo.setSubjectInfo(static_cast<Okular::CertificateInfo::EntityInfoKey>(key), notAvailableIfEmpty(pInfo.subjectInfo(key)));
|
||||
oInfo.setIssuerInfo(static_cast<Okular::CertificateInfo::EntityInfoKey>(key), pInfo.issuerInfo(key));
|
||||
oInfo.setSubjectInfo(static_cast<Okular::CertificateInfo::EntityInfoKey>(key), pInfo.subjectInfo(key));
|
||||
}
|
||||
oInfo.setNickName(pInfo.nickName());
|
||||
oInfo.setValidityStart(pInfo.validityStart());
|
||||
|
|
|
@ -73,29 +73,29 @@ QString CertificateModel::propertyVisibleValue(CertificateModel::Property p) con
|
|||
case CertificateModel::SerialNumber:
|
||||
return QString::fromLatin1(m_certificateInfo.serialNumber().toHex(' '));
|
||||
case CertificateModel::Issuer:
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::DistinguishedName);
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::DistinguishedName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::IssuedOn:
|
||||
return QLocale().toString(m_certificateInfo.validityStart(), QLocale::LongFormat);
|
||||
case CertificateModel::ExpiresOn:
|
||||
return QLocale().toString(m_certificateInfo.validityEnd(), QLocale::LongFormat);
|
||||
case CertificateModel::Subject:
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::DistinguishedName);
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::DistinguishedName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::PublicKey:
|
||||
return i18n("%1 (%2 bits)", SignatureGuiUtils::getReadablePublicKeyType(m_certificateInfo.publicKeyType()), m_certificateInfo.publicKeyStrength());
|
||||
case CertificateModel::KeyUsage:
|
||||
return SignatureGuiUtils::getReadableKeyUsageCommaSeparated(m_certificateInfo.keyUsageExtensions());
|
||||
case CertificateModel::IssuerName:
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::CommonName);
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::IssuerEmail:
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::EmailAddress);
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::IssuerOrganization:
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::Organization);
|
||||
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::SubjectName:
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::CommonName);
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::SubjectEmail:
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::EmailAddress);
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::SubjectOrganization:
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::Organization);
|
||||
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
case CertificateModel::Sha1:
|
||||
return QString::fromLatin1(QCryptographicHash::hash(m_certificateInfo.certificateData(), QCryptographicHash::Sha1).toHex(' '));
|
||||
case CertificateModel::Sha256:
|
||||
|
|
|
@ -132,16 +132,16 @@ CertificateViewer::CertificateViewer(const Okular::CertificateInfo &certInfo, QW
|
|||
auto issuerBox = new QGroupBox(i18n("Issued By"), generalPage);
|
||||
auto issuerFormLayout = new QFormLayout(issuerBox);
|
||||
issuerFormLayout->setLabelAlignment(Qt::AlignLeft);
|
||||
issuerFormLayout->addRow(i18n("Common Name(CN)"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::CommonName)));
|
||||
issuerFormLayout->addRow(i18n("EMail"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::EmailAddress)));
|
||||
issuerFormLayout->addRow(i18n("Organization(O)"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::Organization)));
|
||||
issuerFormLayout->addRow(i18n("Common Name(CN)"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable)));
|
||||
issuerFormLayout->addRow(i18n("EMail"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable)));
|
||||
issuerFormLayout->addRow(i18n("Organization(O)"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable)));
|
||||
|
||||
auto subjectBox = new QGroupBox(i18n("Issued To"), generalPage);
|
||||
auto subjectFormLayout = new QFormLayout(subjectBox);
|
||||
subjectFormLayout->setLabelAlignment(Qt::AlignLeft);
|
||||
subjectFormLayout->addRow(i18n("Common Name(CN)"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::CommonName)));
|
||||
subjectFormLayout->addRow(i18n("EMail"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::EmailAddress)));
|
||||
subjectFormLayout->addRow(i18n("Organization(O)"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::Organization)));
|
||||
subjectFormLayout->addRow(i18n("Common Name(CN)"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable)));
|
||||
subjectFormLayout->addRow(i18n("EMail"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable)));
|
||||
subjectFormLayout->addRow(i18n("Organization(O)"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable)));
|
||||
|
||||
auto validityBox = new QGroupBox(i18n("Validity"), generalPage);
|
||||
auto validityFormLayout = new QFormLayout(validityBox);
|
||||
|
|
|
@ -377,7 +377,7 @@ public:
|
|||
documentPassword.clear();
|
||||
} else {
|
||||
certNicknameToUse = signInfo->certificate->nickName();
|
||||
certCommonName = signInfo->certificate->subjectInfo(Okular::CertificateInfo::CommonName);
|
||||
certCommonName = signInfo->certificate->subjectInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
|
||||
passToUse = signInfo->certificatePassword;
|
||||
documentPassword = signInfo->documentPassword;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@gmail.com>
|
||||
SPDX-FileCopyrightText: 2023 g10 Code GmbH
|
||||
SPDX-FileContributor: Sune Stolborg Vuorela <sune@vuorela.dk>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
@ -11,16 +13,24 @@
|
|||
#include "core/page.h"
|
||||
#include "pageview.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QListView>
|
||||
#include <QMimeDatabase>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QStandardItemModel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KMessageBox>
|
||||
|
||||
namespace SignaturePartUtils
|
||||
{
|
||||
|
||||
std::optional<SigningInformation> getCertificateAndPasswordForSigning(PageView *pageView, Okular::Document *doc)
|
||||
{
|
||||
const Okular::CertificateStore *certStore = doc->certificateStore();
|
||||
|
@ -37,19 +47,44 @@ std::optional<SigningInformation> getCertificateAndPasswordForSigning(PageView *
|
|||
QString password;
|
||||
QString documentPassword;
|
||||
|
||||
QStringList items;
|
||||
QStandardItemModel items;
|
||||
QHash<QString, Okular::CertificateInfo> nickToCert;
|
||||
int minWidth = -1;
|
||||
for (const auto &cert : qAsConst(certs)) {
|
||||
items.append(cert.nickName());
|
||||
auto item = std::make_unique<QStandardItem>();
|
||||
QString commonName = cert.subjectInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::Empty);
|
||||
item->setData(commonName, Qt::UserRole);
|
||||
QString emailAddress = cert.subjectInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::Empty);
|
||||
item->setData(emailAddress, Qt::UserRole + 1);
|
||||
|
||||
minWidth = std::max(minWidth, std::max(cert.nickName().size(), emailAddress.size() + commonName.size()));
|
||||
|
||||
item->setData(cert.nickName(), Qt::DisplayRole);
|
||||
item->setData(cert.subjectInfo(Okular::CertificateInfo::DistinguishedName, Okular::CertificateInfo::EmptyString::Empty), Qt::ToolTipRole);
|
||||
item->setEditable(false);
|
||||
items.appendRow(item.release());
|
||||
nickToCert[cert.nickName()] = cert;
|
||||
}
|
||||
|
||||
bool resok = false;
|
||||
const QString certNicknameToUse = QInputDialog::getItem(pageView, i18n("Select certificate to sign with"), i18n("Certificates:"), items, 0, false, &resok);
|
||||
SelectCertificateDialog dialog(pageView);
|
||||
QFontMetrics fm = dialog.fontMetrics();
|
||||
dialog.list->setMinimumWidth(fm.averageCharWidth() * (minWidth + 5));
|
||||
dialog.list->setModel(&items);
|
||||
dialog.list->setAlternatingRowColors(true);
|
||||
dialog.list->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
QObject::connect(dialog.list->selectionModel(), &QItemSelectionModel::selectionChanged, &dialog, [dialog = &dialog](auto &&, auto &&) {
|
||||
// One can ctrl-click on the selected item to deselect it, that would
|
||||
// leave the selection empty, so better prevent the OK button
|
||||
// from being usable
|
||||
dialog->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(dialog->list->selectionModel()->hasSelection());
|
||||
});
|
||||
dialog.list->selectionModel()->select(items.index(0, 0), QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
|
||||
auto result = dialog.exec();
|
||||
|
||||
if (!resok) {
|
||||
if (result == QDialog::Rejected) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto certNicknameToUse = dialog.list->selectionModel()->currentIndex().data(Qt::DisplayRole).toString();
|
||||
|
||||
// I could not find any case in which i need to enter a password to use the certificate, seems that once you unlcok the firefox/NSS database
|
||||
// you don't need a password anymore, but still there's code to do that in NSS so we have code to ask for it if needed. What we do is
|
||||
|
@ -107,7 +142,7 @@ void signUnsignedSignature(const Okular::FormFieldSignature *form, PageView *pag
|
|||
|
||||
Okular::NewSignatureData data;
|
||||
data.setCertNickname(signingInfo->certificate->nickName());
|
||||
data.setCertSubjectCommonName(signingInfo->certificate->subjectInfo(Okular::CertificateInfo::CommonName));
|
||||
data.setCertSubjectCommonName(signingInfo->certificate->subjectInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable));
|
||||
data.setPassword(signingInfo->certificatePassword);
|
||||
data.setDocumentPassword(signingInfo->documentPassword);
|
||||
|
||||
|
@ -123,4 +158,57 @@ void signUnsignedSignature(const Okular::FormFieldSignature *form, PageView *pag
|
|||
}
|
||||
}
|
||||
|
||||
SelectCertificateDialog::SelectCertificateDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setWindowTitle(i18n("Certificates"));
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
list = new QListView();
|
||||
list->setItemDelegate(new KeyDelegate);
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addWidget(new QLabel(i18n("Select certificate to sign with:")));
|
||||
layout->addWidget(list);
|
||||
layout->addWidget(buttonBox);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
QSize KeyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
auto baseSize = QStyledItemDelegate::sizeHint(option, index);
|
||||
baseSize.setHeight(baseSize.height() * 2);
|
||||
return baseSize;
|
||||
}
|
||||
|
||||
void KeyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
auto style = option.widget ? option.widget->style() : QApplication::style();
|
||||
|
||||
QStyledItemDelegate::paint(painter, option, QModelIndex()); // paint the background but without any text on it.
|
||||
|
||||
QPalette::ColorGroup cg;
|
||||
if (option.state & QStyle::State_Active) {
|
||||
cg = QPalette::Normal;
|
||||
} else {
|
||||
cg = QPalette::Inactive;
|
||||
}
|
||||
|
||||
if (option.state & QStyle::State_Selected) {
|
||||
painter->setPen(QPen {option.palette.brush(cg, QPalette::HighlightedText), 0});
|
||||
} else {
|
||||
painter->setPen(QPen {option.palette.brush(cg, QPalette::Text), 0});
|
||||
}
|
||||
|
||||
auto textRect = option.rect;
|
||||
int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, option.widget) + 1;
|
||||
textRect.adjust(textMargin, 0, -textMargin, 0);
|
||||
|
||||
QRect topHalf {textRect.x(), textRect.y(), textRect.width(), textRect.height() / 2};
|
||||
QRect bottomHalf {textRect.x(), textRect.y() + textRect.height() / 2, textRect.width(), textRect.height() / 2};
|
||||
|
||||
style->drawItemText(painter, topHalf, (option.displayAlignment & Qt::AlignVertical_Mask) | Qt::AlignLeft, option.palette, true, index.data(Qt::DisplayRole).toString());
|
||||
style->drawItemText(painter, bottomHalf, (option.displayAlignment & Qt::AlignVertical_Mask) | Qt::AlignRight, option.palette, true, index.data(Qt::UserRole + 1).toString());
|
||||
style->drawItemText(painter, bottomHalf, (option.displayAlignment & Qt::AlignVertical_Mask) | Qt::AlignLeft, option.palette, true, index.data(Qt::UserRole).toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@gmail.com>
|
||||
SPDX-FileCopyrightText: 2023 g10 Code GmbH
|
||||
SPDX-FileContributor: Sune Stolborg Vuorela <sune@vuorela.dk>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
@ -7,12 +9,16 @@
|
|||
#ifndef OKULAR_SIGNATUREPARTUTILS_H
|
||||
#define OKULAR_SIGNATUREPARTUTILS_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "gui/signatureguiutils.h"
|
||||
|
||||
class PageView;
|
||||
class QListView;
|
||||
class QDialogButtonBox;
|
||||
|
||||
namespace SignaturePartUtils
|
||||
{
|
||||
|
@ -30,6 +36,24 @@ std::optional<SigningInformation> getCertificateAndPasswordForSigning(PageView *
|
|||
QString getFileNameForNewSignedFile(PageView *pageView, Okular::Document *doc);
|
||||
void signUnsignedSignature(const Okular::FormFieldSignature *form, PageView *pageView, Okular::Document *doc);
|
||||
|
||||
class KeyDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QStyledItemDelegate::QStyledItemDelegate;
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const final;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const final;
|
||||
};
|
||||
|
||||
class SelectCertificateDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QListView *list;
|
||||
QDialogButtonBox *buttonBox;
|
||||
|
||||
explicit SelectCertificateDialog(QWidget *parent);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue