summaryrefslogtreecommitdiff
path: root/src/pdf
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2022-06-02 21:51:21 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2022-06-04 20:55:31 +0200
commit33f6047ef17421fd07d0350fedcfbd049e31fe28 (patch)
tree0e64e05110dd5536bf07c4ed5cdaf72633d831ed /src/pdf
parentfa260888d9c9a59acd6e35aa472ca53990ce6635 (diff)
downloadqtwebengine-33f6047ef17421fd07d0350fedcfbd049e31fe28.tar.gz
Use QPdfLink in PageNavigator jump() / jumped(); QML views
One reason for this is to use the new tableView.positionViewAtCell(.., TableView.Contain, offset, rect) to do less scrolling when iterating search results. Now in that case, the QPdfLink object contains correct rectangles, so that we can scale the first one and pass it directly to positionViewAtCell(). When clicking a hyperlink, the destination is a point rather than a rectangle; but positionViewAtCell with a subRect works better than calling it with just an offset, so we construct a small rectangle for that purpose. It's important that the QPdfLink object emitted in the jumped() signal must not contain any rectangles in this case, so that we can distinguish a hyperlink destination from a search-result destination. The QPdfLink object from PdfLinkModel has its own rectangle, but that's the place where the user clicks. When clicked, the view calls pageNavigator.jump(page, location, zoom), rather than the jump(QPdfLink) overload, so that rectangle is not passed along. In an onJumped() handler, we expect the rectangles to be the destination, if present; otherwise we fall back to using the location property, which is always the destination, never the source. In both cases, we need to grow the destination rectangle by jumpLocationMargin, because the offset argument to positionViewAtCell() is an offset, not a margin. But since the rectangle needs to be scaled from points to pixels anyway (according to the current renderScale), it's not much more trouble to add the margin. It looks better to avoid having a search result and its highlight rectangle banging up against the corner of the viewport: the margin lets the user see a bit of context on the page, and the highlight looks more distinct by being spaced out away from the edge. And since the margin gets added to the rectangle's edges, it makes more sense to use the (qreal) point type rather than vector2d. To make it possible to emit a QPdfLink object and access its properties in QML, it's now registered as a QML type. Fixes: QTBUG-102740 Change-Id: I74ccd11a106c5e49a0ce94eef9cf2d50992923b4 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src/pdf')
-rw-r--r--src/pdf/qpdflink.h3
-rw-r--r--src/pdf/qpdfpagenavigator.cpp71
-rw-r--r--src/pdf/qpdfpagenavigator.h7
3 files changed, 74 insertions, 7 deletions
diff --git a/src/pdf/qpdflink.h b/src/pdf/qpdflink.h
index 69f7f25a9..22de24063 100644
--- a/src/pdf/qpdflink.h
+++ b/src/pdf/qpdflink.h
@@ -88,6 +88,7 @@ private: // methods
QPdfLink(QPdfLinkPrivate *d);
friend class QPdfDocument;
friend class QPdfSearchModelPrivate;
+ friend class QPdfPageNavigator;
friend class QQuickPdfPageNavigator;
private: // storage
@@ -100,4 +101,6 @@ Q_PDF_EXPORT QDebug operator<<(QDebug, const QPdfLink &);
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QPdfLink)
+
#endif // QPDFLINK_H
diff --git a/src/pdf/qpdfpagenavigator.cpp b/src/pdf/qpdfpagenavigator.cpp
index db40233e3..e73c6fc24 100644
--- a/src/pdf/qpdfpagenavigator.cpp
+++ b/src/pdf/qpdfpagenavigator.cpp
@@ -106,7 +106,7 @@ void QPdfPageNavigator::forward()
qreal currentZoomWas = currentZoom();
++d->currentHistoryIndex;
d->changing = true;
- emit jumped(currentPage(), currentLocation(), currentZoom());
+ emit jumped(currentLink());
if (currentZoomWas != currentZoom())
emit currentZoomChanged(currentZoom());
emit currentPageChanged(currentPage());
@@ -136,7 +136,7 @@ void QPdfPageNavigator::back()
qreal currentZoomWas = currentZoom();
--d->currentHistoryIndex;
d->changing = true;
- emit jumped(currentPage(), currentLocation(), currentZoom());
+ emit jumped(currentLink());
if (currentZoomWas != currentZoom())
emit currentZoomChanged(currentZoom());
emit currentPageChanged(currentPage());
@@ -190,6 +190,13 @@ qreal QPdfPageNavigator::currentZoom() const
return d->pageHistory.at(d->currentHistoryIndex)->zoom;
}
+QPdfLink QPdfPageNavigator::currentLink() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.count())
+ return QPdfLink();
+ return QPdfLink(d->pageHistory.at(d->currentHistoryIndex).data());
+}
+
/*!
Clear the history and restore \l currentPage, \l currentLocation and
\l currentZoom to their default values.
@@ -204,6 +211,53 @@ void QPdfPageNavigator::clear()
}
/*!
+ Adds the given \a destination to the history of visited locations.
+
+ In this case, PDF views respond to the \l jumped signal by scrolling to
+ place \c destination.rectangles in the viewport, as opposed to placing
+ \c destination.location in the viewport. So it's appropriate to call this
+ method to jump to a search result from QPdfSearchModel (because the
+ rectangles cover the region of text found). To jump to a hyperlink
+ destination, call jump(page, location, zoom) instead, because in that
+ case the QPdfLink object's \c rectangles cover the hyperlink origin
+ location rather than the destination.
+*/
+void QPdfPageNavigator::jump(QPdfLink destination)
+{
+ const bool zoomChange = !qFuzzyCompare(destination.zoom(), currentZoom());
+ const bool pageChange = (destination.page() != currentPage());
+ const bool locationChange = (destination.location() != currentLocation());
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ if (!d->changing) {
+ if (d->currentHistoryIndex >= 0 && forwardAvailableWas)
+ d->pageHistory.remove(d->currentHistoryIndex + 1, d->pageHistory.count() - d->currentHistoryIndex - 1);
+ d->pageHistory.append(destination.d);
+ d->currentHistoryIndex = d->pageHistory.count() - 1;
+ }
+ if (zoomChange)
+ emit currentZoomChanged(currentZoom());
+ if (pageChange)
+ emit currentPageChanged(currentPage());
+ if (locationChange)
+ emit currentLocationChanged(currentLocation());
+ if (d->changing)
+ return;
+ if (!backAvailableWas)
+ emit backAvailableChanged(backAvailable());
+ if (forwardAvailableWas)
+ emit forwardAvailableChanged(forwardAvailable());
+ emit jumped(currentLink());
+ qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << destination << "-> history" <<
+ [this]() {
+ QStringList ret;
+ for (auto d : d->pageHistory)
+ ret << QString::number(d->page);
+ return ret.join(QLatin1Char(','));
+ }();
+}
+
+/*!
Adds the given destination, consisting of \a page, \a location, and \a zoom,
to the history of visited locations.
@@ -249,7 +303,7 @@ void QPdfPageNavigator::jump(int page, const QPointF &location, qreal zoom)
emit backAvailableChanged(backAvailable());
if (forwardAvailableWas)
emit forwardAvailableChanged(forwardAvailable());
- emit jumped(page, location, zoom);
+ emit jumped(currentLink());
qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << "page" << page
<< "@" << location << "zoom" << zoom << "-> history" <<
[this]() {
@@ -326,12 +380,17 @@ bool QPdfPageNavigator::forwardAvailable() const
}
/*!
- \fn void QPdfPageNavigator::jumped(int page, const QPointF &location, qreal zoom)
+ \fn void QPdfPageNavigator::jumped(QPdfLink current)
- This signal is emitted when an abrupt jump occurs, to the specified \a page
- index, \a location on the page, and \a zoom level; but \e not when simply
+ This signal is emitted when an abrupt jump occurs, to the \a current
+ page index, location on the page, and zoom level; but \e not when simply
scrolling through the document one page at a time. That is, jump(),
forward() and back() emit this signal, but update() does not.
+
+ If \c {current.rectangles.length > 0}, they are rectangles that cover
+ a specific destination area: a search result that should be made
+ visible; otherwise, \c {current.location} is the destination location on
+ the \c page (a hyperlink destination, or during forward/back navigation).
*/
QT_END_NAMESPACE
diff --git a/src/pdf/qpdfpagenavigator.h b/src/pdf/qpdfpagenavigator.h
index 2e92b2dc1..35579a02d 100644
--- a/src/pdf/qpdfpagenavigator.h
+++ b/src/pdf/qpdfpagenavigator.h
@@ -41,6 +41,7 @@
#define QPDFPAGENAVIGATOR_H
#include <QtPdf/qtpdfglobal.h>
+#include <QtPdf/qpdflink.h>
#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
@@ -71,6 +72,7 @@ public:
public Q_SLOTS:
void clear();
+ void jump(QPdfLink destination);
void jump(int page, const QPointF &location, qreal zoom = 0);
void update(int page, const QPointF &location, qreal zoom);
void forward();
@@ -82,7 +84,10 @@ Q_SIGNALS:
void currentZoomChanged(qreal zoom);
void backAvailableChanged(bool available);
void forwardAvailableChanged(bool available);
- void jumped(int page, const QPointF &location, qreal zoom);
+ void jumped(QPdfLink current);
+
+protected:
+ QPdfLink currentLink() const;
private:
QScopedPointer<QPdfPageNavigatorPrivate> d;