diff --git a/core/signatureutils.cpp b/core/signatureutils.cpp index 4d8e2c109..1c3227e98 100644 --- a/core/signatureutils.cpp +++ b/core/signatureutils.cpp @@ -1,142 +1,137 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "signatureutils.h" using namespace Okular; CertificateInfo::CertificateInfo() { } CertificateInfo::~CertificateInfo() { } Q_DECLARE_OPERATORS_FOR_FLAGS( CertificateInfo::KeyUsages ) QByteArray CertificateInfo::version() const { return QByteArray(); } QString CertificateInfo::issuerName() const { return QString(); } QString CertificateInfo::issuerDN() const { return QString(); } QByteArray CertificateInfo::serialNumber() const { return QByteArray(); } QDateTime CertificateInfo::validityStart() const { return QDateTime(); } QDateTime CertificateInfo::validityEnd() const { return QDateTime(); } CertificateInfo::KeyUsages CertificateInfo::keyUsages() const { return KuNone; } QByteArray CertificateInfo::publicKey() const { return QByteArray(); } CertificateInfo::PublicKeyType CertificateInfo::publicKeyType() const { return OtherKey; } int CertificateInfo::publicKeyStrength() const { return -1; } -bool CertificateInfo::isSelfSigned() const -{ - return false; -} - QByteArray CertificateInfo::certificateData() const { return QByteArray(); } SignatureInfo::SignatureInfo() { } SignatureInfo::~SignatureInfo() { } SignatureInfo::SignatureStatus SignatureInfo::signatureStatus() const { return SignatureStatusUnknown; } SignatureInfo::CertificateStatus SignatureInfo::certificateStatus() const { return CertificateStatusUnknown; } SignatureInfo::HashAlgorithm SignatureInfo::hashAlgorithm() const { return HashAlgorithmUnknown; } QString SignatureInfo::subjectName() const { return QString(); } QString SignatureInfo::subjectDN() const { return QString(); } QDateTime SignatureInfo::signingTime() const { return QDateTime(); } QByteArray SignatureInfo::signature() const { return QByteArray(); } QList SignatureInfo::signedRangeBounds() const { return QList(); } bool SignatureInfo::signsTotalDocument() const { return false; } CertificateInfo *SignatureInfo::certificateInfo() const { return nullptr; } diff --git a/core/signatureutils.h b/core/signatureutils.h index a223043c9..2955dc21f 100644 --- a/core/signatureutils.h +++ b/core/signatureutils.h @@ -1,251 +1,246 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef OKULAR_SIGNATUREINFO_H #define OKULAR_SIGNATUREINFO_H #include "okularcore_export.h" #include #include #include #include #include namespace Okular { class CertificateInfoPrivate; class SignatureInfoPrivate; /** * @short A helper class to store information x509 digital certificate */ class OKULARCORE_EXPORT CertificateInfo { public: /** * The algorithm of public key. */ enum PublicKeyType { RsaKey, DsaKey, EcKey, OtherKey }; /** * Certificate key usage. */ enum KeyUsage { KuNone = 0, KuDigitalSignature = 1, KuNonRepudiation = 2, KuKeyEncipherment = 4, KuDataEncipherment = 8, KuKeyAgreement = 16, KuKeyCertSign = 32, KuClrSign = 64, KuEncipherOnly = 128 }; Q_DECLARE_FLAGS( KeyUsages, KeyUsage ) /** * Destructor */ virtual ~CertificateInfo(); /** * The certificate version string in hex encoding. */ virtual QByteArray version() const; /** * The common name of certificate issuer. */ virtual QString issuerName() const; /** * The distinguished name of certificate issuer. */ virtual QString issuerDN() const; /** The hex encoded certificate serial number. */ virtual QByteArray serialNumber() const; /** The date-time when certificate becomes valid. */ virtual QDateTime validityStart() const; /** * The date-time when certificate expires. */ virtual QDateTime validityEnd() const; /** * The key usages of certificate. */ virtual KeyUsages keyUsages() const; /** * The public key value. */ virtual QByteArray publicKey() const; /** * The public key type. */ virtual PublicKeyType publicKeyType() const; /** * The strength of public key in bits or -1 in case * key type is 'OtherKey'. */ virtual int publicKeyStrength() const; - /** - * Returns true if certificate is self signed; otherwise returns false. - */ - virtual bool isSelfSigned() const; - /** * The DER encoded certificate. */ virtual QByteArray certificateData() const; protected: CertificateInfo(); private: Q_DISABLE_COPY( CertificateInfo ) }; /** * @short A helper class to store information about digital signature */ class OKULARCORE_EXPORT SignatureInfo { public: /** * The verfication result of the signature. */ enum SignatureStatus { SignatureStatusUnknown, ///< The signature status is unknown for some reason. SignatureValid, ///< The signature is cryptographically valid. SignatureInvalid, ///< The signature is cryptographically invalid. SignatureDigestMismatch, ///< The document content was changed after the signature was applied. SignatureDecodingError, ///< The signature CMS/PKCS7 classure is malformed. SignatureGenericError, ///< The signature could not be verified. SignatureNotFound, ///< The requested signature is not present in the document. SignatureNotVerified ///< The signature is not yet verified. }; /** * The verification result of the certificate. */ enum CertificateStatus { CertificateStatusUnknown, ///< The certificate status is unknown for some reason. CertificateTrusted, ///< The certificate is considered trusted. CertificateUntrustedIssuer, ///< The issuer of this certificate has been marked as untrusted by the user. CertificateUnknownIssuer, ///< The certificate trust chain has not finished in a trusted root certificate. CertificateRevoked, ///< The certificate was revoked by the issuing certificate authority. CertificateExpired, ///< The signing time is outside the validity bounds of this certificate. CertificateGenericError, ///< The certificate could not be verified. CertificateNotVerified ///< The certificate is not yet verified. }; /** * The hash algorithm of the signature */ enum HashAlgorithm { HashAlgorithmUnknown, HashAlgorithmMd2, HashAlgorithmMd5, HashAlgorithmSha1, HashAlgorithmSha256, HashAlgorithmSha384, HashAlgorithmSha512, HashAlgorithmSha224 }; /** * Destructor. */ virtual ~SignatureInfo(); /** * The signature status of the signature. */ virtual SignatureStatus signatureStatus() const; /** * The certificate status of the signature. */ virtual CertificateStatus certificateStatus() const; /** * The signer subject common name associated with the signature. */ virtual QString subjectName() const; /** * The signer subject distinguished name associated with the signature. */ virtual QString subjectDN() const; /** * The the hash algorithm used for the signature. */ virtual HashAlgorithm hashAlgorithm() const; /** * The signing time associated with the signature. */ virtual QDateTime signingTime() const; /** * Get the signature binary data. */ virtual QByteArray signature() const; /** * Get the bounds of the ranges of the document which are signed. */ virtual QList signedRangeBounds() const; /** * Checks whether the signature authenticates the total document * except for the signature itself. */ virtual bool signsTotalDocument() const; /** * Get certificate details. */ virtual CertificateInfo *certificateInfo() const; protected: SignatureInfo(); private: Q_DISABLE_COPY( SignatureInfo ) }; } #endif diff --git a/generators/poppler/pdfsignatureutils.cpp b/generators/poppler/pdfsignatureutils.cpp index d16a41fde..41a0c5986 100644 --- a/generators/poppler/pdfsignatureutils.cpp +++ b/generators/poppler/pdfsignatureutils.cpp @@ -1,223 +1,217 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "pdfsignatureutils.h" PopplerCertificateInfo::PopplerCertificateInfo( const Poppler::CertificateInfo &info ) : m_info( new Poppler::CertificateInfo( nullptr ) ) { *m_info = info; } PopplerCertificateInfo::~PopplerCertificateInfo() { } QByteArray PopplerCertificateInfo::version() const { return m_info->version(); } QString PopplerCertificateInfo::issuerName() const { return m_info->issuerName(); } QString PopplerCertificateInfo::issuerDN() const { return m_info->issuerDN(); } QByteArray PopplerCertificateInfo::serialNumber() const { return m_info->serialNumber(); } QDateTime PopplerCertificateInfo::validityStart() const { return m_info->validityStart(); } QDateTime PopplerCertificateInfo::validityEnd() const { return m_info->validityEnd(); } PopplerCertificateInfo::KeyUsages PopplerCertificateInfo::keyUsages() const { Poppler::CertificateInfo::KeyUsages popplerKu = m_info->keyUsages(); KeyUsages ku = KuNone; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuDigitalSignature ) ) ku |= KuDigitalSignature; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuNonRepudiation ) ) ku |= KuNonRepudiation; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuKeyEncipherment ) ) ku |= KuKeyEncipherment; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuDataEncipherment ) ) ku |= KuDataEncipherment; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuKeyAgreement ) ) ku |= KuKeyAgreement; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuKeyCertSign ) ) ku |= KuKeyCertSign; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuClrSign ) ) ku |= KuClrSign; if ( popplerKu.testFlag( Poppler::CertificateInfo::KuEncipherOnly ) ) ku |= KuEncipherOnly; return ku; } QByteArray PopplerCertificateInfo::publicKey() const { return m_info->publicKey(); } PopplerCertificateInfo::PublicKeyType PopplerCertificateInfo::publicKeyType() const { switch ( m_info->publicKeyType() ) { case Poppler::CertificateInfo::RsaKey: return RsaKey; case Poppler::CertificateInfo::DsaKey: return DsaKey; case Poppler::CertificateInfo::EcKey: return EcKey; case Poppler::CertificateInfo::OtherKey: return OtherKey; } } int PopplerCertificateInfo::publicKeyStrength() const { return m_info->publicKeyStrength(); } -bool PopplerCertificateInfo::isSelfSigned() const -{ - return m_info->isSelfSigned(); -} - QByteArray PopplerCertificateInfo::certificateData() const { return m_info->certificateData(); } PopplerSignatureInfo::PopplerSignatureInfo( const Poppler::SignatureValidationInfo &info ) : m_info( new Poppler::SignatureValidationInfo( nullptr ) ) { *m_info = info; } PopplerSignatureInfo::~PopplerSignatureInfo() { } PopplerSignatureInfo::SignatureStatus PopplerSignatureInfo::signatureStatus() const { switch ( m_info->signatureStatus() ) { case Poppler::SignatureValidationInfo::SignatureValid: return SignatureValid; case Poppler::SignatureValidationInfo::SignatureInvalid: return SignatureInvalid; case Poppler::SignatureValidationInfo::SignatureDigestMismatch: return SignatureDigestMismatch; case Poppler::SignatureValidationInfo::SignatureDecodingError: return SignatureDecodingError; case Poppler::SignatureValidationInfo::SignatureGenericError: return SignatureGenericError; case Poppler::SignatureValidationInfo::SignatureNotFound: return SignatureNotFound; case Poppler::SignatureValidationInfo::SignatureNotVerified: return SignatureNotVerified; default: return SignatureStatusUnknown; } } PopplerSignatureInfo::CertificateStatus PopplerSignatureInfo::certificateStatus() const { switch ( m_info->certificateStatus() ) { case Poppler::SignatureValidationInfo::CertificateTrusted: return CertificateTrusted; case Poppler::SignatureValidationInfo::CertificateUntrustedIssuer: return CertificateUntrustedIssuer; case Poppler::SignatureValidationInfo::CertificateUnknownIssuer: return CertificateUnknownIssuer; case Poppler::SignatureValidationInfo::CertificateRevoked: return CertificateRevoked; case Poppler::SignatureValidationInfo::CertificateExpired: return CertificateExpired; case Poppler::SignatureValidationInfo::CertificateGenericError: return CertificateGenericError; case Poppler::SignatureValidationInfo::CertificateNotVerified: return CertificateNotVerified; default: return CertificateStatusUnknown; } } PopplerSignatureInfo::HashAlgorithm PopplerSignatureInfo::hashAlgorithm() const { switch ( m_info->hashAlgorithm() ) { case Poppler::SignatureValidationInfo::HashAlgorithmMd2: return HashAlgorithmMd2; case Poppler::SignatureValidationInfo::HashAlgorithmMd5: return HashAlgorithmMd5; case Poppler::SignatureValidationInfo::HashAlgorithmSha1: return HashAlgorithmSha1; case Poppler::SignatureValidationInfo::HashAlgorithmSha256: return HashAlgorithmSha256; case Poppler::SignatureValidationInfo::HashAlgorithmSha384: return HashAlgorithmSha384; case Poppler::SignatureValidationInfo::HashAlgorithmSha512: return HashAlgorithmSha512; case Poppler::SignatureValidationInfo::HashAlgorithmSha224: return HashAlgorithmSha224; default: return HashAlgorithmUnknown; } } QString PopplerSignatureInfo::subjectName() const { return m_info->signerName(); } - QString PopplerSignatureInfo::subjectDN() const { return m_info->signerSubjectDN(); } QDateTime PopplerSignatureInfo::signingTime() const { return QDateTime::fromTime_t( m_info->signingTime() ); } QByteArray PopplerSignatureInfo::signature() const { return m_info->signature(); } QList PopplerSignatureInfo::signedRangeBounds() const { return m_info->signedRangeBounds(); } bool PopplerSignatureInfo::signsTotalDocument() const { return m_info->signsTotalDocument(); } Okular::CertificateInfo *PopplerSignatureInfo::certificateInfo() const { return ( new PopplerCertificateInfo( m_info->certificateInfo() ) ); } diff --git a/generators/poppler/pdfsignatureutils.h b/generators/poppler/pdfsignatureutils.h index e507581de..b33adb59a 100644 --- a/generators/poppler/pdfsignatureutils.h +++ b/generators/poppler/pdfsignatureutils.h @@ -1,61 +1,60 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef _OKULAR_GENERATOR_PDF_SIGNATUREINFO_H_ #define _OKULAR_GENERATOR_PDF_SIGNATUREINFO_H_ #include #include "core/signatureutils.h" class PopplerCertificateInfo : public Okular::CertificateInfo { public: PopplerCertificateInfo(const Poppler::CertificateInfo &info); ~PopplerCertificateInfo(); QByteArray version() const override; QString issuerName() const override; QString issuerDN() const override; QByteArray serialNumber() const override; QDateTime validityStart() const override; QDateTime validityEnd() const override; KeyUsages keyUsages() const override; QByteArray publicKey() const override; PublicKeyType publicKeyType() const override; int publicKeyStrength() const override; - bool isSelfSigned() const override; QByteArray certificateData() const override; private: Poppler::CertificateInfo *m_info; }; class PopplerSignatureInfo : public Okular::SignatureInfo { public: PopplerSignatureInfo( const Poppler::SignatureValidationInfo &info ); ~PopplerSignatureInfo(); SignatureStatus signatureStatus() const override; CertificateStatus certificateStatus() const override; QString subjectName() const override; QString subjectDN() const override; HashAlgorithm hashAlgorithm() const override; QDateTime signingTime() const override; QByteArray signature() const override; QList signedRangeBounds() const override; bool signsTotalDocument() const override; Okular::CertificateInfo *certificateInfo() const override; private: Poppler::SignatureValidationInfo *m_info; }; #endif diff --git a/ui/signaturewidgets.cpp b/ui/signaturewidgets.cpp index d4514bcae..3ff953040 100644 --- a/ui/signaturewidgets.cpp +++ b/ui/signaturewidgets.cpp @@ -1,229 +1,228 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "signaturewidgets.h" #include #include #include #include #include #include #include #include static QString getReadableSigState( Okular::SignatureInfo::SignatureStatus sigStatus ) { switch ( sigStatus ) { case Okular::SignatureInfo::SignatureValid: return i18n("Signature is Valid."); case Okular::SignatureInfo::SignatureInvalid: return i18n("Signature is Invalid."); case Okular::SignatureInfo::SignatureDigestMismatch: return i18n("Digest Mismatch."); case Okular::SignatureInfo::SignatureDecodingError: return i18n("Document isn't signed or corrupted data."); case Okular::SignatureInfo::SignatureNotVerified: return i18n("Signature has not yet been verified."); default: return i18n("Unknown Validation Failure."); } } static QString getReadableCertState( Okular::SignatureInfo::CertificateStatus certStatus ) { switch ( certStatus ) { case Okular::SignatureInfo::CertificateTrusted: return i18n("Certificate is Trusted."); case Okular::SignatureInfo::CertificateUntrustedIssuer: return i18n("Certificate issuer isn't Trusted."); case Okular::SignatureInfo::CertificateUnknownIssuer: return i18n("Certificate issuer is unknown."); case Okular::SignatureInfo::CertificateRevoked: return i18n("Certificate has been Revoked."); case Okular::SignatureInfo::CertificateExpired: return i18n("Certificate has Expired."); case Okular::SignatureInfo::CertificateNotVerified: return i18n("Certificate has not yet been verified."); default: return i18n("Unknown issue with Certificate or corrupted data."); } } static QString getReadableHashAlgorithm( Okular::SignatureInfo::HashAlgorithm hashAlg ) { switch ( hashAlg ) { case Okular::SignatureInfo::HashAlgorithmMd2: return i18n("MD2"); case Okular::SignatureInfo::HashAlgorithmMd5: return i18n("MD5"); case Okular::SignatureInfo::HashAlgorithmSha1: return i18n("SHA1"); case Okular::SignatureInfo::HashAlgorithmSha256: return i18n("SHA256"); case Okular::SignatureInfo::HashAlgorithmSha384: return i18n("SHA384"); case Okular::SignatureInfo::HashAlgorithmSha512: return i18n("SHA512"); case Okular::SignatureInfo::HashAlgorithmSha224: return i18n("SHA224"); default: return i18n("Unknown"); } } SignaturePropertiesModel::SignaturePropertiesModel( Okular::SignatureInfo *sigInfo, QObject * parent ) : QAbstractTableModel( parent ) { m_sigProperties.append( qMakePair( i18n("Subject Name"), sigInfo->subjectName() ) ); m_sigProperties.append( qMakePair( i18n("Subject Distinguished Name"), sigInfo->subjectDN() ) ); m_sigProperties.append( qMakePair( i18n("Signing Time"), sigInfo->signingTime().toString( QStringLiteral("MMM dd yyyy hh:mm:ss") ) ) ); m_sigProperties.append( qMakePair( i18n("Hash Algorithm"), getReadableHashAlgorithm( sigInfo->hashAlgorithm() ) ) ); m_sigProperties.append( qMakePair( i18n("Signature Status"), getReadableSigState( sigInfo->signatureStatus() ) ) ); m_sigProperties.append( qMakePair( i18n("Certificate Status"), getReadableCertState( sigInfo->certificateStatus() ) ) ); m_sigProperties.append( qMakePair( i18n("Signature Data"), QString::fromUtf8( sigInfo->signature().toHex(' ') ) ) ); m_sigProperties.append( qMakePair( QStringLiteral("----------"), QString("------Certificate Properties--------") ) ); Okular::CertificateInfo *certInfo = sigInfo->certificateInfo(); m_sigProperties.append( qMakePair( i18n("Version"), certInfo->version() ) ); m_sigProperties.append( qMakePair( i18n("Issuer Name"), certInfo->issuerName() ) ); m_sigProperties.append( qMakePair( i18n("Issuer Distinguished Name"), certInfo->issuerDN() ) ); m_sigProperties.append( qMakePair( i18n("Serial Number"), certInfo->serialNumber() ) ); m_sigProperties.append( qMakePair( i18n("Validity Start"), certInfo->validityStart().toString( QStringLiteral("MMM dd yyyy hh:mm:ss") ) ) ); m_sigProperties.append( qMakePair( i18n("Validity End"), certInfo->validityEnd().toString( QStringLiteral("MMM dd yyyy hh:mm:ss") ) ) ); m_sigProperties.append( qMakePair( i18n("Public Key"), certInfo->publicKey() ) ); - m_sigProperties.append( qMakePair( i18n("Is Self Signed"), certInfo->isSelfSigned() ? QString("true") : QString("false") ) ); } int SignaturePropertiesModel::columnCount( const QModelIndex &parent ) const { return parent.isValid() ? 0 : 2; } int SignaturePropertiesModel::rowCount( const QModelIndex &parent ) const { return parent.isValid() ? 0 : m_sigProperties.size(); } QVariant SignaturePropertiesModel::data( const QModelIndex &index, int role ) const { int row = index.row(); if ( !index.isValid() || row < 0 || row >= m_sigProperties.count() ) return QVariant(); switch ( role ) { case Qt::DisplayRole: case Qt::ToolTipRole: switch ( index.column() ) { case 0: return m_sigProperties[row].first; case 1: return m_sigProperties[row].second; default: return QString(); } case PropertyValueRole: return m_sigProperties[row].second; } return QVariant(); } QVariant SignaturePropertiesModel::headerData( int section, Qt::Orientation orientation, int role ) const { if ( role == Qt::TextAlignmentRole ) return QVariant( Qt::AlignLeft ); if ( orientation != Qt::Horizontal || role != Qt::DisplayRole) return QVariant(); switch ( section ) { case 0: return i18n("Property"); case 1: return i18n("Value"); default: return QVariant(); } } SignaturePropertiesDialog::SignaturePropertiesDialog( Okular::SignatureInfo *sigInfo, QWidget *parent ) : QDialog( parent ), m_sigInfo( sigInfo ) { setModal( true ); setFixedSize( QSize( 450, 500 )); setWindowTitle( i18n("Signature Properties") ); auto sigPropLabel = new QLabel( this ); sigPropLabel->setText( i18n("Signature Properties:") ); auto sigPropTree = new QTreeView( this ); sigPropTree->setIndentation( 0 ); m_sigPropModel = new SignaturePropertiesModel( m_sigInfo, this ); sigPropTree->setModel( m_sigPropModel ); connect( sigPropTree, &QTreeView::clicked, this, &SignaturePropertiesDialog::updateText ); m_sigPropText = new QTextEdit( this ); m_sigPropText->setReadOnly( true ); auto btnBox = new QDialogButtonBox( QDialogButtonBox::Close, this ); btnBox->button( QDialogButtonBox::Close )->setDefault( true ); connect( btnBox, &QDialogButtonBox::rejected, this, &SignatureSummaryDialog::reject ); auto mainLayout = new QVBoxLayout( this ); mainLayout->addWidget( sigPropLabel ); mainLayout->addWidget( sigPropTree ); mainLayout->addWidget( m_sigPropText ); mainLayout->addWidget( btnBox ); setLayout( mainLayout ); } void SignaturePropertiesDialog::updateText( const QModelIndex &index ) { m_sigPropText->setText( m_sigPropModel->data( index, SignaturePropertiesModel::PropertyValueRole ).toString() ); } SignatureSummaryDialog::SignatureSummaryDialog( Okular::SignatureInfo *sigInfo, QWidget *parent ) : QDialog( parent ), m_sigInfo( sigInfo ) { setModal( true ); setFixedSize( QSize(250, 100) ); setWindowTitle( i18n("Signature Validation Status") ); auto sigStatusLabel = new QLabel( this ); sigStatusLabel->setText( getReadableSigState( m_sigInfo->signatureStatus() ) ); auto btnBox = new QDialogButtonBox( QDialogButtonBox::Close, this ); auto sigPropBtn = new QPushButton( i18n( "Signature Properties"), this ); btnBox->button( QDialogButtonBox::Close )->setDefault( true ); btnBox->addButton( sigPropBtn, QDialogButtonBox::ActionRole ); connect( btnBox, &QDialogButtonBox::rejected, this, &SignatureSummaryDialog::reject ); connect( sigPropBtn, &QPushButton::clicked, this, &SignatureSummaryDialog::showSignatureProperties ); auto mainLayout = new QVBoxLayout( this ); mainLayout->addWidget( sigStatusLabel ); mainLayout->addWidget( btnBox ); setLayout( mainLayout ); } void SignatureSummaryDialog::showSignatureProperties() { reject(); SignaturePropertiesDialog sigPropDlg( m_sigInfo, this ); sigPropDlg.exec(); } #include "moc_signaturewidgets.cpp"