From 4b1d85f81bf0df1fdfc86e74ad71e9cf8201092f Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Thu, 30 Apr 2020 00:42:42 +0200 Subject: [PATCH] Show signatures that don't belong to any page in the signature panel Needs poppler 0.88, we "pretend" the belong to page 0 since in Okular core there's no concept of having a signature that doesn't belong to any page BUGS: 415199 --- generators/poppler/CMakeLists.txt | 10 +++ .../poppler/config-okular-poppler.h.cmake | 3 + generators/poppler/generator_pdf.cpp | 62 +++++++++++++++++-- generators/poppler/generator_pdf.h | 4 +- 4 files changed, 73 insertions(+), 6 deletions(-) diff --git a/generators/poppler/CMakeLists.txt b/generators/poppler/CMakeLists.txt index 259a7a6f6..d1d9cbadd 100644 --- a/generators/poppler/CMakeLists.txt +++ b/generators/poppler/CMakeLists.txt @@ -104,6 +104,16 @@ int main() } " HAVE_POPPLER_0_87) +check_cxx_source_compiles(" +#include +int main() +{ + Poppler::Document *d = nullptr; + d->signatures(); + return 0; +} +" HAVE_POPPLER_0_88) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config-okular-poppler.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-okular-poppler.h diff --git a/generators/poppler/config-okular-poppler.h.cmake b/generators/poppler/config-okular-poppler.h.cmake index 022623d37..2c81e8dc6 100644 --- a/generators/poppler/config-okular-poppler.h.cmake +++ b/generators/poppler/config-okular-poppler.h.cmake @@ -24,3 +24,6 @@ /* Defined if we have the 0.87 version of the Poppler library */ #cmakedefine HAVE_POPPLER_0_87 1 + +/* Defined if we have the 0.88 version of the Poppler library */ +#cmakedefine HAVE_POPPLER_0_88 1 diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp index 0786e6d39..166825f9a 100644 --- a/generators/poppler/generator_pdf.cpp +++ b/generators/poppler/generator_pdf.cpp @@ -771,7 +771,15 @@ void PDFGenerator::loadPages(QVector &pagesVector, int rotation, page->setDuration( p->duration() ); page->setLabel( p->label() ); - addFormFields( p, page ); + QLinkedList okularFormFields; +#ifdef HAVE_POPPLER_0_88 + if ( i > 0 ) // for page 0 we handle the form fields at the end + okularFormFields = getFormFields( p ); +#else + okularFormFields = getFormFields( p ); +#endif + if ( !okularFormFields.isEmpty() ) + page->setFormFields( okularFormFields ); // kWarning(PDFDebug).nospace() << page->width() << "x" << page->height(); #ifdef PDFGENERATOR_DEBUG @@ -789,6 +797,52 @@ void PDFGenerator::loadPages(QVector &pagesVector, int rotation, // set the Okular::page at the right position in document's pages vector pagesVector[i] = page; } + + // Once we've added the signatures to all pages except page 0, we add all the missing signatures there + // we do that because there's signatures that don't belong to any page, but okular needs a page<->signature mapping + if ( count > 0 ) + { +#ifdef HAVE_POPPLER_0_88 + const QVector allSignatures = pdfdoc->signatures(); + Poppler::Page * page0 = pdfdoc->page( 0 ); + QLinkedList page0FormFields = getFormFields( page0 ); + + for (Poppler::FormFieldSignature *s : allSignatures) + { + bool createSignature = true; + const QString fullyQualifiedName = s->fullyQualifiedName(); + auto compareSignatureByFullyQualifiedName = [&fullyQualifiedName](const Okular::FormField *off) { return off->fullyQualifiedName() == fullyQualifiedName; }; + + // See if the signature is in one of the already loaded page (i.e. 1 to end) + for (Okular::Page *p : pagesVector) + { + const QLinkedList pageFormFields = p->formFields(); + if (std::find_if(pageFormFields.begin(), pageFormFields.end(), compareSignatureByFullyQualifiedName) != pageFormFields.end()) + { + delete s; + createSignature = false; + continue; + } + } + // See if the signature is in page 0 + if (std::find_if(page0FormFields.constBegin(), page0FormFields.constEnd(), compareSignatureByFullyQualifiedName) != page0FormFields.constEnd()) + { + delete s; + createSignature = false; + } + // Otherwise it's a page-less signature, add it to page 0 + if (createSignature) + { + Okular::FormField * of = new PopplerFormFieldSignature( std::unique_ptr( s ) ); + page0FormFields.append( of ); + + } + } + + if ( !page0FormFields.isEmpty() ) + pagesVector[0]->setFormFields( page0FormFields ); +#endif + } } Okular::DocumentInfo PDFGenerator::generateDocumentInfo( const QSet &keys ) const @@ -1920,7 +1974,7 @@ void PDFGenerator::addTransition( Poppler::Page * pdfPage, Okular::Page * page ) page->setTransition( transition ); } -void PDFGenerator::addFormFields( Poppler::Page * popplerPage, Okular::Page * page ) +QLinkedList PDFGenerator::getFormFields( Poppler::Page * popplerPage ) { const QList popplerFormFields = popplerPage->formFields(); QLinkedList okularFormFields; @@ -1951,8 +2005,8 @@ void PDFGenerator::addFormFields( Poppler::Page * popplerPage, Okular::Page * pa // no form field available - delete the Poppler::FormField delete f; } - if ( !okularFormFields.isEmpty() ) - page->setFormFields( okularFormFields ); + + return okularFormFields; } PDFGenerator::PrintError PDFGenerator::printError() const diff --git a/generators/poppler/generator_pdf.h b/generators/poppler/generator_pdf.h index 2c08adce7..afb3c1f37 100644 --- a/generators/poppler/generator_pdf.h +++ b/generators/poppler/generator_pdf.h @@ -115,8 +115,8 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, p void addAnnotations( Poppler::Page * popplerPage, Okular::Page * page ); // fetch the transition information and add it to the page void addTransition( Poppler::Page * pdfPage, Okular::Page * page ); - // fetch the form fields and add them to the page - void addFormFields( Poppler::Page * popplerPage, Okular::Page * page ); + // fetch the poppler page form fields + QLinkedList getFormFields( Poppler::Page * popplerPage ); Okular::TextPage * abstractTextPage(const QList &text, double height, double width, int rot);