Fix two Signature issues on multipage/multisignature documents

First issue:
 - The "document is totally signed" was based on the last signature of
   the last page (that had signatures) that is not correct and needs to
   be based in the last signature by date

 - The "Rev #" number was based on the signature on the page, so if we
   had two pages with one signature each the model showed "Rev 1" for
   both

It adds new API which is not awesome in a stable branch, but the first
issue is important enough that warrants this to go to the stable branch
remotes/origin/release/21.12
Albert Astals Cid 4 years ago
parent 8a09492a9a
commit 44c86de7e4
  1. 6
      core/form.cpp
  2. 7
      core/form.h
  3. 1
      core/form_p.h
  4. 1
      core/page.cpp
  5. 2
      part/part.cpp
  6. 11
      part/signatureguiutils.cpp
  7. 5
      part/signatureguiutils.h
  8. 59
      part/signaturemodel.cpp
  9. 2
      part/signaturepanel.cpp
  10. 2
      part/signaturepropertiesdialog.cpp

@ -115,6 +115,12 @@ void FormField::setAdditionalAction(Annotation::AdditionalActionType type, Actio
d->m_additionalAnnotActions[type] = action; d->m_additionalAnnotActions[type] = action;
} }
Page *FormField::page() const
{
Q_D(const FormField);
return d->m_page;
}
class Okular::FormFieldButtonPrivate : public Okular::FormFieldPrivate class Okular::FormFieldButtonPrivate : public Okular::FormFieldPrivate
{ {
public: public:

@ -157,6 +157,13 @@ public:
*/ */
Action *additionalAction(Annotation::AdditionalActionType type) const; Action *additionalAction(Annotation::AdditionalActionType type) const;
/**
* Returns the page of this form field
*
* @since 21.12.2
*/
Page *page() const;
protected: protected:
/// @cond PRIVATE /// @cond PRIVATE
explicit FormField(FormFieldPrivate &dd); explicit FormField(FormFieldPrivate &dd);

@ -35,6 +35,7 @@ public:
Action *m_activateAction; Action *m_activateAction;
QHash<int, Action *> m_additionalActions; QHash<int, Action *> m_additionalActions;
QHash<int, Action *> m_additionalAnnotActions; QHash<int, Action *> m_additionalAnnotActions;
Page *m_page = nullptr;
Q_DECLARE_PUBLIC(FormField) Q_DECLARE_PUBLIC(FormField)
FormField *q_ptr; FormField *q_ptr;

@ -712,6 +712,7 @@ void Page::setFormFields(const QLinkedList<FormField *> &fields)
d->formfields = fields; d->formfields = fields;
for (FormField *ff : qAsConst(d->formfields)) { for (FormField *ff : qAsConst(d->formfields)) {
ff->d_ptr->setDefault(); ff->d_ptr->setDefault();
ff->d_ptr->m_page = this;
} }
} }

@ -1586,7 +1586,7 @@ bool Part::openFile()
if (m_embedMode == PrintPreviewMode) { if (m_embedMode == PrintPreviewMode) {
m_signatureMessage->setText(i18n("All editing and interactive features for this document are disabled. Please save a copy and reopen to edit this document.")); m_signatureMessage->setText(i18n("All editing and interactive features for this document are disabled. Please save a copy and reopen to edit this document."));
} else { } else {
const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(m_document, true, 0); const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(m_document);
bool allSignaturesValid = true; bool allSignaturesValid = true;
for (const Okular::FormFieldSignature *signature : signatureFormFields) { for (const Okular::FormFieldSignature *signature : signatureFormFields) {
const Okular::SignatureInfo &info = signature->signatureInfo(); const Okular::SignatureInfo &info = signature->signatureInfo();

@ -14,10 +14,10 @@
namespace SignatureGuiUtils namespace SignatureGuiUtils
{ {
QVector<const Okular::FormFieldSignature *> getSignatureFormFields(Okular::Document *doc, bool allPages, int pageNum) QVector<const Okular::FormFieldSignature *> getSignatureFormFields(Okular::Document *doc)
{ {
uint curPage = allPages ? 0 : pageNum; uint curPage = 0;
const uint endPage = allPages ? doc->pages() - 1 : pageNum; const uint endPage = doc->pages() - 1;
QVector<const Okular::FormFieldSignature *> signatureFormFields; QVector<const Okular::FormFieldSignature *> signatureFormFields;
while (curPage <= endPage) { while (curPage <= endPage) {
const QLinkedList<Okular::FormField *> formFields = doc->page(curPage++)->formFields(); const QLinkedList<Okular::FormField *> formFields = doc->page(curPage++)->formFields();
@ -27,6 +27,11 @@ QVector<const Okular::FormFieldSignature *> getSignatureFormFields(Okular::Docum
} }
} }
} }
std::sort(signatureFormFields.begin(), signatureFormFields.end(), [](const Okular::FormFieldSignature *a, const Okular::FormFieldSignature *b) {
const Okular::SignatureInfo &infoA = a->signatureInfo();
const Okular::SignatureInfo &infoB = b->signatureInfo();
return infoA.signingTime() < infoB.signingTime();
});
return signatureFormFields; return signatureFormFields;
} }

@ -20,10 +20,9 @@ class FormFieldSignature;
namespace SignatureGuiUtils namespace SignatureGuiUtils
{ {
/** /**
* Returns a vector containing signature form fields. If @p allPages is true then all signature form fields in the * Returns a vector containing signature form fields sorted by date (last is newer).
* document are returned otherwise the fields in page number @p pageNum are returned.
*/ */
QVector<const Okular::FormFieldSignature *> getSignatureFormFields(Okular::Document *doc, bool allPages, int pageNum); QVector<const Okular::FormFieldSignature *> getSignatureFormFields(Okular::Document *doc);
QString getReadableSignatureStatus(Okular::SignatureInfo::SignatureStatus sigStatus); QString getReadableSignatureStatus(Okular::SignatureInfo::SignatureStatus sigStatus);
QString getReadableCertStatus(Okular::SignatureInfo::CertificateStatus certStatus); QString getReadableCertStatus(Okular::SignatureInfo::CertificateStatus certStatus);
QString getReadableHashAlgorithm(Okular::SignatureInfo::HashAlgorithm hashAlg); QString getReadableHashAlgorithm(Okular::SignatureInfo::HashAlgorithm hashAlg);

@ -117,36 +117,39 @@ void SignatureModelPrivate::notifySetup(const QVector<Okular::Page *> &pages, in
q->beginResetModel(); q->beginResetModel();
qDeleteAll(root->children); qDeleteAll(root->children);
root->children.clear(); root->children.clear();
for (const Okular::Page *page : pages) {
const int currentPage = page->number();
// get form fields page by page so that page number and index of the form can be determined.
const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(document, false, currentPage);
if (signatureFormFields.isEmpty())
continue;
for (int i = 0; i < signatureFormFields.count(); i++) {
const Okular::FormFieldSignature *sf = signatureFormFields[i];
const Okular::SignatureInfo &info = sf->signatureInfo();
// based on whether or not signature form is a nullptr it is decided if clicking on an item should change the viewport.
auto *parentItem = new SignatureItem(root, sf, SignatureItem::RevisionInfo, currentPage);
parentItem->displayString = i18n("Rev. %1: Signed By %2", i + 1, info.signerName());
auto childItem1 = new SignatureItem(parentItem, nullptr, SignatureItem::ValidityStatus, currentPage);
childItem1->displayString = SignatureGuiUtils::getReadableSignatureStatus(info.signatureStatus());
auto childItem2 = new SignatureItem(parentItem, nullptr, SignatureItem::SigningTime, currentPage);
childItem2->displayString = i18n("Signing Time: %1", info.signingTime().toString(Qt::DefaultLocaleLongDate));
const QString reason = info.reason();
if (!reason.isEmpty()) {
auto childItem3 = new SignatureItem(parentItem, nullptr, SignatureItem::Reason, currentPage);
childItem3->displayString = i18n("Reason: %1", reason);
}
auto childItem4 = new SignatureItem(parentItem, sf, SignatureItem::FieldInfo, currentPage); if (pages.isEmpty()) {
childItem4->displayString = i18n("Field: %1 on page %2", sf->name(), currentPage + 1); q->endResetModel();
return;
}
int revNumber = 1;
const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(document);
for (const Okular::FormFieldSignature *sf : signatureFormFields) {
const Okular::SignatureInfo &info = sf->signatureInfo();
const int pageNumber = sf->page()->number();
// based on whether or not signature form is a nullptr it is decided if clicking on an item should change the viewport.
auto *parentItem = new SignatureItem(root, sf, SignatureItem::RevisionInfo, pageNumber);
parentItem->displayString = i18n("Rev. %1: Signed By %2", revNumber, info.signerName());
auto childItem1 = new SignatureItem(parentItem, nullptr, SignatureItem::ValidityStatus, pageNumber);
childItem1->displayString = SignatureGuiUtils::getReadableSignatureStatus(info.signatureStatus());
auto childItem2 = new SignatureItem(parentItem, nullptr, SignatureItem::SigningTime, pageNumber);
childItem2->displayString = i18n("Signing Time: %1", info.signingTime().toString(Qt::DefaultLocaleLongDate));
const QString reason = info.reason();
if (!reason.isEmpty()) {
auto childItem3 = new SignatureItem(parentItem, nullptr, SignatureItem::Reason, pageNumber);
childItem3->displayString = i18n("Reason: %1", reason);
} }
auto childItem4 = new SignatureItem(parentItem, sf, SignatureItem::FieldInfo, pageNumber);
childItem4->displayString = i18n("Field: %1 on page %2", sf->name(), pageNumber + 1);
++revNumber;
} }
q->endResetModel(); q->endResetModel();
} }

@ -111,7 +111,7 @@ void SignaturePanel::notifySetup(const QVector<Okular::Page *> & /*pages*/, int
return; return;
Q_D(SignaturePanel); Q_D(SignaturePanel);
const QVector<const Okular::FormFieldSignature *> signatureForms = SignatureGuiUtils::getSignatureFormFields(d->m_document, true, -1); const QVector<const Okular::FormFieldSignature *> signatureForms = SignatureGuiUtils::getSignatureFormFields(d->m_document);
emit documentHasSignatures(!signatureForms.isEmpty()); emit documentHasSignatures(!signatureForms.isEmpty());
} }

@ -88,7 +88,7 @@ SignaturePropertiesDialog::SignaturePropertiesDialog(Okular::Document *doc, cons
if (signatureStatus != Okular::SignatureInfo::SignatureStatusUnknown && !signatureInfo.signsTotalDocument()) { if (signatureStatus != Okular::SignatureInfo::SignatureStatusUnknown && !signatureInfo.signsTotalDocument()) {
revisionBox = new QGroupBox(i18n("Document Version")); revisionBox = new QGroupBox(i18n("Document Version"));
auto revisionLayout = new QHBoxLayout(revisionBox); auto revisionLayout = new QHBoxLayout(revisionBox);
const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(m_doc, true, -1); const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(m_doc);
revisionLayout->addWidget(new QLabel(i18nc("Document Revision <current> of <total>", "Document Revision %1 of %2", signatureFormFields.indexOf(m_signatureForm) + 1, signatureFormFields.size()))); revisionLayout->addWidget(new QLabel(i18nc("Document Revision <current> of <total>", "Document Revision %1 of %2", signatureFormFields.indexOf(m_signatureForm) + 1, signatureFormFields.size())));
revisionLayout->addStretch(); revisionLayout->addStretch();
auto revisionBtn = new QPushButton(i18n("View Signed Version...")); auto revisionBtn = new QPushButton(i18n("View Signed Version..."));

Loading…
Cancel
Save