summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-02-05 10:56:48 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2020-02-11 08:29:53 +0100
commit7afe95f14d7d048a73baa12b3bd5f6a9bcea2ccb (patch)
treee264172edcc5869acccd66217b5bd92f63576309
parent92cd38cd4a24e344492c2dd8a7a63e9dacf10553 (diff)
PDF multipage view: track specific link and navigation destinations
Unfortunately it's getting harder to do things declaratively, because we have to avoid circular bindings, and because of needing to use imperative APIs. The current-page spinbox provides onValueModified() to detect when the user modifies it, distinct from the simple fact that the value changed. We shouldn't make bindings to set ListView.currentIndex anyway, because that results in slow animation (and loading pages in all delegates along the way) rather than quick jumping to the correct page. Instead we need to use ListView.positionViewAtIndex(), another imperative API, to get quick jumps without having to calculate and set contentY in some other way. Now we move toward the NavigationStack providing storage for the current destination at all times. Changes there will trigger programmatically moving the ListView. When the user scrolls manually, that generates a "destination" in the navigation stack, such that the back button can jump back to the previous location, and then the forward button can return to the destination where manual scrolling ended up. Fixes: QTBUG-77510 Change-Id: I47544210d2e0f9aa790f3d2594839678374e463d Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--examples/pdf/multipage/viewer.qml4
-rw-r--r--src/pdf/quick/qml/PdfMultiPageView.qml50
-rw-r--r--src/pdf/quick/qquickpdfnavigationstack.cpp1
3 files changed, 41 insertions, 14 deletions
diff --git a/examples/pdf/multipage/viewer.qml b/examples/pdf/multipage/viewer.qml
index 77c06f80f..bbc28cd8d 100644
--- a/examples/pdf/multipage/viewer.qml
+++ b/examples/pdf/multipage/viewer.qml
@@ -139,7 +139,7 @@ ApplicationWindow {
from: 1
to: document.pageCount
editable: true
- onValueChanged: view.currentPage = value - 1
+ onValueModified: view.goToPage(value - 1)
Shortcut {
sequence: StandardKey.MoveToPreviousPage
onActivated: currentPageSB.value--
@@ -256,7 +256,7 @@ ApplicationWindow {
anchors.fill: parent
document: root.document
searchString: searchField.text
- onCurrentPageReallyChanged: currentPageSB.value = page + 1
+ onCurrentPageChanged: currentPageSB.value = view.currentPage + 1
}
footer: ToolBar {
diff --git a/src/pdf/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml
index 095081c5d..acef9fbea 100644
--- a/src/pdf/quick/qml/PdfMultiPageView.qml
+++ b/src/pdf/quick/qml/PdfMultiPageView.qml
@@ -62,16 +62,19 @@ Item {
property real pageRotation: 0
property string searchString
property string selectedText
- property alias currentPage: listView.currentIndex
+ property alias currentPage: navigationStack.currentPage
function copySelectionToClipboard() {
if (listView.currentItem !== null)
listView.currentItem.selection.copyToClipboard()
}
property alias backEnabled: navigationStack.backAvailable
property alias forwardEnabled: navigationStack.forwardAvailable
- function back() { navigationStack.back() }
- function forward() { navigationStack.forward() }
- signal currentPageReallyChanged(page: int)
+ function back() {
+ navigationStack.back()
+ }
+ function forward() {
+ navigationStack.forward()
+ }
function resetScale() {
root.renderScale = 1
@@ -99,6 +102,16 @@ Item {
}
}
+ function goToPage(page) {
+ goToLocation(page, Qt.point(0, 0), 0)
+ }
+
+ function goToLocation(page, location, zoom) {
+ if (zoom > 0)
+ root.renderScale = zoom
+ navigationStack.push(page, location, zoom)
+ }
+
id: root
ListView {
id: listView
@@ -109,11 +122,7 @@ Item {
highlightMoveVelocity: 2000 // TODO increase velocity when setting currentIndex somehow, too
property real rotationModulus: Math.abs(root.pageRotation % 180)
property bool rot90: rotationModulus > 45 && rotationModulus < 135
- property size firstPagePointSize: document.pagePointSize(0)
- onCurrentIndexChanged: {
- navigationStack.push(currentIndex, Qt.point(0, 0), root.renderScale)
- root.currentPageReallyChanged(currentIndex)
- }
+ property size firstPagePointSize: document === undefined ? Qt.size(0, 0) : document.pagePointSize(0)
delegate: Rectangle {
id: paper
implicitWidth: image.width
@@ -233,7 +242,7 @@ Item {
cursorShape: Qt.PointingHandCursor
onClicked: {
if (page >= 0)
- listView.currentIndex = page
+ root.goToLocation(page, location, zoom)
else
Qt.openUrlExternally(url)
}
@@ -241,11 +250,28 @@ Item {
}
}
}
- ScrollBar.vertical: ScrollBar { }
+ ScrollBar.vertical: ScrollBar {
+ property bool moved: false
+ onPositionChanged: moved = true
+ onActiveChanged: {
+ var currentPage = listView.indexAt(0, listView.contentY)
+ var currentItem = listView.itemAtIndex(currentPage)
+ var currentLocation = Qt.point(0, listView.contentY - currentItem.y)
+ if (active) {
+ moved = false
+ navigationStack.push(currentPage, currentLocation, root.renderScale);
+ } else if (moved) {
+ navigationStack.update(currentPage, currentLocation, root.renderScale);
+ }
+ }
+ }
}
PdfNavigationStack {
id: navigationStack
onJumped: listView.currentIndex = page
- onCurrentPageChanged: root.currentPageReallyChanged(navigationStack.currentPage)
+ onCurrentPageChanged: listView.positionViewAtIndex(currentPage, ListView.Beginning)
+ onCurrentLocationChanged: listView.contentY += currentLocation.y // currentPageChanged() MUST occur first!
+ onCurrentZoomChanged: root.renderScale = currentZoom
+ // TODO deal with horizontal location (need another Flickable probably)
}
}
diff --git a/src/pdf/quick/qquickpdfnavigationstack.cpp b/src/pdf/quick/qquickpdfnavigationstack.cpp
index 57acdc4bc..51f65f032 100644
--- a/src/pdf/quick/qquickpdfnavigationstack.cpp
+++ b/src/pdf/quick/qquickpdfnavigationstack.cpp
@@ -56,6 +56,7 @@ Q_LOGGING_CATEGORY(qLcNav, "qt.pdf.navigationstack")
QQuickPdfNavigationStack::QQuickPdfNavigationStack(QObject *parent)
: QObject(parent)
{
+ push(0, QPointF(), 1);
}
/*!