summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-01-10 07:47:52 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2022-03-03 06:05:18 +0100
commit7b8832ca2b84d549c9d374550c3c46b3d4d42a38 (patch)
tree47eed7bcd915b7db53d06e8cef749cf6df913609
parentaf190c9d05d2a5afc2de4dd9b2172fec8e4ce3b7 (diff)
Add QQuickPdfPageImage and use in the PDF viewer components
Image works fine, except that if QPdfIOHandler is not given an already-allocated QPdfDocument instance, it needs to construct its own. So we now have QPdfFile: a subclass of QFile acting as a wrapper, to carry the document instance (that the user has most likely declared) down into QPdfIOHandler::load(QIODevice *). Thus, in nontrivial PDF-viewing use cases, there is now usually only one multi-purpose document instance. And this takes care of viewing password-protected PDFs in the multipage example, because we already prompt for it and set the document.password property. In trivial use cases, it's OK to continue using Image, and QPdfIOHandler will still construct its own QPdfDocument instance if the QIODevice cannot be cast to a QPdfFile. Task-number: QTBUG-77506 Task-number: QTBUG-83988 Task-number: QTBUG-96574 Change-Id: I3adfa54c30b0baa5dedebcf3bc759758f136b757 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/pdf/CMakeLists.txt1
-rw-r--r--src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp35
-rw-r--r--src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h4
-rw-r--r--src/pdf/qpdfdocument.cpp8
-rw-r--r--src/pdf/qpdfdocument.h3
-rw-r--r--src/pdf/qpdffile.cpp61
-rw-r--r--src/pdf/qpdffile_p.h70
-rw-r--r--src/pdfquick/CMakeLists.txt1
-rw-r--r--src/pdfquick/PdfMultiPageView.qml10
-rw-r--r--src/pdfquick/PdfPageView.qml6
-rw-r--r--src/pdfquick/PdfScrollablePageView.qml6
-rw-r--r--src/pdfquick/qquickpdfdocument.cpp13
-rw-r--r--src/pdfquick/qquickpdfdocument_p.h5
-rw-r--r--src/pdfquick/qquickpdfpageimage.cpp155
-rw-r--r--src/pdfquick/qquickpdfpageimage_p.h89
15 files changed, 446 insertions, 21 deletions
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
index b572b3155..14474caf2 100644
--- a/src/pdf/CMakeLists.txt
+++ b/src/pdf/CMakeLists.txt
@@ -18,6 +18,7 @@ qt_internal_add_module(Pdf
qpdfdestination.cpp qpdfdestination.h qpdfdestination_p.h
qpdfdocument.cpp qpdfdocument.h qpdfdocument_p.h
qpdfdocumentrenderoptions.h
+ qpdffile.cpp qpdffile_p.h
qpdflinkmodel.cpp qpdflinkmodel_p.h qpdflinkmodel_p_p.h
qpdfpagenavigation.cpp qpdfpagenavigation.h
qpdfpagerenderer.cpp qpdfpagerenderer.h
diff --git a/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
index ecf2846ac..5dee51b70 100644
--- a/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
+++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
@@ -40,6 +40,7 @@
#include "qpdfiohandler_p.h"
#include <QLoggingCategory>
#include <QPainter>
+#include <QtPdf/private/qpdffile_p.h>
QT_BEGIN_NAMESPACE
@@ -49,6 +50,12 @@ QPdfIOHandler::QPdfIOHandler()
{
}
+QPdfIOHandler::~QPdfIOHandler()
+{
+ if (m_ownsDocument)
+ delete m_doc;
+}
+
bool QPdfIOHandler::canRead() const
{
if (!device())
@@ -76,14 +83,14 @@ int QPdfIOHandler::currentImageNumber() const
QRect QPdfIOHandler::currentImageRect() const
{
- return QRect(QPoint(0, 0), m_doc.pageSize(m_page).toSize());
+ return QRect(QPoint(0, 0), m_doc->pageSize(m_page).toSize());
}
int QPdfIOHandler::imageCount() const
{
int ret = 0;
if (const_cast<QPdfIOHandler *>(this)->load(device()))
- ret = m_doc.pageCount();
+ ret = m_doc->pageCount();
qCDebug(qLcPdf) << ret;
return ret;
}
@@ -91,12 +98,12 @@ int QPdfIOHandler::imageCount() const
bool QPdfIOHandler::read(QImage *image)
{
if (load(device())) {
- if (m_page >= m_doc.pageCount())
+ if (m_page >= m_doc->pageCount())
return false;
if (m_page < 0)
m_page = 0;
const bool xform = (m_clipRect.isValid() || m_scaledSize.isValid() || m_scaledClipRect.isValid());
- QSize pageSize = m_doc.pageSize(m_page).toSize();
+ QSize pageSize = m_doc->pageSize(m_page).toSize();
QSize finalSize = pageSize;
QRectF bounds;
if (xform && !finalSize.isEmpty()) {
@@ -139,7 +146,7 @@ bool QPdfIOHandler::read(QImage *image)
options.setScaledSize(pageSize);
image->fill(m_backColor.rgba());
QPainter p(image);
- QImage pageImage = m_doc.render(m_page, finalSize, options);
+ QImage pageImage = m_doc->render(m_page, finalSize, options);
p.drawImage(0, 0, pageImage);
p.end();
}
@@ -156,7 +163,7 @@ QVariant QPdfIOHandler::option(ImageOption option) const
return QImage::Format_ARGB32_Premultiplied;
case Size:
const_cast<QPdfIOHandler *>(this)->load(device());
- return m_doc.pageSize(qMax(0, m_page));
+ return m_doc->pageSize(qMax(0, m_page));
case ClipRect:
return m_clipRect;
case ScaledSize:
@@ -166,7 +173,7 @@ QVariant QPdfIOHandler::option(ImageOption option) const
case BackgroundColor:
return m_backColor;
case Name:
- return m_doc.metaData(QPdfDocument::Title);
+ return m_doc->metaData(QPdfDocument::Title);
default:
break;
}
@@ -233,8 +240,18 @@ bool QPdfIOHandler::load(QIODevice *device)
if (!canRead())
return false;
- m_doc.load(device);
- m_loaded = (m_doc.error() == QPdfDocument::DocumentError::NoError);
+ QPdfFile *pdfFile = qobject_cast<QPdfFile *>(device);
+ if (pdfFile) {
+ m_doc = pdfFile->document();
+ m_ownsDocument = false;
+ qCDebug(qLcPdf) << "loading via QPdfFile, reusing document instance" << m_doc;
+ } else {
+ m_doc = new QPdfDocument();
+ m_ownsDocument = true;
+ m_doc->load(device);
+ qCDebug(qLcPdf) << "loading via new document instance" << m_doc;
+ }
+ m_loaded = (m_doc->error() == QPdfDocument::DocumentError::NoError);
return m_loaded;
}
diff --git a/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
index 562909f06..23d038757 100644
--- a/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
+++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
@@ -60,6 +60,7 @@ class QPdfIOHandler : public QImageIOHandler
{
public:
QPdfIOHandler();
+ virtual ~QPdfIOHandler();
bool canRead() const override;
static bool canRead(QIODevice *device);
int currentImageNumber() const override;
@@ -76,7 +77,7 @@ private:
bool load(QIODevice *device);
private:
- QPdfDocument m_doc;
+ QPdfDocument *m_doc = nullptr;
int m_page = -1;
QRect m_clipRect;
@@ -84,6 +85,7 @@ private:
QRect m_scaledClipRect;
QColor m_backColor = Qt::transparent;
bool m_loaded = false;
+ bool m_ownsDocument = false;
};
QT_END_NAMESPACE
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index 5a6dca99b..f442c1ebf 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -497,6 +497,14 @@ QPdfDocument::DocumentError QPdfDocument::load(const QString &fileName)
return d->lastError;
}
+QString QPdfDocument::fileName() const
+{
+ const QFile *f = qobject_cast<QFile *>(d->device.data());
+ if (f)
+ return f->fileName();
+ return QString();
+}
+
/*!
\enum QPdfDocument::Status
diff --git a/src/pdf/qpdfdocument.h b/src/pdf/qpdfdocument.h
index 9a81d4a8c..52dd7ac5a 100644
--- a/src/pdf/qpdfdocument.h
+++ b/src/pdf/qpdfdocument.h
@@ -129,11 +129,14 @@ Q_SIGNALS:
private:
friend class QPdfBookmarkModelPrivate;
+ friend class QPdfFile;
friend class QPdfLinkModelPrivate;
friend class QPdfSearchModel;
friend class QPdfSearchModelPrivate;
friend class QQuickPdfSelection;
+ QString fileName() const;
+
Q_PRIVATE_SLOT(d, void _q_tryLoadingWithSizeFromContentHeader())
Q_PRIVATE_SLOT(d, void _q_copyFromSequentialSourceDevice())
QScopedPointer<QPdfDocumentPrivate> d;
diff --git a/src/pdf/qpdffile.cpp b/src/pdf/qpdffile.cpp
new file mode 100644
index 000000000..d36095fd6
--- /dev/null
+++ b/src/pdf/qpdffile.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpdffile_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QPdfFile
+ \inmodule QtPdf
+
+ QPdfFile is a means of passing a PDF file along with the associated
+ QPdfDocument together into QPdfIOHandler::load(QIODevice *device) so that
+ QPdfIOHandler does not need to construct its own redundant QPdfDocument
+ instance. If it succeeds in casting the QIODevice to a QPdfFile, it is
+ expected to use the QPdfDocument operations for all I/O, and thus the
+ normal QFile I/O functions are not needed for that use case.
+*/
+
+QPdfFile::QPdfFile(QPdfDocument *doc)
+ : QFile(doc->fileName()), m_document(doc)
+{
+}
+
+QT_END_NAMESPACE
+
+//#include "moc_qpdffile_p.cpp"
diff --git a/src/pdf/qpdffile_p.h b/src/pdf/qpdffile_p.h
new file mode 100644
index 000000000..277fbf29b
--- /dev/null
+++ b/src/pdf/qpdffile_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPDFFILE_P_H
+#define QPDFFILE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpdfdocument.h"
+
+#include <QtCore/qfile.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_PDF_EXPORT QPdfFile : public QFile
+{
+ Q_OBJECT
+public:
+ QPdfFile(QPdfDocument *doc);
+ QPdfDocument *document() { return m_document; }
+
+private:
+ QPdfDocument *m_document;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFFILE_P_H
diff --git a/src/pdfquick/CMakeLists.txt b/src/pdfquick/CMakeLists.txt
index 19520d2da..1e58120da 100644
--- a/src/pdfquick/CMakeLists.txt
+++ b/src/pdfquick/CMakeLists.txt
@@ -20,6 +20,7 @@ qt_internal_add_qml_module(PdfQuick
qquickpdfdocument.cpp qquickpdfdocument_p.h
qquickpdflinkmodel.cpp qquickpdflinkmodel_p.h
qquickpdfnavigationstack.cpp qquickpdfnavigationstack_p.h
+ qquickpdfpageimage.cpp qquickpdfpageimage_p.h
qquickpdfsearchmodel.cpp qquickpdfsearchmodel_p.h
qquickpdfselection.cpp qquickpdfselection_p.h
qtpdfquickglobal_p.h
diff --git a/src/pdfquick/PdfMultiPageView.qml b/src/pdfquick/PdfMultiPageView.qml
index 8ab5e2c2e..f67e2c17a 100644
--- a/src/pdfquick/PdfMultiPageView.qml
+++ b/src/pdfquick/PdfMultiPageView.qml
@@ -156,10 +156,10 @@ Item {
anchors.centerIn: pinch.active ? undefined : parent
property size pagePointSize: document.pagePointSize(index)
property real pageScale: image.paintedWidth / pagePointSize.width
- Image {
+ PdfPageImage {
id: image
- source: document.source
- currentFrame: index
+ document: root.document
+ currentPage: index
asynchronous: true
fillMode: Image.PreserveAspectFit
width: paper.pagePointSize.width * root.renderScale
@@ -290,7 +290,7 @@ Item {
model: PdfLinkModel {
id: linkModel
document: root.document
- page: image.currentFrame
+ page: image.currentPage
}
delegate: Shape {
required property rect rect
@@ -337,7 +337,7 @@ Item {
id: selection
anchors.fill: parent
document: root.document
- page: image.currentFrame
+ page: image.currentPage
renderScale: image.renderScale
fromPoint: textSelectionDrag.centroid.pressPosition
toPoint: textSelectionDrag.centroid.position
diff --git a/src/pdfquick/PdfPageView.qml b/src/pdfquick/PdfPageView.qml
index ed1f00372..bcb286c0c 100644
--- a/src/pdfquick/PdfPageView.qml
+++ b/src/pdfquick/PdfPageView.qml
@@ -146,10 +146,10 @@ Rectangle {
// TODO deal with horizontal location (need WheelHandler or Flickable probably)
}
- Image {
+ PdfPageImage {
id: image
- currentFrame: navigationStack.currentPage
- source: document.status === PdfDocument.Ready ? document.source : ""
+ document: root.document
+ currentPage: navigationStack.currentPage
asynchronous: true
fillMode: Image.PreserveAspectFit
property bool centerOnLoad: false
diff --git a/src/pdfquick/PdfScrollablePageView.qml b/src/pdfquick/PdfScrollablePageView.qml
index 40be27176..9e458397e 100644
--- a/src/pdfquick/PdfScrollablePageView.qml
+++ b/src/pdfquick/PdfScrollablePageView.qml
@@ -168,10 +168,10 @@ Flickable {
property real rotationModulus: Math.abs(root.pageRotation % 180)
property bool rot90: rotationModulus > 45 && rotationModulus < 135
- Image {
+ PdfPageImage {
id: image
- currentFrame: navigationStack.currentPage
- source: document.status === PdfDocument.Ready ? document.source : ""
+ document: root.document
+ currentPage: navigationStack.currentPage
asynchronous: true
fillMode: Image.PreserveAspectFit
rotation: root.pageRotation
diff --git a/src/pdfquick/qquickpdfdocument.cpp b/src/pdfquick/qquickpdfdocument.cpp
index 64ad0071a..bdfad3905 100644
--- a/src/pdfquick/qquickpdfdocument.cpp
+++ b/src/pdfquick/qquickpdfdocument.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qquickpdfdocument_p.h"
+#include <private/qpdffile_p.h>
#include <QtCore/qstandardpaths.h>
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlengine.h>
@@ -221,6 +222,18 @@ qreal QQuickPdfDocument::heightSumBeforePage(int page, qreal spacing, int facing
return ret;
}
+/*!
+ \internal
+ Returns a QPdfFile instance that can carry this document down into
+ QPdfIOHandler::load(QIODevice *). It should not be used for other purposes.
+*/
+QPdfFile *QQuickPdfDocument::carrierFile()
+{
+ if (!m_carrierFile)
+ m_carrierFile = new QPdfFile(&m_doc);
+ return m_carrierFile;
+}
+
void QQuickPdfDocument::updateMaxPageSize()
{
if (m_maxPageWidthHeight.isValid())
diff --git a/src/pdfquick/qquickpdfdocument_p.h b/src/pdfquick/qquickpdfdocument_p.h
index 2d6f2ca3b..fb7f06b97 100644
--- a/src/pdfquick/qquickpdfdocument_p.h
+++ b/src/pdfquick/qquickpdfdocument_p.h
@@ -61,6 +61,8 @@
QT_BEGIN_NAMESPACE
+class QPdfFile;
+
class Q_PDFQUICK_EXPORT QQuickPdfDocument : public QObject, public QQmlParserStatus
{
Q_OBJECT
@@ -128,15 +130,18 @@ Q_SIGNALS:
private:
QPdfDocument &document() { return m_doc; }
+ QPdfFile *carrierFile();
void updateMaxPageSize();
private:
QUrl m_source;
QUrl m_resolvedSource;
QPdfDocument m_doc;
+ QPdfFile *m_carrierFile = nullptr;
QSizeF m_maxPageWidthHeight;
friend class QQuickPdfLinkModel;
+ friend class QQuickPdfPageImage;
friend class QQuickPdfSearchModel;
friend class QQuickPdfSelection;
diff --git a/src/pdfquick/qquickpdfpageimage.cpp b/src/pdfquick/qquickpdfpageimage.cpp
new file mode 100644
index 000000000..18513fba4
--- /dev/null
+++ b/src/pdfquick/qquickpdfpageimage.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpdfpageimage_p.h"
+#include "qquickpdfdocument_p.h"
+#include <private/qpdffile_p.h>
+#include <QtPdf/QPdfPageNavigation>
+#include <QtQuick/private/qquickimage_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(qLcImg, "qt.pdf.image")
+
+/*!
+ \qmltype PdfPageImage
+ \instantiates QQuickPdfPageImage
+ \inqmlmodule QtPdf
+ \ingroup pdf
+ \inherits Item
+ \brief Displays one page from a PDF document.
+ \since 6.4
+
+ The PdfPageImage type is an Image specialized to render a page from a PDF document.
+*/
+
+class QQuickPdfPageImagePrivate: public QQuickImagePrivate
+{
+public:
+ QQuickPdfPageImagePrivate() : QQuickImagePrivate() {}
+
+ QQuickPdfDocument *doc = nullptr;
+};
+
+QQuickPdfPageImage::QQuickPdfPageImage(QQuickItem *parent)
+ : QQuickImage(*(new QQuickPdfPageImagePrivate), parent)
+{
+}
+
+QQuickPdfPageImage::~QQuickPdfPageImage()
+{
+ Q_D(QQuickPdfPageImage);
+ // cancel any async rendering job that is running on my behalf
+ d->pix.clear();
+}
+
+void QQuickPdfPageImage::setDocument(QQuickPdfDocument *document)
+{
+ Q_D(QQuickPdfPageImage);
+ if (d->doc == document)
+ return;
+
+ if (d->doc)
+ disconnect(d->doc, &QQuickPdfDocument::statusChanged, this, &QQuickPdfPageImage::documentStatusChanged);
+ d->doc = document;
+ if (document) {
+ connect(document, &QQuickPdfDocument::statusChanged, this, &QQuickPdfPageImage::documentStatusChanged);
+ if (document->status() == QPdfDocument::Status::Ready)
+ setSource(document->resolvedSource()); // calls load()
+ }
+ emit documentChanged();
+}
+
+QQuickPdfDocument *QQuickPdfPageImage::document() const
+{
+ Q_D(const QQuickPdfPageImage);
+ return d->doc;
+}
+
+void QQuickPdfPageImage::load()
+{
+ Q_D(QQuickPdfPageImage);
+ auto carrierFile = d->doc->carrierFile();
+ static int thisRequestProgress = -1;
+ static int thisRequestFinished = -1;
+ if (thisRequestProgress == -1) {
+ thisRequestProgress =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
+ thisRequestFinished =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
+ }
+
+ d->pix.loadImageFromDevice(qmlEngine(this), carrierFile, d->url,
+ d->sourceClipRect.toRect(), d->sourcesize * d->devicePixelRatio,
+ QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
+
+ qCDebug(qLcImg) << "loading page" << d->currentFrame << "of" << d->frameCount
+ << "from" << carrierFile->fileName() << "status" << d->pix.status();
+
+ switch (d->pix.status()) {
+ case QQuickPixmap::Ready:
+ pixmapChange();
+ break;
+ case QQuickPixmap::Loading:
+ d->pix.connectFinished(this, thisRequestFinished);
+ d->pix.connectDownloadProgress(this, thisRequestProgress);
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ if (d->status != Loading) {
+ d->status = Loading;
+ emit statusChanged(d->status);
+ }
+ break;
+ default:
+ qCDebug(qLcImg) << "unexpected status" << d->pix.status();
+ break;
+ }
+}
+
+void QQuickPdfPageImage::documentStatusChanged()
+{
+ Q_D(QQuickPdfPageImage);
+ qCDebug(qLcImg) << "document status" << d->doc->status();
+ if (d->doc->status() == QPdfDocument::Status::Ready)
+ setSource(d->doc->resolvedSource()); // calls load()
+}
+
+QT_END_NAMESPACE
diff --git a/src/pdfquick/qquickpdfpageimage_p.h b/src/pdfquick/qquickpdfpageimage_p.h
new file mode 100644
index 000000000..b77a4f037
--- /dev/null
+++ b/src/pdfquick/qquickpdfpageimage_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPDFPAGEIMAGE_P_H
+#define QQUICKPDFPAGEIMAGE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtPdfQuick/private/qtpdfquickglobal_p.h>
+#include <QtQuick/private/qquickimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPdfDocument;
+class QQuickPdfPageImagePrivate;
+class Q_PDFQUICK_EXPORT QQuickPdfPageImage : public QQuickImage
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged FINAL)
+ Q_PROPERTY(int currentPage READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged FINAL)
+ QML_NAMED_ELEMENT(PdfPageImage)
+ QML_ADDED_IN_VERSION(6, 4)
+
+public:
+ QQuickPdfPageImage(QQuickItem *parent = nullptr);
+ ~QQuickPdfPageImage();
+
+ void setDocument(QQuickPdfDocument *document);
+ QQuickPdfDocument *document() const;
+
+signals:
+ void documentChanged();
+
+protected:
+ void load() override;
+ void documentStatusChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QQuickPdfPageImage)
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPDFPAGEIMAGE_P_H