[poppler] poppler/PDFDoc.cc poppler/PDFDoc.h poppler/XRef.cc poppler/XRef.h qt5/demos qt5/src qt6/demos qt6/src
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri May 14 22:18:15 UTC 2021
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 <mahmoudkhalil11 at gmail.com>
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.
*/
More information about the poppler
mailing list