Commit 44c86de7 authored by Albert Astals Cid's avatar Albert Astals Cid
Browse files

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
parent 8a09492a
Pipeline #118126 passed with stage
in 27 minutes and 15 seconds
......@@ -115,6 +115,12 @@ void FormField::setAdditionalAction(Annotation::AdditionalActionType type, Actio
d->m_additionalAnnotActions[type] = action;
}
Page *FormField::page() const
{
Q_D(const FormField);
return d->m_page;
}
class Okular::FormFieldButtonPrivate : public Okular::FormFieldPrivate
{
public:
......
......@@ -157,6 +157,13 @@ public:
*/
Action *additionalAction(Annotation::AdditionalActionType type) const;
/**
* Returns the page of this form field
*
* @since 21.12.2
*/
Page *page() const;
protected:
/// @cond PRIVATE
explicit FormField(FormFieldPrivate &dd);
......
......@@ -35,6 +35,7 @@ public:
Action *m_activateAction;
QHash<int, Action *> m_additionalActions;
QHash<int, Action *> m_additionalAnnotActions;
Page *m_page = nullptr;
Q_DECLARE_PUBLIC(FormField)
FormField *q_ptr;
......
......@@ -712,6 +712,7 @@ void Page::setFormFields(const QLinkedList<FormField *> &fields)
d->formfields = fields;
for (FormField *ff : qAsConst(d->formfields)) {
ff->d_ptr->setDefault();
ff->d_ptr->m_page = this;
}
}
......
......@@ -1586,7 +1586,7 @@ bool Part::openFile()
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."));
} 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;
for (const Okular::FormFieldSignature *signature : signatureFormFields) {
const Okular::SignatureInfo &info = signature->signatureInfo();
......
......@@ -14,10 +14,10 @@
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;
const uint endPage = allPages ? doc->pages() - 1 : pageNum;
uint curPage = 0;
const uint endPage = doc->pages() - 1;
QVector<const Okular::FormFieldSignature *> signatureFormFields;
while (curPage <= endPage) {
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;
}
......
......@@ -20,10 +20,9 @@ class FormFieldSignature;
namespace SignatureGuiUtils
{
/**
* Returns a vector containing signature form fields. If @p allPages is true then all signature form fields in the
* document are returned otherwise the fields in page number @p pageNum are returned.
* Returns a vector containing signature form fields sorted by date (last is newer).
*/
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 getReadableCertStatus(Okular::SignatureInfo::CertificateStatus certStatus);
QString getReadableHashAlgorithm(Okular::SignatureInfo::HashAlgorithm hashAlg);
......
......@@ -117,36 +117,39 @@ void SignatureModelPrivate::notifySetup(const QVector<Okular::Page *> &pages, in
q->beginResetModel();
qDeleteAll(root->children);
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);
childItem4->displayString = i18n("Field: %1 on page %2", sf->name(), currentPage + 1);
if (pages.isEmpty()) {
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();
}
......
......@@ -111,7 +111,7 @@ void SignaturePanel::notifySetup(const QVector<Okular::Page *> & /*pages*/, int
return;
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());
}
......
......@@ -88,7 +88,7 @@ SignaturePropertiesDialog::SignaturePropertiesDialog(Okular::Document *doc, cons
if (signatureStatus != Okular::SignatureInfo::SignatureStatusUnknown && !signatureInfo.signsTotalDocument()) {
revisionBox = new QGroupBox(i18n("Document Version"));
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->addStretch();
auto revisionBtn = new QPushButton(i18n("View Signed Version..."));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment