From 09a6eac4a63b32548ecc1ff5b16a5d8fc3ba1c04 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge <shawn.rutledge@qt.io> Date: Wed, 5 Feb 2020 15:53:57 +0100 Subject: [PATCH] Add QPdfDestination; NavigationStack stores page, location and zoom Push/back/forward behavior seems more correct now, but still no autotest yet. QPdfDestination might be useful to represent locations of search results, for link destinations and maybe named destinations too. Fixes: QTBUG-77512 Change-Id: I113b2c535a2cd302106e6546104c64e12985d387 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> --- examples/pdf/pdfviewer/viewer.qml | 3 +- src/pdf/api/qpdfdestination.h | 81 +++++++++ src/pdf/api/qpdfdestination_p.h | 60 +++++++ src/pdf/pdfcore.pro | 3 + src/pdf/qpdfdestination.cpp | 135 +++++++++++++++ src/pdf/qpdfdocument.cpp | 3 + src/pdf/quick/qml/PdfMultiPageView.qml | 4 +- src/pdf/quick/qml/PdfPageView.qml | 3 +- src/pdf/quick/qquickpdfnavigationstack.cpp | 188 ++++++++++++++++----- src/pdf/quick/qquickpdfnavigationstack_p.h | 21 ++- 10 files changed, 447 insertions(+), 54 deletions(-) create mode 100644 src/pdf/api/qpdfdestination.h create mode 100644 src/pdf/api/qpdfdestination_p.h create mode 100644 src/pdf/qpdfdestination.cpp diff --git a/examples/pdf/pdfviewer/viewer.qml b/examples/pdf/pdfviewer/viewer.qml index a8e581a45..095bc3985 100644 --- a/examples/pdf/pdfviewer/viewer.qml +++ b/examples/pdf/pdfviewer/viewer.qml @@ -140,7 +140,7 @@ ApplicationWindow { from: 1 to: document.pageCount editable: true - onValueChanged: pageView.currentPage = value - 1 + onValueChanged: pageView.goToPage(value - 1) Shortcut { sequence: StandardKey.MoveToPreviousPage onActivated: currentPageSB.value-- @@ -223,7 +223,6 @@ ApplicationWindow { PdfPageView { id: pageView -// currentPage: currentPageSB.value - 1 // TODO should work but ends up being NaN in QQuickSpinBoxPrivate::setValue() (?!) // onCurrentPageChanged: currentPageSB.value = pageView.currrentPage + 1 onCurrentPageReallyChanged: currentPageSB.value = page + 1 diff --git a/src/pdf/api/qpdfdestination.h b/src/pdf/api/qpdfdestination.h new file mode 100644 index 000000000..dc5d6314a --- /dev/null +++ b/src/pdf/api/qpdfdestination.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 QPDFDESTINATION_H +#define QPDFDESTINATION_H + +#include <QtPdf/qtpdfglobal.h> +#include <QExplicitlySharedDataPointer> +#include <QObject> +#include <QPointF> + +QT_BEGIN_NAMESPACE + +class QPdfDestinationPrivate; + +class Q_PDF_EXPORT QPdfDestination +{ + Q_GADGET + Q_PROPERTY(bool valid READ isValid) + Q_PROPERTY(int page READ page) + Q_PROPERTY(QPointF location READ location) + Q_PROPERTY(qreal zoom READ zoom) + +public: + QPdfDestination(const QPdfDestination &other); + ~QPdfDestination(); + QPdfDestination &operator=(const QPdfDestination &other); + inline QPdfDestination &operator=(QPdfDestination &&other) noexcept { swap(other); return *this; } + void swap(QPdfDestination &other) noexcept { d.swap(other.d); } + bool isValid() const; + int page() const; + QPointF location() const; + qreal zoom() const; + +private: + QPdfDestination(); + QPdfDestination(int page, QPointF location, qreal zoom); + QPdfDestination(QPdfDestinationPrivate *d); + friend class QPdfDocument; + friend class QQuickPdfNavigationStack; + +private: + QExplicitlySharedDataPointer<QPdfDestinationPrivate> d; +}; + +QT_END_NAMESPACE + +#endif // QPDFDESTINATION_H diff --git a/src/pdf/api/qpdfdestination_p.h b/src/pdf/api/qpdfdestination_p.h new file mode 100644 index 000000000..a5aeb804f --- /dev/null +++ b/src/pdf/api/qpdfdestination_p.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 QPDFDESTINATION_P_H +#define QPDFDESTINATION_P_H + +#include <QPointF> + +QT_BEGIN_NAMESPACE + +class QPdfDestinationPrivate : public QSharedData +{ +public: + QPdfDestinationPrivate() = default; + QPdfDestinationPrivate(int page, QPointF location, qreal zoom) + : page(page), + location(location), + zoom(zoom) { } + + int page = -1; + QPointF location; + qreal zoom = 1; +}; + +QT_END_NAMESPACE + +#endif // QPDFDESTINATION_P_H diff --git a/src/pdf/pdfcore.pro b/src/pdf/pdfcore.pro index ecb1d0cdb..951b5699f 100644 --- a/src/pdf/pdfcore.pro +++ b/src/pdf/pdfcore.pro @@ -60,6 +60,7 @@ ios: OBJECTS += $$NINJA_OBJECTS SOURCES += \ qpdfbookmarkmodel.cpp \ + qpdfdestination.cpp \ qpdfdocument.cpp \ qpdflinkmodel.cpp \ qpdfpagenavigation.cpp \ @@ -72,6 +73,8 @@ SOURCES += \ HEADERS += \ api/qpdfbookmarkmodel.h \ + api/qpdfdestination.h \ + api/qpdfdestination_p.h \ api/qpdfdocument.h \ api/qpdfdocument_p.h \ api/qpdfdocumentrenderoptions.h \ diff --git a/src/pdf/qpdfdestination.cpp b/src/pdf/qpdfdestination.cpp new file mode 100644 index 000000000..86e429dcf --- /dev/null +++ b/src/pdf/qpdfdestination.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 "qpdfdestination.h" +#include "qpdfdestination_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QPdfDestination + \since 5.15 + \inmodule QtPdf + + \brief The QPdfDestination class defines a location on a page in a PDF + document, and a suggested zoom level at which it is intended to be viewed. +*/ + +/*! + Constructs an invalid Destination. + + \sa valid +*/ +QPdfDestination::QPdfDestination() + : d(new QPdfDestinationPrivate()) +{ +} + +QPdfDestination::QPdfDestination(int page, QPointF location, qreal zoom) + : d(new QPdfDestinationPrivate(page, location, zoom)) +{ +} + +QPdfDestination::QPdfDestination(QPdfDestinationPrivate *d) + : d(d) +{ +} + +QPdfDestination::QPdfDestination(const QPdfDestination &other) + : d(other.d) +{ +} + +QPdfDestination::~QPdfDestination() +{ +} + +/*! + \property QPdfDestination::valid + + This property holds whether the destination is valid. +*/ +bool QPdfDestination::isValid() const +{ + return d->page >= 0; +} + +/*! + \property QPdfDestination::page + + This property holds the page number. +*/ +int QPdfDestination::page() const +{ + return d->page; +} + +/*! + \property QPdfDestination::location + + This property holds the location on the page, in units of points. +*/ +QPointF QPdfDestination::location() const +{ + return d->location; +} + +/*! + \property QPdfDestination::zoom + + This property holds the suggested magnification level, where 1.0 means default scale + (1 pixel = 1 point). +*/ +qreal QPdfDestination::zoom() const +{ + return d->zoom; +} + +//QDataStream& operator<<(QDataStream& stream, const QPdfDestination& dest) +//{ +// stream << *dest.d.data(); +// return stream; +//} + +QDataStream& operator<<(QDataStream& stream, const QPdfDestinationPrivate& dest) +{ + stream << QStringLiteral("QPdfDestination") << dest.page << dest.location ; // << dest.zoom(); + return stream; +} + +QT_END_NAMESPACE + +#include "moc_qpdfdestination.cpp" diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp index 3719938a2..42cd2492d 100644 --- a/src/pdf/qpdfdocument.cpp +++ b/src/pdf/qpdfdocument.cpp @@ -345,6 +345,9 @@ void QPdfDocumentPrivate::checkComplete() bool QPdfDocumentPrivate::checkPageComplete(int page) { + if (page < 0 || page >= pageCount) + return false; + if (loadComplete) return true; diff --git a/src/pdf/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml index 28436b90d..be41153b6 100644 --- a/src/pdf/quick/qml/PdfMultiPageView.qml +++ b/src/pdf/quick/qml/PdfMultiPageView.qml @@ -111,7 +111,7 @@ Item { property bool rot90: rotationModulus > 45 && rotationModulus < 135 property size firstPagePointSize: document.pagePointSize(0) onCurrentIndexChanged: { - navigationStack.currentPage = currentIndex + navigationStack.push(currentIndex, Qt.point(0, 0), root.renderScale) root.currentPageReallyChanged(currentIndex) } delegate: Rectangle { @@ -244,7 +244,7 @@ Item { } PdfNavigationStack { id: navigationStack - onCurrentPageJumped: listView.currentIndex = page + onJumped: listView.currentIndex = page onCurrentPageChanged: root.currentPageReallyChanged(navigationStack.currentPage) } } diff --git a/src/pdf/quick/qml/PdfPageView.qml b/src/pdf/quick/qml/PdfPageView.qml index cf287ecf7..d03e9dc9d 100644 --- a/src/pdf/quick/qml/PdfPageView.qml +++ b/src/pdf/quick/qml/PdfPageView.qml @@ -57,6 +57,7 @@ Rectangle { property alias forwardEnabled: navigationStack.forwardAvailable function back() { navigationStack.back() } function forward() { navigationStack.forward() } + function goToPage(page) { navigationStack.push(page, Qt.point(0, 0), renderScale) } signal currentPageReallyChanged(page: int) property real __pageScale: image.paintedWidth / document.pagePointSize(navigationStack.currentPage).width @@ -203,7 +204,7 @@ Rectangle { cursorShape: Qt.PointingHandCursor onClicked: { if (page >= 0) - navigationStack.currentPage = page + navigationStack.push(page, Qt.point(0, 0), paper.renderScale) else Qt.openUrlExternally(url) } diff --git a/src/pdf/quick/qquickpdfnavigationstack.cpp b/src/pdf/quick/qquickpdfnavigationstack.cpp index c19fae735..57acdc4bc 100644 --- a/src/pdf/quick/qquickpdfnavigationstack.cpp +++ b/src/pdf/quick/qquickpdfnavigationstack.cpp @@ -46,10 +46,10 @@ Q_LOGGING_CATEGORY(qLcNav, "qt.pdf.navigationstack") \instantiates QQuickPdfNavigationStack \inqmlmodule QtQuick.Pdf \ingroup pdf - \brief History of the pages visited within a PDF Document. + \brief History of the destinations visited within a PDF Document. \since 5.15 - PdfNavigationStack remembers which pages the user has visited in a PDF + PdfNavigationStack remembers which destinations the user has visited in a PDF document, and provides the ability to traverse backward and forward. */ @@ -61,102 +61,206 @@ QQuickPdfNavigationStack::QQuickPdfNavigationStack(QObject *parent) /*! \qmlmethod void PdfNavigationStack::forward() - Goes back to the page that was being viewed before back() was called, and - then emits the \l currentPageJumped() signal. + Goes back to the page, location and zoom level that was being viewed before + back() was called, and then emits the \l jumped() signal. - If \l currentPage was set by assignment or binding since the last time - \l back() was called, the forward() function does nothing, because there is - a branch in the timeline which causes the "future" to be lost. + If a new destination was pushed since the last time \l back() was called, + the forward() function does nothing, because there is a branch in the + timeline which causes the "future" to be lost. */ void QQuickPdfNavigationStack::forward() { - if (m_nextHistoryIndex >= m_pageHistory.count()) + if (m_currentHistoryIndex >= m_pageHistory.count() - 1) return; bool backAvailableWas = backAvailable(); bool forwardAvailableWas = forwardAvailable(); + QPointF currentLocationWas = currentLocation(); + qreal currentZoomWas = currentZoom(); + ++m_currentHistoryIndex; m_changing = true; - setCurrentPage(m_pageHistory.at(++m_nextHistoryIndex)); - m_changing = false; - emit currentPageJumped(m_currentPage); - if (backAvailableWas != backAvailable()) + emit jumped(currentPage(), currentLocation(), currentZoom()); + emit currentPageChanged(); + if (currentLocationWas != currentLocation()) + emit currentLocationChanged(); + if (currentZoomWas != currentZoom()) + emit currentZoomChanged(); + if (!backAvailableWas) emit backAvailableChanged(); if (forwardAvailableWas != forwardAvailable()) emit forwardAvailableChanged(); + m_changing = false; } /*! \qmlmethod void PdfNavigationStack::back() - Pops the stack and causes the \l currentPage property to change to the - most-recently-viewed page, and then emits the \l currentPageJumped() - signal. + Pops the stack, updates the \l currentPage, \l currentLocation and + \l currentZoom properties to the most-recently-viewed destination, and then + emits the \l jumped() signal. */ void QQuickPdfNavigationStack::back() { - if (m_nextHistoryIndex <= 0) + if (m_currentHistoryIndex <= 0) return; bool backAvailableWas = backAvailable(); bool forwardAvailableWas = forwardAvailable(); + QPointF currentLocationWas = currentLocation(); + qreal currentZoomWas = currentZoom(); + --m_currentHistoryIndex; m_changing = true; - // TODO don't do that when going back after going forward - m_pageHistory.append(m_currentPage); - setCurrentPage(m_pageHistory.at(--m_nextHistoryIndex)); - m_changing = false; - emit currentPageJumped(m_currentPage); + emit jumped(currentPage(), currentLocation(), currentZoom()); + emit currentPageChanged(); + if (currentLocationWas != currentLocation()) + emit currentLocationChanged(); + if (currentZoomWas != currentZoom()) + emit currentZoomChanged(); if (backAvailableWas != backAvailable()) emit backAvailableChanged(); - if (forwardAvailableWas != forwardAvailable()) + if (!forwardAvailableWas) emit forwardAvailableChanged(); + m_changing = false; } /*! \qmlproperty int PdfNavigationStack::currentPage This property holds the current page that is being viewed. + If there is no current page, it holds \c -1. +*/ +int QQuickPdfNavigationStack::currentPage() const +{ + if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count()) + return -1; + return m_pageHistory.at(m_currentHistoryIndex)->page; +} + +/*! + \qmlproperty point PdfNavigationStack::currentLocation + + This property holds the current location on the page that is being viewed. +*/ +QPointF QQuickPdfNavigationStack::currentLocation() const +{ + if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count()) + return QPointF(); + return m_pageHistory.at(m_currentHistoryIndex)->location; +} - It should be set when the viewer's current page changes. Every time this - property is set, it pushes the current page number onto the stack, such - that the history of pages that have been viewed will grow. +/*! + \qmlproperty real PdfNavigationStack::currentZoom + + This property holds the magnification scale on the page that is being viewed. */ -void QQuickPdfNavigationStack::setCurrentPage(int currentPage) +qreal QQuickPdfNavigationStack::currentZoom() const { - if (m_currentPage == currentPage) + if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count()) + return 1; + return m_pageHistory.at(m_currentHistoryIndex)->zoom; +} + +/*! + \qmlmethod void PdfNavigationStack::push(int page, point location, qreal zoom) + + Adds the given destination, consisting of \a page, \a location and \a zoom, + to the history of visited locations. + + If forwardAvailable is \c true, calling this function represents a branch + in the timeline which causes the "future" to be lost, and therefore + forwardAvailable will change to \c false. +*/ +void QQuickPdfNavigationStack::push(int page, QPointF location, qreal zoom) +{ + if (page == currentPage() && location == currentLocation() && zoom == currentZoom()) return; + if (qFuzzyIsNull(zoom)) + zoom = currentZoom(); bool backAvailableWas = backAvailable(); bool forwardAvailableWas = forwardAvailable(); if (!m_changing) { - if (m_nextHistoryIndex >= 0 && m_nextHistoryIndex < m_pageHistory.count()) - m_pageHistory.remove(m_nextHistoryIndex, m_pageHistory.count() - m_nextHistoryIndex); - m_pageHistory.append(m_currentPage); - m_nextHistoryIndex = m_pageHistory.count(); + if (m_currentHistoryIndex >= 0 && forwardAvailableWas) + m_pageHistory.remove(m_currentHistoryIndex + 1, m_pageHistory.count() - m_currentHistoryIndex - 1); + m_pageHistory.append(QExplicitlySharedDataPointer<QPdfDestinationPrivate>(new QPdfDestinationPrivate(page, location, zoom))); + m_currentHistoryIndex = m_pageHistory.count() - 1; } - m_currentPage = currentPage; emit currentPageChanged(); - if (backAvailableWas != backAvailable()) + emit currentLocationChanged(); + emit currentZoomChanged(); + if (m_changing) + return; + if (!backAvailableWas) emit backAvailableChanged(); - if (forwardAvailableWas != forwardAvailable()) + if (forwardAvailableWas) emit forwardAvailableChanged(); - qCDebug(qLcNav) << "current" << m_currentPage << "history" << m_pageHistory; + qCDebug(qLcNav) << "push: index" << m_currentHistoryIndex << "page" << page + << "@" << location << "zoom" << zoom << "-> history" << + [this]() { + QStringList ret; + for (auto d : m_pageHistory) + ret << QString::number(d->page); + return ret.join(','); + }(); +} + +/*! + \qmlmethod void PdfNavigationStack::update(int page, point location, qreal zoom) + + Modifies the current destination, consisting of \a page, \a location and \a zoom. + + This can be called periodically while the user is manually moving around + the document, so that after back() is called, forward() will jump back to + the most-recently-viewed destination rather than the destination that was + last specified by push(). + + The \c currentPageChanged, \c currentLocationChanged and \c currentZoomChanged + signals will be emitted if the respective properties are actually changed. + The \l jumped signal is not emitted, because this operation + represents smooth movement rather than a navigational jump. +*/ +void QQuickPdfNavigationStack::update(int page, QPointF location, qreal zoom) +{ + if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count()) + return; + int currentPageWas = currentPage(); + QPointF currentLocationWas = currentLocation(); + qreal currentZoomWas = currentZoom(); + if (page == currentPageWas && location == currentLocationWas && zoom == currentZoomWas) + return; + m_pageHistory[m_currentHistoryIndex]->page = page; + m_pageHistory[m_currentHistoryIndex]->location = location; + m_pageHistory[m_currentHistoryIndex]->zoom = zoom; + if (currentPageWas != page) + emit currentPageChanged(); + if (currentLocationWas != location) + emit currentLocationChanged(); + if (currentZoomWas != zoom) + emit currentZoomChanged(); + qCDebug(qLcNav) << "update: index" << m_currentHistoryIndex << "page" << page + << "@" << location << "zoom" << zoom << "-> history" << + [this]() { + QStringList ret; + for (auto d : m_pageHistory) + ret << QString::number(d->page); + return ret.join(','); + }(); } bool QQuickPdfNavigationStack::backAvailable() const { - return m_nextHistoryIndex > 0; + return m_currentHistoryIndex > 0; } bool QQuickPdfNavigationStack::forwardAvailable() const { - return m_nextHistoryIndex < m_pageHistory.count(); + return m_currentHistoryIndex < m_pageHistory.count() - 1; } /*! - \qmlsignal PdfNavigationStack::currentPageJumped(int page) + \qmlsignal PdfNavigationStack::jumped(int page, point location, qreal zoom) This signal is emitted when either forward() or back() is called, to - distinguish navigational jumps from cases when the \l currentPage property - is set by means of a binding or assignment. Contrast with the - \c currentPageChanged signal, which is emitted in all cases, and does not - include the \c page argument. + distinguish navigational jumps from cases when push() is called. + Contrast with the \c currentPageChanged signal, which is emitted in all + cases, and does not include the \c page, \c location and \c zoom arguments. */ QT_END_NAMESPACE diff --git a/src/pdf/quick/qquickpdfnavigationstack_p.h b/src/pdf/quick/qquickpdfnavigationstack_p.h index 54713fabb..8d7102fb1 100644 --- a/src/pdf/quick/qquickpdfnavigationstack_p.h +++ b/src/pdf/quick/qquickpdfnavigationstack_p.h @@ -49,6 +49,7 @@ // #include "qquickpdfdocument_p.h" +#include "../api/qpdfdestination_p.h" #include <QtQml/qqml.h> @@ -57,32 +58,38 @@ QT_BEGIN_NAMESPACE class QQuickPdfNavigationStack : public QObject { Q_OBJECT - Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged) + Q_PROPERTY(int currentPage READ currentPage NOTIFY currentPageChanged) + Q_PROPERTY(QPointF currentLocation READ currentLocation NOTIFY currentLocationChanged) + Q_PROPERTY(qreal currentZoom READ currentZoom NOTIFY currentZoomChanged) Q_PROPERTY(bool backAvailable READ backAvailable NOTIFY backAvailableChanged) Q_PROPERTY(bool forwardAvailable READ forwardAvailable NOTIFY forwardAvailableChanged) public: explicit QQuickPdfNavigationStack(QObject *parent = nullptr); + Q_INVOKABLE void push(int page, QPointF location, qreal zoom); + Q_INVOKABLE void update(int page, QPointF location, qreal zoom); Q_INVOKABLE void forward(); Q_INVOKABLE void back(); - int currentPage() const { return m_currentPage; } - void setCurrentPage(int currentPage); + int currentPage() const; + QPointF currentLocation() const; + qreal currentZoom() const; bool backAvailable() const; bool forwardAvailable() const; Q_SIGNALS: void currentPageChanged(); - void currentPageJumped(int page); + void currentLocationChanged(); + void currentZoomChanged(); void backAvailableChanged(); void forwardAvailableChanged(); + void jumped(int page, QPointF location, qreal zoom); private: - QVector<int> m_pageHistory; - int m_nextHistoryIndex = 0; - int m_currentPage = 0; + QVector<QExplicitlySharedDataPointer<QPdfDestinationPrivate>> m_pageHistory; + int m_currentHistoryIndex = 0; bool m_changing = false; Q_DISABLE_COPY(QQuickPdfNavigationStack) -- GitLab