poppler/PDFDoc.cc | 20 ++++++++++---------- poppler/PDFDoc.h | 8 ++++---- poppler/XRef.cc | 8 +++++++- poppler/XRef.h | 5 ++++- qt5/demos/viewer.cpp | 21 +++++++++++++++++++++ qt5/demos/viewer.h | 2 ++ qt5/src/poppler-document.cc | 10 ++++++++++ qt5/src/poppler-private.cc | 13 +++++++++++++ qt5/src/poppler-private.h | 19 +++++++++++++++---- qt5/src/poppler-qt5.h | 17 +++++++++++++++++ qt6/demos/viewer.cpp | 21 +++++++++++++++++++++ qt6/demos/viewer.h | 2 ++ qt6/src/poppler-document.cc | 10 ++++++++++ qt6/src/poppler-private.cc | 13 +++++++++++++ qt6/src/poppler-private.h | 19 +++++++++++++++---- qt6/src/poppler-qt6.h | 17 +++++++++++++++++ 16 files changed, 181 insertions(+), 24 deletions(-)
New commits: commit 2254e62a7e2fe3a4144251e47c7578ce3b717bc9 Author: Mahmoud Khalil <[email protected]> Date: Wed Jan 27 21:14:57 2021 +0200 Provides the `wasReconstructed` value to caller Modifies the Poppler backend library to call a callback method submitted by callers in case a XRef reconstruction occurs, as well as, providing an API for setting the callback from the qt5/qt6 frontend so that users be able to set callback and check whether it has already happened or not. FIXES #416 diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index ca440ca1..56b929be 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -136,7 +136,7 @@ PDFDoc::PDFDoc() init(); } -PDFDoc::PDFDoc(const GooString *fileNameA, const GooString *ownerPassword, const GooString *userPassword, void *guiDataA) +PDFDoc::PDFDoc(const GooString *fileNameA, const GooString *ownerPassword, const GooString *userPassword, void *guiDataA, const std::function<void()> &xrefReconstructedCallback) { #ifdef _WIN32 int n, i; @@ -176,11 +176,11 @@ PDFDoc::PDFDoc(const GooString *fileNameA, const GooString *ownerPassword, const // create stream str = new FileStream(file, 0, false, file->size(), Object(objNull)); - ok = setup(ownerPassword, userPassword); + ok = setup(ownerPassword, userPassword, xrefReconstructedCallback); } #ifdef _WIN32 -PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, GooString *userPassword, void *guiDataA) +PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, GooString *userPassword, void *guiDataA, const std::function<void()> &xrefReconstructedCallback) { OSVERSIONINFO version; int i; @@ -217,11 +217,11 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, Go // create stream str = new FileStream(file, 0, false, file->size(), Object(objNull)); - ok = setup(ownerPassword, userPassword); + ok = setup(ownerPassword, userPassword, xrefReconstructedCallback); } #endif -PDFDoc::PDFDoc(BaseStream *strA, const GooString *ownerPassword, const GooString *userPassword, void *guiDataA) +PDFDoc::PDFDoc(BaseStream *strA, const GooString *ownerPassword, const GooString *userPassword, void *guiDataA, const std::function<void()> &xrefReconstructedCallback) { #ifdef _WIN32 int n, i; @@ -246,10 +246,10 @@ PDFDoc::PDFDoc(BaseStream *strA, const GooString *ownerPassword, const GooString #endif } str = strA; - ok = setup(ownerPassword, userPassword); + ok = setup(ownerPassword, userPassword, xrefReconstructedCallback); } -bool PDFDoc::setup(const GooString *ownerPassword, const GooString *userPassword) +bool PDFDoc::setup(const GooString *ownerPassword, const GooString *userPassword, const std::function<void()> &xrefReconstructedCallback) { pdfdocLocker(); @@ -278,12 +278,12 @@ bool PDFDoc::setup(const GooString *ownerPassword, const GooString *userPassword bool wasReconstructed = false; // read xref table - xref = new XRef(str, getStartXRef(), getMainXRefEntriesOffset(), &wasReconstructed); + xref = new XRef(str, getStartXRef(), getMainXRefEntriesOffset(), &wasReconstructed, false, xrefReconstructedCallback); if (!xref->isOk()) { if (wasReconstructed) { delete xref; startXRefPos = -1; - xref = new XRef(str, getStartXRef(true), getMainXRefEntriesOffset(true), &wasReconstructed); + xref = new XRef(str, getStartXRef(true), getMainXRefEntriesOffset(true), &wasReconstructed, false, xrefReconstructedCallback); } if (!xref->isOk()) { error(errSyntaxError, -1, "Couldn't read xref table"); @@ -305,7 +305,7 @@ bool PDFDoc::setup(const GooString *ownerPassword, const GooString *userPassword // try one more time to construct the Catalog, maybe the problem is damaged XRef delete catalog; delete xref; - xref = new XRef(str, 0, 0, nullptr, true); + xref = new XRef(str, 0, 0, nullptr, true, xrefReconstructedCallback); catalog = new Catalog(this); } diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index a9ce2bd3..2cd4b35d 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -121,13 +121,13 @@ enum PDFSubtypeConformance class POPPLER_PRIVATE_EXPORT PDFDoc { public: - PDFDoc(const GooString *fileNameA, const GooString *ownerPassword = nullptr, const GooString *userPassword = nullptr, void *guiDataA = nullptr); + PDFDoc(const GooString *fileNameA, const GooString *ownerPassword = nullptr, const GooString *userPassword = nullptr, void *guiDataA = nullptr, const std::function<void()> &xrefReconstructedCallback = {}); #ifdef _WIN32 - PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword = nullptr, GooString *userPassword = nullptr, void *guiDataA = nullptr); + PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword = nullptr, GooString *userPassword = nullptr, void *guiDataA = nullptr, const std::function<void()> &xrefReconstructedCallback = {}); #endif - PDFDoc(BaseStream *strA, const GooString *ownerPassword = nullptr, const GooString *userPassword = nullptr, void *guiDataA = nullptr); + PDFDoc(BaseStream *strA, const GooString *ownerPassword = nullptr, const GooString *userPassword = nullptr, void *guiDataA = nullptr, const std::function<void()> &xrefReconstructedCallback = {}); ~PDFDoc(); PDFDoc(const PDFDoc &) = delete; @@ -344,7 +344,7 @@ private: PDFDoc(); void init(); - bool setup(const GooString *ownerPassword, const GooString *userPassword); + bool setup(const GooString *ownerPassword, const GooString *userPassword, const std::function<void()> &xrefReconstructedCallback); bool checkFooter(); void checkHeader(); bool checkEncryption(const GooString *ownerPassword, const GooString *userPassword); diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 77a6752f..c7a509fb 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -258,12 +258,14 @@ XRef::XRef(const Object *trailerDictA) : XRef {} trailerDict = trailerDictA->copy(); } -XRef::XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA, bool *wasReconstructed, bool reconstruct) : XRef {} +XRef::XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA, bool *wasReconstructed, bool reconstruct, const std::function<void()> &xrefReconstructedCallback) : XRef {} { Object obj; mainXRefEntriesOffset = mainXRefEntriesOffsetA; + xrefReconstructedCb = xrefReconstructedCallback; + // read the trailer str = strA; start = str->getStart(); @@ -864,6 +866,10 @@ bool XRef::constructXRef(bool *wasReconstructed, bool needCatalogDict) *wasReconstructed = true; } + if (xrefReconstructedCb) { + xrefReconstructedCb(); + } + str->reset(); while (true) { pos = str->getPos(); diff --git a/poppler/XRef.h b/poppler/XRef.h index 1b050f8e..2b30b509 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -34,6 +34,8 @@ #ifndef XREF_H #define XREF_H +#include <functional> + #include "poppler-config.h" #include "poppler_private_export.h" #include "Object.h" @@ -101,7 +103,7 @@ public: // Constructor, create an empty XRef but with info dict, used for PDF writing XRef(const Object *trailerDictA); // Constructor. Read xref table from stream. - XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA = 0, bool *wasReconstructed = nullptr, bool reconstruct = false); + XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA = 0, bool *wasReconstructed = nullptr, bool reconstruct = false, const std::function<void()> &xrefReconstructedCallback = {}); // Destructor. ~XRef(); @@ -247,6 +249,7 @@ private: bool scannedSpecialFlags; // true if scanSpecialFlags has been called bool strOwner; // true if str is owned by the instance mutable std::recursive_mutex mutex; + std::function<void()> xrefReconstructedCb; int reserve(int newSize); int resize(int newSize); diff --git a/qt5/demos/viewer.cpp b/qt5/demos/viewer.cpp index 0b1a8f0e..72c83f64 100644 --- a/qt5/demos/viewer.cpp +++ b/qt5/demos/viewer.cpp @@ -44,6 +44,8 @@ #include <QtWidgets/QMenuBar> #include <QtWidgets/QMessageBox> +#include <functional> + PdfViewer::PdfViewer(QWidget *parent) : QMainWindow(parent), m_currentPage(0), m_doc(nullptr) { setWindowTitle(tr("Poppler-Qt5 Demo")); @@ -172,6 +174,8 @@ QSize PdfViewer::sizeHint() const void PdfViewer::loadDocument(const QString &file) { + // resetting xrefReconstructed each time we load new document + xrefReconstructed = false; Poppler::Document *newdoc = Poppler::Document::load(file); if (!newdoc) { QMessageBox msgbox(QMessageBox::Critical, tr("Open Error"), tr("Cannot open:\n") + file, QMessageBox::Ok, this); @@ -196,6 +200,13 @@ void PdfViewer::loadDocument(const QString &file) m_doc->setRenderHint(Poppler::Document::TextAntialiasing, m_settingsTextAAAct->isChecked()); m_doc->setRenderHint(Poppler::Document::Antialiasing, m_settingsGfxAAAct->isChecked()); m_doc->setRenderBackend((Poppler::Document::RenderBackend)m_settingsRenderBackendGrp->checkedAction()->data().toInt()); + if (m_doc->xrefWasReconstructed()) { + xrefReconstructedHandler(m_doc); + } else { + std::function<void()> cb = [this]() { xrefReconstructedHandler(m_doc); }; + + m_doc->setXRefReconstructedCallback(cb); + } Q_FOREACH (DocumentObserver *obs, m_observers) { obs->documentLoaded(); @@ -222,6 +233,16 @@ void PdfViewer::closeDocument() m_fileSaveCopyAct->setEnabled(false); } +void PdfViewer::xrefReconstructedHandler(Poppler::Document *doc) +{ + if (!xrefReconstructed) { + QMessageBox msgbox(QMessageBox::Critical, tr("File may be corrupted"), tr("The PDF may be broken but we're still showing something, contents may not be correct"), QMessageBox::Ok, this); + msgbox.exec(); + + xrefReconstructed = true; + } +} + void PdfViewer::slotOpenFile() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open PDF Document"), QDir::homePath(), tr("PDF Documents (*.pdf)")); diff --git a/qt5/demos/viewer.h b/qt5/demos/viewer.h index 105b1bbe..3e3d422d 100644 --- a/qt5/demos/viewer.h +++ b/qt5/demos/viewer.h @@ -56,8 +56,10 @@ private Q_SLOTS: private: void setPage(int page); int page() const; + void xrefReconstructedHandler(Poppler::Document *doc); int m_currentPage; + bool xrefReconstructed; QAction *m_fileOpenAct; QAction *m_fileSaveCopyAct; diff --git a/qt5/src/poppler-document.cc b/qt5/src/poppler-document.cc index 762eba9f..74dbd959 100644 --- a/qt5/src/poppler-document.cc +++ b/qt5/src/poppler-document.cc @@ -833,6 +833,16 @@ QVector<FormFieldSignature *> Document::signatures() const return result; } +bool Document::xrefWasReconstructed() const +{ + return m_doc->xrefReconstructed; +} + +void Document::setXRefReconstructedCallback(const std::function<void()> &callback) +{ + m_doc->xrefReconstructedCallback = callback; +} + QDateTime convertDate(const char *dateString) { int year, mon, day, hour, min, sec, tzHours, tzMins; diff --git a/qt5/src/poppler-private.cc b/qt5/src/poppler-private.cc index 695b9b8c..4896c29d 100644 --- a/qt5/src/poppler-private.cc +++ b/qt5/src/poppler-private.cc @@ -250,6 +250,8 @@ void DocumentData::init() paperColor = Qt::white; m_hints = 0; m_optContentModel = nullptr; + xrefReconstructed = false; + xrefReconstructedCallback = {}; } void DocumentData::addTocChildren(QDomDocument *docSyn, QDomNode *parent, const std::vector<::OutlineItem *> *items) @@ -282,6 +284,17 @@ void DocumentData::addTocChildren(QDomDocument *docSyn, QDomNode *parent, const } } +void DocumentData::noitfyXRefReconstructed() +{ + if (!xrefReconstructed) { + xrefReconstructed = true; + } + + if (xrefReconstructedCallback) { + xrefReconstructedCallback(); + } +} + FormWidget *FormFieldData::getFormWidget(const FormField *f) { return f->m_formData->fm; diff --git a/qt5/src/poppler-private.h b/qt5/src/poppler-private.h index 3d503321..11302dd0 100644 --- a/qt5/src/poppler-private.h +++ b/qt5/src/poppler-private.h @@ -45,6 +45,7 @@ #include <QtCore/QPointer> #include <QtCore/QVector> +#include <functional> #include <config.h> #include <poppler-config.h> #include <GfxState.h> @@ -106,10 +107,10 @@ public: m_filePath = filePath; #ifdef _WIN32 - doc = new PDFDoc((wchar_t *)filePath.utf16(), filePath.length(), ownerPassword, userPassword); + doc = new PDFDoc((wchar_t *)filePath.utf16(), filePath.length(), ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); #else GooString *fileName = new GooString(QFile::encodeName(filePath).constData()); - doc = new PDFDoc(fileName, ownerPassword, userPassword); + doc = new PDFDoc(fileName, ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); #endif delete ownerPassword; @@ -121,7 +122,7 @@ public: m_device = device; QIODeviceInStream *str = new QIODeviceInStream(device, 0, false, device->size(), Object(objNull)); init(); - doc = new PDFDoc(str, ownerPassword, userPassword); + doc = new PDFDoc(str, ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); delete ownerPassword; delete userPassword; } @@ -132,7 +133,7 @@ public: fileContents = data; MemStream *str = new MemStream((char *)fileContents.data(), 0, fileContents.length(), Object(objNull)); init(); - doc = new PDFDoc(str, ownerPassword, userPassword); + doc = new PDFDoc(str, ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); delete ownerPassword; delete userPassword; } @@ -160,6 +161,13 @@ public: } } + /** + * a method that is being called whenever PDFDoc's XRef is reconstructed + * where we'll set xrefReconstructed flag and notify users of the + * reconstruction event + */ + void noitfyXRefReconstructed(); + static Document *checkDocument(DocumentData *doc); PDFDoc *doc; @@ -176,6 +184,9 @@ public: GfxLCMSProfilePtr m_sRGBProfile; GfxLCMSProfilePtr m_displayProfile; #endif + bool xrefReconstructed; + // notifies the user whenever the backend's PDFDoc XRef is reconstructed + std::function<void()> xrefReconstructedCallback; }; class FontInfoData diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h index 56bab8a2..5a375d6b 100644 --- a/qt5/src/poppler-qt5.h +++ b/qt5/src/poppler-qt5.h @@ -45,6 +45,8 @@ #ifndef __POPPLER_QT_H__ #define __POPPLER_QT_H__ +#include <functional> + #include "poppler-annotation.h" #include "poppler-link.h" #include "poppler-optcontent.h" @@ -1888,6 +1890,21 @@ QString subject = m_doc->info("Subject"); */ QVector<FormFieldSignature *> signatures() const; + /** + Returns whether the document's XRef table has been reconstructed or not + + \since 21.06 + */ + bool xrefWasReconstructed() const; + + /** + Sets the document's XRef reconstruction callback, so whenever a XRef table + reconstruction happens the callback will get triggered. + + \since 21.06 + */ + void setXRefReconstructedCallback(const std::function<void()> &callback); + /** Destructor. */ diff --git a/qt6/demos/viewer.cpp b/qt6/demos/viewer.cpp index f1cfc852..7e5dedef 100644 --- a/qt6/demos/viewer.cpp +++ b/qt6/demos/viewer.cpp @@ -45,6 +45,8 @@ #include <QMenuBar> #include <QMessageBox> +#include <functional> + PdfViewer::PdfViewer(QWidget *parent) : QMainWindow(parent), m_currentPage(0), m_doc(nullptr) { setWindowTitle(tr("Poppler-Qt6 Demo")); @@ -168,6 +170,8 @@ QSize PdfViewer::sizeHint() const void PdfViewer::loadDocument(const QString &file) { + // resetting xrefReconstructed each time we load new document + xrefReconstructed = false; Poppler::Document *newdoc = Poppler::Document::load(file); if (!newdoc) { QMessageBox msgbox(QMessageBox::Critical, tr("Open Error"), tr("Cannot open:\n") + file, QMessageBox::Ok, this); @@ -192,6 +196,13 @@ void PdfViewer::loadDocument(const QString &file) m_doc->setRenderHint(Poppler::Document::TextAntialiasing, m_settingsTextAAAct->isChecked()); m_doc->setRenderHint(Poppler::Document::Antialiasing, m_settingsGfxAAAct->isChecked()); m_doc->setRenderBackend((Poppler::Document::RenderBackend)m_settingsRenderBackendGrp->checkedAction()->data().toInt()); + if (m_doc->xrefWasReconstructed()) { + xrefReconstructedHandler(m_doc); + } else { + std::function<void()> cb = [this]() { xrefReconstructedHandler(m_doc); }; + + m_doc->setXRefReconstructedCallback(cb); + } Q_FOREACH (DocumentObserver *obs, m_observers) { obs->documentLoaded(); @@ -218,6 +229,16 @@ void PdfViewer::closeDocument() m_fileSaveCopyAct->setEnabled(false); } +void PdfViewer::xrefReconstructedHandler(Poppler::Document *doc) +{ + if (!xrefReconstructed) { + QMessageBox msgbox(QMessageBox::Critical, tr("File may be corrupted"), tr("The PDF may be broken but we're still showing something, contents may not be correct"), QMessageBox::Ok, this); + msgbox.exec(); + + xrefReconstructed = true; + } +} + void PdfViewer::slotOpenFile() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open PDF Document"), QDir::homePath(), tr("PDF Documents (*.pdf)")); diff --git a/qt6/demos/viewer.h b/qt6/demos/viewer.h index 105b1bbe..3e3d422d 100644 --- a/qt6/demos/viewer.h +++ b/qt6/demos/viewer.h @@ -56,8 +56,10 @@ private Q_SLOTS: private: void setPage(int page); int page() const; + void xrefReconstructedHandler(Poppler::Document *doc); int m_currentPage; + bool xrefReconstructed; QAction *m_fileOpenAct; QAction *m_fileSaveCopyAct; diff --git a/qt6/src/poppler-document.cc b/qt6/src/poppler-document.cc index 8aaa0e79..d53269dd 100644 --- a/qt6/src/poppler-document.cc +++ b/qt6/src/poppler-document.cc @@ -815,6 +815,16 @@ QVector<FormFieldSignature *> Document::signatures() const return result; } +bool Document::xrefWasReconstructed() const +{ + return m_doc->xrefReconstructed; +} + +void Document::setXRefReconstructedCallback(const std::function<void()> &callback) +{ + m_doc->xrefReconstructedCallback = callback; +} + QDateTime convertDate(const char *dateString) { int year, mon, day, hour, min, sec, tzHours, tzMins; diff --git a/qt6/src/poppler-private.cc b/qt6/src/poppler-private.cc index a2971adc..01ae79e5 100644 --- a/qt6/src/poppler-private.cc +++ b/qt6/src/poppler-private.cc @@ -193,6 +193,19 @@ void DocumentData::init() paperColor = Qt::white; m_hints = 0; m_optContentModel = nullptr; + xrefReconstructed = false; + xrefReconstructedCallback = {}; +} + +void DocumentData::noitfyXRefReconstructed() +{ + if (!xrefReconstructed) { + xrefReconstructed = true; + } + + if (xrefReconstructedCallback) { + xrefReconstructedCallback(); + } } FormWidget *FormFieldData::getFormWidget(const FormField *f) diff --git a/qt6/src/poppler-private.h b/qt6/src/poppler-private.h index e1cff9c6..5ee724aa 100644 --- a/qt6/src/poppler-private.h +++ b/qt6/src/poppler-private.h @@ -45,6 +45,7 @@ #include <QtCore/QPointer> #include <QtCore/QVector> +#include <functional> #include <config.h> #include <poppler-config.h> #include <GfxState.h> @@ -106,10 +107,10 @@ public: m_filePath = filePath; #ifdef _WIN32 - doc = new PDFDoc((wchar_t *)filePath.utf16(), filePath.length(), ownerPassword, userPassword); + doc = new PDFDoc((wchar_t *)filePath.utf16(), filePath.length(), ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); #else GooString *fileName = new GooString(QFile::encodeName(filePath).constData()); - doc = new PDFDoc(fileName, ownerPassword, userPassword); + doc = new PDFDoc(fileName, ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); #endif delete ownerPassword; @@ -121,7 +122,7 @@ public: m_device = device; QIODeviceInStream *str = new QIODeviceInStream(device, 0, false, device->size(), Object(objNull)); init(); - doc = new PDFDoc(str, ownerPassword, userPassword); + doc = new PDFDoc(str, ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); delete ownerPassword; delete userPassword; } @@ -132,7 +133,7 @@ public: fileContents = data; MemStream *str = new MemStream((char *)fileContents.data(), 0, fileContents.length(), Object(objNull)); init(); - doc = new PDFDoc(str, ownerPassword, userPassword); + doc = new PDFDoc(str, ownerPassword, userPassword, nullptr, std::bind(&DocumentData::noitfyXRefReconstructed, this)); delete ownerPassword; delete userPassword; } @@ -158,6 +159,13 @@ public: } } + /** + * a method that is being called whenever PDFDoc's XRef is reconstructed + * where we'll set xrefReconstructed flag and notify users of the + * reconstruction event + */ + void noitfyXRefReconstructed(); + static Document *checkDocument(DocumentData *doc); PDFDoc *doc; @@ -174,6 +182,9 @@ public: GfxLCMSProfilePtr m_sRGBProfile; GfxLCMSProfilePtr m_displayProfile; #endif + bool xrefReconstructed; + // notifies the user whenever the backend's PDFDoc XRef is reconstructed + std::function<void()> xrefReconstructedCallback; }; class FontInfoData diff --git a/qt6/src/poppler-qt6.h b/qt6/src/poppler-qt6.h index dbef56ae..565c2c19 100644 --- a/qt6/src/poppler-qt6.h +++ b/qt6/src/poppler-qt6.h @@ -45,6 +45,8 @@ #ifndef __POPPLER_QT_H__ #define __POPPLER_QT_H__ +#include <functional> + #include "poppler-annotation.h" #include "poppler-link.h" #include "poppler-optcontent.h" @@ -1723,6 +1725,21 @@ QString subject = m_doc->info("Subject"); */ QVector<FormFieldSignature *> signatures() const; + /** + Returns whether the document's XRef table has been reconstructed or not + + \since 21.06 + */ + bool xrefWasReconstructed() const; + + /** + Sets the document's XRef reconstruction callback, so whenever a XRef table + reconstruction happens the callback will get triggered. + + \since 21.06 + */ + void setXRefReconstructedCallback(const std::function<void()> &callback); + /** Destructor. */ _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
