aboutsummaryrefslogtreecommitdiffstats
path: root/examples/pdf/quickpdfviewer/viewer.qml
diff options
context:
space:
mode:
Diffstat (limited to 'examples/pdf/quickpdfviewer/viewer.qml')
-rw-r--r--examples/pdf/quickpdfviewer/viewer.qml307
1 files changed, 307 insertions, 0 deletions
diff --git a/examples/pdf/quickpdfviewer/viewer.qml b/examples/pdf/quickpdfviewer/viewer.qml
new file mode 100644
index 000000000..998c41d20
--- /dev/null
+++ b/examples/pdf/quickpdfviewer/viewer.qml
@@ -0,0 +1,307 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Layouts
+import QtQuick.Pdf
+
+ApplicationWindow {
+ id: root
+ width: 800
+ height: 1024
+ color: "lightgrey"
+ title: document.title
+ visible: true
+ required property url source // for main.py
+ property real scaleStep: Math.sqrt(2)
+
+ header: ToolBar {
+ RowLayout {
+ anchors.fill: parent
+ anchors.rightMargin: 6
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.Open
+ icon.source: "qrc:/pdfviewer/resources/document-open.svg"
+ onTriggered: fileDialog.open()
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.ZoomIn
+ enabled: view.sourceSize.width < 10000
+ icon.source: "qrc:/pdfviewer/resources/zoom-in.svg"
+ onTriggered: view.renderScale *= root.scaleStep
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.ZoomOut
+ enabled: view.sourceSize.width > 50
+ icon.source: "qrc:/pdfviewer/resources/zoom-out.svg"
+ onTriggered: view.renderScale /= root.scaleStep
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "qrc:/pdfviewer/resources/zoom-fit-width.svg"
+ onTriggered: view.scaleToWidth(root.contentItem.width, root.contentItem.height)
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "qrc:/pdfviewer/resources/zoom-fit-best.svg"
+ onTriggered: view.scaleToPage(root.contentItem.width, root.contentItem.height)
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: "Ctrl+0"
+ icon.source: "qrc:/pdfviewer/resources/zoom-original.svg"
+ onTriggered: view.resetScale()
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: "Ctrl+L"
+ icon.source: "qrc:/pdfviewer/resources/rotate-left.svg"
+ onTriggered: view.pageRotation -= 90
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: "Ctrl+R"
+ icon.source: "qrc:/pdfviewer/resources/rotate-right.svg"
+ onTriggered: view.pageRotation += 90
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "qrc:/pdfviewer/resources/go-previous-view-page.svg"
+ enabled: view.backEnabled
+ onTriggered: view.back()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "go back"
+ }
+ SpinBox {
+ id: currentPageSB
+ from: 1
+ to: document.pageCount
+ editable: true
+ value: view.currentPage + 1
+ onValueModified: view.goToPage(value - 1)
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ onActivated: view.goToPage(currentPageSB.value - 2)
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ onActivated: view.goToPage(currentPageSB.value)
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "qrc:/pdfviewer/resources/go-next-view-page.svg"
+ enabled: view.forwardEnabled
+ onTriggered: view.forward()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "go forward"
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.SelectAll
+ icon.source: "qrc:/pdfviewer/resources/edit-select-all.svg"
+ onTriggered: view.selectAll()
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.Copy
+ icon.source: "qrc:/pdfviewer/resources/edit-copy.svg"
+ enabled: view.selectedText !== ""
+ onTriggered: view.copySelectionToClipboard()
+ }
+ }
+ Shortcut {
+ sequence: StandardKey.Find
+ onActivated: searchField.forceActiveFocus()
+ }
+ Shortcut {
+ sequence: StandardKey.Quit
+ onActivated: Qt.quit()
+ }
+ }
+ }
+
+ FileDialog {
+ id: fileDialog
+ title: "Open a PDF file"
+ nameFilters: [ "PDF files (*.pdf)" ]
+ onAccepted: document.source = selectedFile
+ }
+
+ Dialog {
+ id: passwordDialog
+ title: "Password"
+ standardButtons: Dialog.Ok | Dialog.Cancel
+ modal: true
+ closePolicy: Popup.CloseOnEscape
+ anchors.centerIn: parent
+ width: 300
+
+ contentItem: TextField {
+ id: passwordField
+ placeholderText: qsTr("Please provide the password")
+ echoMode: TextInput.Password
+ width: parent.width
+ onAccepted: passwordDialog.accept()
+ }
+ onOpened: function() { passwordField.forceActiveFocus() }
+ onAccepted: document.password = passwordField.text
+ }
+
+ Dialog {
+ id: errorDialog
+ title: "Error loading " + document.source
+ standardButtons: Dialog.Close
+ modal: true
+ closePolicy: Popup.CloseOnEscape
+ anchors.centerIn: parent
+ width: 300
+ visible: document.status === PdfDocument.Error
+
+ contentItem: Label {
+ id: errorField
+ text: document.error
+ }
+ }
+
+ PdfScrollablePageView {
+ id: view
+ anchors.fill: parent
+ anchors.leftMargin: searchDrawer.position * searchDrawer.width
+ document: PdfDocument {
+ id: document
+ source: Qt.resolvedUrl(root.source)
+ onPasswordRequired: passwordDialog.open()
+ }
+ searchString: searchField.text
+ }
+
+ Drawer {
+ id: searchDrawer
+ edge: Qt.LeftEdge
+// modal: false
+// dim: false // commented out as workaround for QTBUG-83859
+ width: 300
+ y: root.header.height
+ height: view.height
+ clip: true
+ ListView {
+ id: searchResultsList
+ anchors.fill: parent
+ anchors.margins: 2
+ model: view.searchModel
+ currentIndex: view.searchModel.currentResult
+ ScrollBar.vertical: ScrollBar { }
+ delegate: ItemDelegate {
+ id: resultDelegate
+ required property int index
+ required property int page
+ required property string contextBefore
+ required property string contextAfter
+ width: parent ? parent.width : 0
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
+ Label {
+ text: "Page " + (resultDelegate.page + 1) + ": "
+ }
+ Label {
+ text: resultDelegate.contextBefore
+ elide: Text.ElideLeft
+ horizontalAlignment: Text.AlignRight
+ Layout.fillWidth: true
+ Layout.preferredWidth: parent.width / 2
+ }
+ Label {
+ font.bold: true
+ text: view.searchString
+ width: implicitWidth
+ }
+ Label {
+ text: resultDelegate.contextAfter
+ elide: Text.ElideRight
+ Layout.fillWidth: true
+ Layout.preferredWidth: parent.width / 2
+ }
+ }
+ highlighted: ListView.isCurrentItem
+ onClicked: view.searchModel.currentResult = resultDelegate.index
+ }
+ }
+ }
+
+ footer: ToolBar {
+ height: footerRow.implicitHeight
+ RowLayout {
+ id: footerRow
+ anchors.fill: parent
+ ToolButton {
+ action: Action {
+ icon.source: "qrc:/pdfviewer/resources/go-up-search.svg"
+ shortcut: StandardKey.FindPrevious
+ onTriggered: view.searchBack()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "find previous"
+ }
+ TextField {
+ id: searchField
+ placeholderText: "search"
+ Layout.minimumWidth: 150
+ Layout.maximumWidth: 300
+ Layout.fillWidth: true
+ onAccepted: searchDrawer.open()
+ Image {
+ visible: searchField.text !== ""
+ source: "qrc:/pdfviewer/resources/edit-clear.svg"
+ anchors {
+ right: parent.right
+ top: parent.top
+ bottom: parent.bottom
+ margins: 3
+ rightMargin: 5
+ }
+ TapHandler {
+ onTapped: searchField.clear()
+ }
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "qrc:/pdfviewer/resources/go-down-search.svg"
+ shortcut: StandardKey.FindNext
+ onTriggered: view.searchForward()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "find next"
+ }
+ Label {
+ Layout.fillWidth: true
+ property size implicitPointSize: document.pagePointSize(view.currentPage)
+ text: "page " + (view.currentPage + 1) + " of " + document.pageCount +
+ " scale " + view.renderScale.toFixed(2) +
+ " original " + implicitPointSize.width.toFixed(1) + "x" + implicitPointSize.height.toFixed(1) + "pts"
+ visible: document.status === PdfDocument.Ready
+ }
+ }
+ }
+}