summaryrefslogtreecommitdiffstats
path: root/src/pdf/quick/qml
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-02-07 14:54:31 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2020-02-11 08:30:06 +0100
commite5a33355798d3277c631b0024f389cdca2f2c683 (patch)
treebf4ee5e91241a9cafd8dfe185a1174fb27f3114f /src/pdf/quick/qml
parent7afe95f14d7d048a73baa12b3bd5f6a9bcea2ccb (diff)
PDF multipage viewer: iterate search results
This version still has separate PdfSearchModel instances on each page, but now there are buttons to iterate and highlight the search results in order. When you come to the last result on one page, hitting the "Find Next" button will jump to the next page, and keep jumping forward from there until another result is found. Unfortunately this jumping takes time if it skips over a lot of pages because of empty search results. That seems to be another reason to make PdfSearchModel into a whole-document search model and use one instance. Also reorganize PdfMultiPageView.qml's public API into sections according to functionality rather than by type. Change-Id: I677a764fcbf231b2656aff8abe7240a27582a696 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/pdf/quick/qml')
-rw-r--r--src/pdf/quick/qml/PdfMultiPageView.qml100
1 files changed, 68 insertions, 32 deletions
diff --git a/src/pdf/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml
index acef9fbea..bc5134267 100644
--- a/src/pdf/quick/qml/PdfMultiPageView.qml
+++ b/src/pdf/quick/qml/PdfMultiPageView.qml
@@ -58,32 +58,33 @@ Item {
// public API
// TODO 5.15: required property
property var document: undefined
- property real renderScale: 1
- property real pageRotation: 0
- property string searchString
+
property string selectedText
- property alias currentPage: navigationStack.currentPage
function copySelectionToClipboard() {
if (listView.currentItem !== null)
listView.currentItem.selection.copyToClipboard()
}
+
+ // page navigation
+ property alias currentPage: navigationStack.currentPage
property alias backEnabled: navigationStack.backAvailable
property alias forwardEnabled: navigationStack.forwardAvailable
- function back() {
- navigationStack.back()
- }
- function forward() {
- navigationStack.forward()
- }
-
- function resetScale() {
- root.renderScale = 1
+ function back() { navigationStack.back() }
+ function forward() { navigationStack.forward() }
+ 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)
}
+ // page scaling
+ property real renderScale: 1
+ property real pageRotation: 0
+ function resetScale() { root.renderScale = 1 }
function scaleToWidth(width, height) {
root.renderScale = width / (listView.rot90 ? listView.firstPagePointSize.height : listView.firstPagePointSize.width)
}
-
function scaleToPage(width, height) {
var windowAspect = width / height
var pageAspect = listView.firstPagePointSize.width / listView.firstPagePointSize.height
@@ -102,14 +103,39 @@ Item {
}
}
- function goToPage(page) {
- goToLocation(page, Qt.point(0, 0), 0)
+ // text search
+ property alias searchString: searchModel.searchString
+ property bool searchBackEnabled: searchModel.currentResult > 0
+ property bool searchForwardEnabled: searchModel.currentResult < searchModel.matchGeometry.length - 1
+ function searchBack() {
+ if (searchModel.currentResult > 0) {
+ --searchModel.currentResult
+ } else {
+ searchModel.deferRendering = true // save time while we are searching
+ while (searchModel.currentResult <= 0) {
+ if (navigationStack.currentPage > 0)
+ goToPage(navigationStack.currentPage - 1)
+ else
+ goToPage(document.pageCount - 1)
+ searchModel.currentResult = searchModel.matchGeometry.length - 1
+ }
+ searchModel.deferRendering = false
+ }
}
-
- function goToLocation(page, location, zoom) {
- if (zoom > 0)
- root.renderScale = zoom
- navigationStack.push(page, location, zoom)
+ function searchForward() {
+ if (searchModel.currentResult < searchModel.matchGeometry.length - 1) {
+ ++searchModel.currentResult
+ } else {
+ searchModel.deferRendering = true // save time while we are searching
+ while (searchModel.currentResult >= searchModel.matchGeometry.length - 1) {
+ searchModel.currentResult = 0
+ if (navigationStack.currentPage < document.pageCount - 1)
+ goToPage(navigationStack.currentPage + 1)
+ else
+ goToPage(0)
+ }
+ searchModel.deferRendering = false
+ }
}
id: root
@@ -133,7 +159,7 @@ Item {
property real pageScale: image.paintedWidth / pagePointSize.width
Image {
id: image
- source: document.source
+ source: searchModel.deferRendering ? "" : document.source
currentFrame: index
asynchronous: true
fillMode: Image.PreserveAspectFit
@@ -152,18 +178,26 @@ Item {
Shape {
anchors.fill: parent
opacity: 0.25
- visible: image.status === Image.Ready
+ visible: image.status === Image.Ready && searchModel.page == index
ShapePath {
strokeWidth: 1
- strokeColor: "blue"
- fillColor: "cyan"
+ strokeColor: "steelblue"
+ fillColor: "lightsteelblue"
scale: Qt.size(paper.pageScale, paper.pageScale)
PathMultiline {
- id: searchResultBoundaries
paths: searchModel.matchGeometry
}
}
ShapePath {
+ strokeWidth: 1
+ strokeColor: "blue"
+ fillColor: "cyan"
+ scale: Qt.size(paper.pageScale, paper.pageScale)
+ PathPolyline {
+ path: searchModel.matchGeometry[searchModel.currentResult]
+ }
+ }
+ ShapePath {
fillColor: "orange"
scale: Qt.size(paper.pageScale, paper.pageScale)
PathMultiline {
@@ -172,12 +206,6 @@ Item {
}
}
}
- PdfSearchModel {
- id: searchModel
- document: root.document
- page: image.currentFrame
- searchString: root.searchString
- }
PdfSelection {
id: selection
document: root.document
@@ -274,4 +302,12 @@ Item {
onCurrentZoomChanged: root.renderScale = currentZoom
// TODO deal with horizontal location (need another Flickable probably)
}
+ PdfSearchModel {
+ id: searchModel
+ document: root.document === undefined ? null : root.document
+ page: navigationStack.currentPage
+ searchString: root.searchString
+ property int currentResult: 0
+ property bool deferRendering: false
+ }
}