Fix tray visibility and message reception issues
- Disable sound initialization to prevent hanging
- Add missing import re in utils.py
- Fix settings loading for QSettings
- Update file paths to use PROJECT_ROOT
- Revert to working API paths and listener from commit efdc63e
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
import QtQuick
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
QtObject {
|
||||
property SystemPalette palette: SystemPalette { }
|
||||
function withAlpha(color, alpha) {
|
||||
return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
|
||||
}
|
||||
property color selectionColor: withAlpha(palette.highlight, 0.5)
|
||||
property color pageSearchResultsColor: withAlpha(Qt.lighter(Material.accentColor, 1.5), 0.5)
|
||||
property color currentSearchResultStrokeColor: Material.accentColor
|
||||
property real currentSearchResultStrokeWidth: 2
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
import QtQuick
|
||||
import QtQuick.Controls.Universal
|
||||
|
||||
QtObject {
|
||||
property SystemPalette palette: SystemPalette { }
|
||||
function withAlpha(color, alpha) {
|
||||
return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
|
||||
}
|
||||
property color selectionColor: withAlpha(palette.highlight, 0.5)
|
||||
property color pageSearchResultsColor: withAlpha(Qt.lighter(Universal.accent, 1.5), 0.5)
|
||||
property color currentSearchResultStrokeColor: Universal.accent
|
||||
property real currentSearchResultStrokeWidth: 2
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
/*!
|
||||
\qmltype PdfLinkDelegate
|
||||
\inqmlmodule QtQuick.Pdf
|
||||
\brief A component to decorate hyperlinks on a PDF page.
|
||||
|
||||
PdfLinkDelegate provides the component that QML-based PDF viewers
|
||||
instantiate on top of each hyperlink that is found on each PDF page.
|
||||
|
||||
This component does not provide any visual decoration, because often the
|
||||
hyperlinks will already be formatted in a distinctive way; but when the
|
||||
mouse cursor hovers, it changes to Qt::PointingHandCursor, and a tooltip
|
||||
appears after a delay. Clicking emits the goToLocation() signal if the link
|
||||
is internal, or calls Qt.openUrlExternally() if the link contains a URL.
|
||||
|
||||
\sa PdfPageView, PdfScrollablePageView, PdfMultiPageView
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
required property var link
|
||||
required property rect rectangle
|
||||
required property url url
|
||||
required property int page
|
||||
required property point location
|
||||
required property real zoom
|
||||
|
||||
/*!
|
||||
\qmlsignal PdfLinkDelegate::tapped(link)
|
||||
|
||||
Emitted on mouse click or touch tap. The \a link argument is an
|
||||
instance of QPdfLink with information about the hyperlink.
|
||||
*/
|
||||
signal tapped(var link)
|
||||
|
||||
/*!
|
||||
\qmlsignal PdfLinkDelegate::contextMenuRequested(link)
|
||||
|
||||
Emitted on mouse right-click or touch long-press. The \a link argument
|
||||
is an instance of QPdfLink with information about the hyperlink.
|
||||
*/
|
||||
signal contextMenuRequested(var link)
|
||||
|
||||
HoverHandler {
|
||||
id: linkHH
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
TapHandler {
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: root.tapped(root.link)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
|
||||
acceptedButtons: Qt.RightButton
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: root.contextMenuRequested(root.link)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
onLongPressed: root.contextMenuRequested(root.link)
|
||||
}
|
||||
ToolTip {
|
||||
visible: linkHH.hovered
|
||||
delay: 1000
|
||||
property string destFormat: qsTr("Page %1 location %2, %3 zoom %4")
|
||||
text: root.page >= 0 ?
|
||||
destFormat.arg(root.page + 1).arg(root.location.x.toFixed(1))
|
||||
.arg(root.location.y.toFixed(1)).arg(root.zoom) :
|
||||
root.url
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,623 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Pdf
|
||||
import QtQuick.Shapes
|
||||
|
||||
/*!
|
||||
\qmltype PdfMultiPageView
|
||||
\inqmlmodule QtQuick.Pdf
|
||||
\brief A complete PDF viewer component for scrolling through multiple pages.
|
||||
|
||||
PdfMultiPageView provides a PDF viewer component that offers a user
|
||||
experience similar to many common PDF viewer applications. It supports
|
||||
flicking through the pages in the entire document, with narrow gaps between
|
||||
the page images.
|
||||
|
||||
PdfMultiPageView also supports selecting text and copying it to the
|
||||
clipboard, zooming in and out, clicking an internal link to jump to another
|
||||
section in the document, rotating the view, and searching for text. The
|
||||
\l {PDF Multipage Viewer Example} demonstrates how to use these features
|
||||
in an application.
|
||||
|
||||
The implementation is a QML assembly of smaller building blocks that are
|
||||
available separately. In case you want to make changes in your own version
|
||||
of this component, you can copy the QML, which is installed into the
|
||||
\c QtQuick/Pdf/qml module directory, and modify it as needed.
|
||||
|
||||
\sa PdfPageView, PdfScrollablePageView, PdfStyle
|
||||
*/
|
||||
Item {
|
||||
/*!
|
||||
\qmlproperty PdfDocument PdfMultiPageView::document
|
||||
|
||||
A PdfDocument object with a valid \c source URL is required:
|
||||
|
||||
\snippet multipageview.qml 0
|
||||
*/
|
||||
required property PdfDocument document
|
||||
|
||||
/*!
|
||||
\qmlproperty PdfDocument PdfMultiPageView::selectedText
|
||||
|
||||
The selected text.
|
||||
*/
|
||||
property string selectedText
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::selectAll()
|
||||
|
||||
Selects all the text on the \l {currentPage}{current page}, and makes it
|
||||
available as the system \l {QClipboard::Selection}{selection} on systems
|
||||
that support that feature.
|
||||
|
||||
\sa copySelectionToClipboard()
|
||||
*/
|
||||
function selectAll() {
|
||||
const currentItem = tableView.itemAtCell(tableView.cellAtPos(root.width / 2, root.height / 2))
|
||||
const pdfSelection = currentItem?.selection as PdfSelection
|
||||
pdfSelection?.selectAll()
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::copySelectionToClipboard()
|
||||
|
||||
Copies the selected text (if any) to the
|
||||
\l {QClipboard::Clipboard}{system clipboard}.
|
||||
|
||||
\sa selectAll()
|
||||
*/
|
||||
function copySelectionToClipboard() {
|
||||
const currentItem = tableView.itemAtCell(tableView.cellAtPos(root.width / 2, root.height / 2))
|
||||
const pdfSelection = currentItem?.selection as PdfSelection
|
||||
console.log(lcMPV, "currentItem", currentItem, "sel", pdfSelection?.text)
|
||||
pdfSelection?.copyToClipboard()
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// page navigation
|
||||
|
||||
/*!
|
||||
\qmlproperty int PdfMultiPageView::currentPage
|
||||
\readonly
|
||||
|
||||
This property holds the zero-based page number of the page visible in the
|
||||
scrollable view. If there is no current page, it holds -1.
|
||||
|
||||
This property is read-only, and is typically used in a binding (or
|
||||
\c onCurrentPageChanged script) to update the part of the user interface
|
||||
that shows the current page number, such as a \l SpinBox.
|
||||
|
||||
\sa PdfPageNavigator::currentPage
|
||||
*/
|
||||
property alias currentPage: pageNavigator.currentPage
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PdfMultiPageView::backEnabled
|
||||
\readonly
|
||||
|
||||
This property indicates if it is possible to go back in the navigation
|
||||
history to a previous-viewed page.
|
||||
|
||||
\sa PdfPageNavigator::backAvailable, back()
|
||||
*/
|
||||
property alias backEnabled: pageNavigator.backAvailable
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PdfMultiPageView::forwardEnabled
|
||||
\readonly
|
||||
|
||||
This property indicates if it is possible to go to next location in the
|
||||
navigation history.
|
||||
|
||||
\sa PdfPageNavigator::forwardAvailable, forward()
|
||||
*/
|
||||
property alias forwardEnabled: pageNavigator.forwardAvailable
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::back()
|
||||
|
||||
Scrolls the view back to the previous page that the user visited most
|
||||
recently; or does nothing if there is no previous location on the
|
||||
navigation stack.
|
||||
|
||||
\sa PdfPageNavigator::back(), currentPage, backEnabled
|
||||
*/
|
||||
function back() { pageNavigator.back() }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::forward()
|
||||
|
||||
Scrolls the view to the page that the user was viewing when the back()
|
||||
method was called; or does nothing if there is no "next" location on the
|
||||
navigation stack.
|
||||
|
||||
\sa PdfPageNavigator::forward(), currentPage
|
||||
*/
|
||||
function forward() { pageNavigator.forward() }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::goToPage(int page)
|
||||
|
||||
Scrolls the view to the given \a page number, if possible.
|
||||
|
||||
\sa PdfPageNavigator::jump(), currentPage
|
||||
*/
|
||||
function goToPage(page) {
|
||||
if (page === pageNavigator.currentPage)
|
||||
return
|
||||
goToLocation(page, Qt.point(-1, -1), 0)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::goToLocation(int page, point location, real zoom)
|
||||
|
||||
Scrolls the view to the \a location on the \a page, if possible,
|
||||
and sets the \a zoom level.
|
||||
|
||||
\sa PdfPageNavigator::jump(), currentPage
|
||||
*/
|
||||
function goToLocation(page, location, zoom) {
|
||||
if (tableView.rows === 0) {
|
||||
// save this request for later
|
||||
tableView.pendingRow = page
|
||||
tableView.pendingLocation = location
|
||||
tableView.pendingZoom = zoom
|
||||
return
|
||||
}
|
||||
if (zoom > 0) {
|
||||
pageNavigator.jumping = true // don't call pageNavigator.update() because we will jump() instead
|
||||
root.renderScale = zoom
|
||||
pageNavigator.jumping = false
|
||||
}
|
||||
pageNavigator.jump(page, location, zoom) // actually jump
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty int PdfMultiPageView::currentPageRenderingStatus
|
||||
|
||||
This property holds the \l {QtQuick::Image::status}{rendering status} of
|
||||
the \l {currentPage}{current page}.
|
||||
*/
|
||||
property int currentPageRenderingStatus: Image.Null
|
||||
|
||||
// --------------------------------
|
||||
// page scaling
|
||||
|
||||
/*!
|
||||
\qmlproperty real PdfMultiPageView::renderScale
|
||||
|
||||
This property holds the ratio of pixels to points. The default is \c 1,
|
||||
meaning one point (1/72 of an inch) equals 1 logical pixel.
|
||||
*/
|
||||
property real renderScale: 1
|
||||
|
||||
/*!
|
||||
\qmlproperty real PdfMultiPageView::pageRotation
|
||||
|
||||
This property holds the clockwise rotation of the pages.
|
||||
|
||||
The default value is \c 0 degrees (that is, no rotation relative to the
|
||||
orientation of the pages as stored in the PDF file).
|
||||
*/
|
||||
property real pageRotation: 0
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::resetScale()
|
||||
|
||||
Sets \l renderScale back to its default value of \c 1.
|
||||
*/
|
||||
function resetScale() { root.renderScale = 1 }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::scaleToWidth(real width, real height)
|
||||
|
||||
Sets \l renderScale such that the width of the first page will fit into a
|
||||
viewport with the given \a width and \a height. If the page is not rotated,
|
||||
it will be scaled so that its width fits \a width. If it is rotated +/- 90
|
||||
degrees, it will be scaled so that its width fits \a height.
|
||||
*/
|
||||
function scaleToWidth(width, height) {
|
||||
root.renderScale = width / (tableView.rot90 ? tableView.firstPagePointSize.height : tableView.firstPagePointSize.width)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::scaleToPage(real width, real height)
|
||||
|
||||
Sets \l renderScale such that the whole first page will fit into a viewport
|
||||
with the given \a width and \a height. The resulting \l renderScale depends
|
||||
on \l pageRotation: the page will fit into the viewport at a larger size if
|
||||
it is first rotated to have a matching aspect ratio.
|
||||
*/
|
||||
function scaleToPage(width, height) {
|
||||
const windowAspect = width / height
|
||||
const pageAspect = tableView.firstPagePointSize.width / tableView.firstPagePointSize.height
|
||||
if (tableView.rot90) {
|
||||
if (windowAspect > pageAspect) {
|
||||
root.renderScale = height / tableView.firstPagePointSize.width
|
||||
} else {
|
||||
root.renderScale = width / tableView.firstPagePointSize.height
|
||||
}
|
||||
} else {
|
||||
if (windowAspect > pageAspect) {
|
||||
root.renderScale = height / tableView.firstPagePointSize.height
|
||||
} else {
|
||||
root.renderScale = width / tableView.firstPagePointSize.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// text search
|
||||
|
||||
/*!
|
||||
\qmlproperty PdfSearchModel PdfMultiPageView::searchModel
|
||||
|
||||
This property holds a PdfSearchModel containing the list of search results
|
||||
for a given \l searchString.
|
||||
|
||||
\sa PdfSearchModel
|
||||
*/
|
||||
property alias searchModel: searchModel
|
||||
|
||||
/*!
|
||||
\qmlproperty string PdfMultiPageView::searchString
|
||||
|
||||
This property holds the search string that the user may choose to search
|
||||
for. It is typically used in a binding to the \c text property of a
|
||||
TextField.
|
||||
|
||||
\sa searchModel
|
||||
*/
|
||||
property alias searchString: searchModel.searchString
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::searchBack()
|
||||
|
||||
Decrements the
|
||||
\l{PdfSearchModel::currentResult}{searchModel's current result}
|
||||
so that the view will jump to the previous search result.
|
||||
*/
|
||||
function searchBack() { --searchModel.currentResult }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfMultiPageView::searchForward()
|
||||
|
||||
Increments the
|
||||
\l{PdfSearchModel::currentResult}{searchModel's current result}
|
||||
so that the view will jump to the next search result.
|
||||
*/
|
||||
function searchForward() { ++searchModel.currentResult }
|
||||
|
||||
LoggingCategory {
|
||||
id: lcMPV
|
||||
name: "qt.pdf.multipageview"
|
||||
}
|
||||
|
||||
id: root
|
||||
PdfStyle { id: style }
|
||||
TableView {
|
||||
id: tableView
|
||||
property bool debug: false
|
||||
property real minScale: 0.1
|
||||
property real maxScale: 10
|
||||
property point jumpLocationMargin: Qt.point(10, 10) // px away from viewport edges
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 2
|
||||
model: root.document ? root.document.pageCount : 0
|
||||
rowSpacing: 6
|
||||
property real rotationNorm: Math.round((360 + (root.pageRotation % 360)) % 360)
|
||||
property bool rot90: rotationNorm == 90 || rotationNorm == 270
|
||||
onRot90Changed: forceLayout()
|
||||
onHeightChanged: forceLayout()
|
||||
onWidthChanged: forceLayout()
|
||||
property size firstPagePointSize: root.document?.status === PdfDocument.Ready ? root.document.pagePointSize(0) : Qt.size(1, 1)
|
||||
property real pageHolderWidth: Math.max(root.width, ((rot90 ? root.document?.maxPageHeight : root.document?.maxPageWidth) ?? 0) * root.renderScale)
|
||||
columnWidthProvider: function(col) { return root.document ? pageHolderWidth + vscroll.width + 2 : 0 }
|
||||
rowHeightProvider: function(row) { return (rot90 ? root.document.pagePointSize(row).width : root.document.pagePointSize(row).height) * root.renderScale }
|
||||
|
||||
// delayed-jump feature in case the user called goToPage() or goToLocation() too early
|
||||
property int pendingRow: -1
|
||||
property point pendingLocation
|
||||
property real pendingZoom: -1
|
||||
onRowsChanged: {
|
||||
if (rows > 0 && tableView.pendingRow >= 0) {
|
||||
console.log(lcMPV, "initiating delayed jump to page", tableView.pendingRow, "loc", tableView.pendingLocation, "zoom", tableView.pendingZoom)
|
||||
root.goToLocation(tableView.pendingRow, tableView.pendingLocation, tableView.pendingZoom)
|
||||
tableView.pendingRow = -1
|
||||
tableView.pendingLocation = Qt.point(-1, -1)
|
||||
tableView.pendingZoom = -1
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Rectangle {
|
||||
id: pageHolder
|
||||
required property int index
|
||||
color: tableView.debug ? "beige" : "transparent"
|
||||
Text {
|
||||
visible: tableView.debug
|
||||
anchors { right: parent.right; verticalCenter: parent.verticalCenter }
|
||||
rotation: -90; text: pageHolder.width.toFixed(1) + "x" + pageHolder.height.toFixed(1) + "\n" +
|
||||
image.width.toFixed(1) + "x" + image.height.toFixed(1)
|
||||
}
|
||||
property alias selection: selection
|
||||
Rectangle {
|
||||
id: paper
|
||||
width: image.width
|
||||
height: image.height
|
||||
rotation: root.pageRotation
|
||||
anchors.centerIn: pinch.active ? undefined : parent
|
||||
property size pagePointSize: root.document.pagePointSize(pageHolder.index)
|
||||
property real pageScale: image.paintedWidth / pagePointSize.width
|
||||
PdfPageImage {
|
||||
id: image
|
||||
document: root.document
|
||||
currentFrame: pageHolder.index
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectFit
|
||||
width: paper.pagePointSize.width * root.renderScale
|
||||
height: paper.pagePointSize.height * root.renderScale
|
||||
property real renderScale: root.renderScale
|
||||
property real oldRenderScale: 1
|
||||
onRenderScaleChanged: {
|
||||
image.sourceSize.width = paper.pagePointSize.width * renderScale * Screen.devicePixelRatio
|
||||
image.sourceSize.height = 0
|
||||
paper.scale = 1
|
||||
searchHighlights.update()
|
||||
}
|
||||
onStatusChanged: {
|
||||
if (pageHolder.index === pageNavigator.currentPage)
|
||||
root.currentPageRenderingStatus = status
|
||||
}
|
||||
}
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
visible: image.status === Image.Ready
|
||||
onVisibleChanged: searchHighlights.update()
|
||||
ShapePath {
|
||||
strokeWidth: -1
|
||||
fillColor: style.pageSearchResultsColor
|
||||
scale: Qt.size(paper.pageScale, paper.pageScale)
|
||||
PathMultiline {
|
||||
id: searchHighlights
|
||||
function update() {
|
||||
// paths could be a binding, but we need to be able to "kick" it sometimes
|
||||
paths = searchModel.boundingPolygonsOnPage(pageHolder.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: searchModel
|
||||
// whenever the highlights on the _current_ page change, they actually need to change on _all_ pages
|
||||
// (usually because the search string has changed)
|
||||
function onCurrentPageBoundingPolygonsChanged() { searchHighlights.update() }
|
||||
}
|
||||
ShapePath {
|
||||
strokeWidth: -1
|
||||
fillColor: style.selectionColor
|
||||
scale: Qt.size(paper.pageScale, paper.pageScale)
|
||||
PathMultiline {
|
||||
paths: selection.geometry
|
||||
}
|
||||
}
|
||||
}
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
visible: image.status === Image.Ready && searchModel.currentPage === pageHolder.index
|
||||
ShapePath {
|
||||
strokeWidth: style.currentSearchResultStrokeWidth
|
||||
strokeColor: style.currentSearchResultStrokeColor
|
||||
fillColor: "transparent"
|
||||
scale: Qt.size(paper.pageScale, paper.pageScale)
|
||||
PathMultiline {
|
||||
paths: searchModel.currentResultBoundingPolygons
|
||||
}
|
||||
}
|
||||
}
|
||||
PinchHandler {
|
||||
id: pinch
|
||||
minimumScale: tableView.minScale / root.renderScale
|
||||
maximumScale: Math.max(1, tableView.maxScale / root.renderScale)
|
||||
minimumRotation: root.pageRotation
|
||||
maximumRotation: root.pageRotation
|
||||
onActiveChanged:
|
||||
if (active) {
|
||||
paper.z = 10
|
||||
} else {
|
||||
paper.z = 0
|
||||
const centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
|
||||
pinch.centroid.position.y / root.renderScale)
|
||||
const centroidInFlickable = tableView.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
|
||||
const newSourceWidth = image.sourceSize.width * paper.scale
|
||||
const ratio = newSourceWidth / image.sourceSize.width
|
||||
console.log(lcMPV, "pinch ended on page", pageHolder.index,
|
||||
"with scale", paper.scale.toFixed(3), "ratio", ratio.toFixed(3),
|
||||
"centroid", pinch.centroid.position, centroidInPoints,
|
||||
"wrt flickable", centroidInFlickable,
|
||||
"page at", pageHolder.x.toFixed(2), pageHolder.y.toFixed(2),
|
||||
"contentX/Y were", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2))
|
||||
if (ratio > 1.1 || ratio < 0.9) {
|
||||
const centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
|
||||
paper.scale = 1
|
||||
pinch.persistentScale = 1
|
||||
paper.x = 0
|
||||
paper.y = 0
|
||||
root.renderScale *= ratio
|
||||
tableView.forceLayout()
|
||||
if (tableView.rotationNorm == 0) {
|
||||
tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.x - centroidInFlickable.x
|
||||
tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.y - centroidInFlickable.y
|
||||
} else if (tableView.rotationNorm == 90) {
|
||||
tableView.contentX = pageHolder.x + tableView.originX + image.height - centroidOnPage.y - centroidInFlickable.x
|
||||
tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.x - centroidInFlickable.y
|
||||
} else if (tableView.rotationNorm == 180) {
|
||||
tableView.contentX = pageHolder.x + tableView.originX + image.width - centroidOnPage.x - centroidInFlickable.x
|
||||
tableView.contentY = pageHolder.y + tableView.originY + image.height - centroidOnPage.y - centroidInFlickable.y
|
||||
} else if (tableView.rotationNorm == 270) {
|
||||
tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.y - centroidInFlickable.x
|
||||
tableView.contentY = pageHolder.y + tableView.originY + image.width - centroidOnPage.x - centroidInFlickable.y
|
||||
}
|
||||
console.log(lcMPV, "contentX/Y adjusted to", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2), "y @top", pageHolder.y)
|
||||
tableView.returnToBounds()
|
||||
}
|
||||
}
|
||||
grabPermissions: PointerHandler.CanTakeOverFromAnything
|
||||
}
|
||||
DragHandler {
|
||||
id: textSelectionDrag
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
|
||||
target: null
|
||||
}
|
||||
TapHandler {
|
||||
id: mouseClickHandler
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
|
||||
}
|
||||
TapHandler {
|
||||
id: touchTapHandler
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
onTapped: {
|
||||
selection.clear()
|
||||
selection.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
model: PdfLinkModel {
|
||||
id: linkModel
|
||||
document: root.document
|
||||
page: image.currentFrame
|
||||
}
|
||||
delegate: PdfLinkDelegate {
|
||||
x: rectangle.x * paper.pageScale
|
||||
y: rectangle.y * paper.pageScale
|
||||
width: rectangle.width * paper.pageScale
|
||||
height: rectangle.height * paper.pageScale
|
||||
visible: image.status === Image.Ready
|
||||
onTapped:
|
||||
(link) => {
|
||||
if (link.page >= 0)
|
||||
root.goToLocation(link.page, link.location, link.zoom)
|
||||
else
|
||||
Qt.openUrlExternally(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
PdfSelection {
|
||||
id: selection
|
||||
anchors.fill: parent
|
||||
document: root.document
|
||||
page: image.currentFrame
|
||||
renderScale: image.renderScale
|
||||
from: textSelectionDrag.centroid.pressPosition
|
||||
to: textSelectionDrag.centroid.position
|
||||
hold: !textSelectionDrag.active && !mouseClickHandler.pressed
|
||||
onTextChanged: root.selectedText = text
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
}
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: vscroll
|
||||
property bool moved: false
|
||||
onPositionChanged: moved = true
|
||||
onPressedChanged: if (pressed) {
|
||||
// When the user starts scrolling, push the location where we came from so the user can go "back" there
|
||||
const cell = tableView.cellAtPos(root.width / 2, root.height / 2)
|
||||
const currentItem = tableView.itemAtCell(cell)
|
||||
const currentLocation = currentItem
|
||||
? Qt.point((tableView.contentX - currentItem.x + tableView.jumpLocationMargin.x) / root.renderScale,
|
||||
(tableView.contentY - currentItem.y + tableView.jumpLocationMargin.y) / root.renderScale)
|
||||
: Qt.point(0, 0) // maybe the delegate wasn't loaded yet
|
||||
pageNavigator.jump(cell.y, currentLocation, root.renderScale)
|
||||
}
|
||||
onActiveChanged: if (!active ) {
|
||||
// When the scrollbar stops moving, tell navstack where we are, so as to update currentPage etc.
|
||||
const cell = tableView.cellAtPos(root.width / 2, root.height / 2)
|
||||
const currentItem = tableView.itemAtCell(cell)
|
||||
const currentLocation = currentItem
|
||||
? Qt.point((tableView.contentX - currentItem.x + tableView.jumpLocationMargin.x) / root.renderScale,
|
||||
(tableView.contentY - currentItem.y + tableView.jumpLocationMargin.y) / root.renderScale)
|
||||
: Qt.point(0, 0) // maybe the delegate wasn't loaded yet
|
||||
pageNavigator.update(cell.y, currentLocation, root.renderScale)
|
||||
}
|
||||
}
|
||||
ScrollBar.horizontal: ScrollBar { }
|
||||
}
|
||||
onRenderScaleChanged: {
|
||||
// if pageNavigator.jumped changes the scale, don't turn around and update the stack again;
|
||||
// and don't force layout either, because positionViewAtCell() will do that
|
||||
if (pageNavigator.jumping)
|
||||
return
|
||||
// page size changed: TableView needs to redo layout to avoid overlapping delegates or gaps between them
|
||||
tableView.forceLayout()
|
||||
const cell = tableView.cellAtPos(root.width / 2, root.height / 2)
|
||||
const currentItem = tableView.itemAtCell(cell)
|
||||
if (currentItem) {
|
||||
const currentLocation = Qt.point((tableView.contentX - currentItem.x + tableView.jumpLocationMargin.x) / root.renderScale,
|
||||
(tableView.contentY - currentItem.y + tableView.jumpLocationMargin.y) / root.renderScale)
|
||||
pageNavigator.update(cell.y, currentLocation, renderScale)
|
||||
}
|
||||
}
|
||||
PdfPageNavigator {
|
||||
id: pageNavigator
|
||||
property bool jumping: false
|
||||
property int previousPage: 0
|
||||
onJumped: function(current) {
|
||||
jumping = true
|
||||
if (current.zoom > 0)
|
||||
root.renderScale = current.zoom
|
||||
const pageSize = root.document.pagePointSize(current.page)
|
||||
if (current.location.y < 0) {
|
||||
// invalid to indicate that a specific location was not needed,
|
||||
// so attempt to position the new page just as the current page is
|
||||
const previousPageDelegate = tableView.itemAtCell(0, previousPage)
|
||||
const currentYOffset = previousPageDelegate
|
||||
? tableView.contentY - previousPageDelegate.y
|
||||
: 0
|
||||
tableView.positionViewAtRow(current.page, Qt.AlignTop, currentYOffset)
|
||||
console.log(lcMPV, "going from page", previousPage, "to", current.page, "offset", currentYOffset,
|
||||
"ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
|
||||
} else if (current.rectangles.length > 0) {
|
||||
// jump to a search result and position the covered area within the viewport
|
||||
pageSize.width *= root.renderScale
|
||||
pageSize.height *= root.renderScale
|
||||
const rectPts = current.rectangles[0]
|
||||
const rectPx = Qt.rect(rectPts.x * root.renderScale - tableView.jumpLocationMargin.x,
|
||||
rectPts.y * root.renderScale - tableView.jumpLocationMargin.y,
|
||||
rectPts.width * root.renderScale + tableView.jumpLocationMargin.x * 2,
|
||||
rectPts.height * root.renderScale + tableView.jumpLocationMargin.y * 2)
|
||||
tableView.positionViewAtCell(0, current.page, TableView.Contain, Qt.point(0, 0), rectPx)
|
||||
console.log(lcMPV, "going to zoom", root.renderScale, "rect", rectPx, "on page", current.page,
|
||||
"ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
|
||||
} else {
|
||||
// jump to a page and position the given location relative to the top-left corner of the viewport
|
||||
pageSize.width *= root.renderScale
|
||||
pageSize.height *= root.renderScale
|
||||
const rectPx = Qt.rect(current.location.x * root.renderScale - tableView.jumpLocationMargin.x,
|
||||
current.location.y * root.renderScale - tableView.jumpLocationMargin.y,
|
||||
tableView.jumpLocationMargin.x * 2, tableView.jumpLocationMargin.y * 2)
|
||||
tableView.positionViewAtCell(0, current.page, TableView.AlignLeft | TableView.AlignTop, Qt.point(0, 0), rectPx)
|
||||
console.log(lcMPV, "going to zoom", root.renderScale, "loc", current.location, "on page", current.page,
|
||||
"ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
|
||||
}
|
||||
jumping = false
|
||||
previousPage = current.page
|
||||
}
|
||||
|
||||
property url documentSource: root.document.source
|
||||
onDocumentSourceChanged: {
|
||||
pageNavigator.clear()
|
||||
root.resetScale()
|
||||
tableView.contentX = 0
|
||||
tableView.contentY = 0
|
||||
}
|
||||
}
|
||||
PdfSearchModel {
|
||||
id: searchModel
|
||||
document: root.document === undefined ? null : root.document
|
||||
onCurrentResultChanged: pageNavigator.jump(currentResultLink)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,439 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Pdf
|
||||
import QtQuick.Shapes
|
||||
|
||||
/*!
|
||||
\qmltype PdfPageView
|
||||
\inqmlmodule QtQuick.Pdf
|
||||
\brief A PDF viewer component to show one page a time.
|
||||
|
||||
PdfPageView provides a PDF viewer component that shows one whole page at a
|
||||
time, without scrolling. It supports selecting text and copying it to the
|
||||
clipboard, zooming in and out, clicking an internal link to jump to another
|
||||
section in the document, rotating the view, and searching for text.
|
||||
|
||||
The implementation is a QML assembly of smaller building blocks that are
|
||||
available separately. In case you want to make changes in your own version
|
||||
of this component, you can copy the QML, which is installed into the
|
||||
\c QtQuick/Pdf/qml module directory, and modify it as needed.
|
||||
|
||||
\sa PdfScrollablePageView, PdfMultiPageView, PdfStyle
|
||||
*/
|
||||
Rectangle {
|
||||
/*!
|
||||
\qmlproperty PdfDocument PdfPageView::document
|
||||
|
||||
A PdfDocument object with a valid \c source URL is required:
|
||||
|
||||
\snippet pdfpageview.qml 0
|
||||
*/
|
||||
required property PdfDocument document
|
||||
|
||||
/*!
|
||||
\qmlproperty int PdfPageView::status
|
||||
|
||||
This property holds the \l {QtQuick::Image::status}{rendering status} of
|
||||
the \l {currentPage}{current page}.
|
||||
*/
|
||||
property alias status: image.status
|
||||
|
||||
/*!
|
||||
\qmlproperty PdfDocument PdfPageView::selectedText
|
||||
|
||||
The selected text.
|
||||
*/
|
||||
property alias selectedText: selection.text
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::selectAll()
|
||||
|
||||
Selects all the text on the \l {currentPage}{current page}, and makes it
|
||||
available as the system \l {QClipboard::Selection}{selection} on systems
|
||||
that support that feature.
|
||||
|
||||
\sa copySelectionToClipboard()
|
||||
*/
|
||||
function selectAll() {
|
||||
selection.selectAll()
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::copySelectionToClipboard()
|
||||
|
||||
Copies the selected text (if any) to the
|
||||
\l {QClipboard::Clipboard}{system clipboard}.
|
||||
|
||||
\sa selectAll()
|
||||
*/
|
||||
function copySelectionToClipboard() {
|
||||
selection.copyToClipboard()
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// page navigation
|
||||
|
||||
/*!
|
||||
\qmlproperty int PdfPageView::currentPage
|
||||
\readonly
|
||||
|
||||
This property holds the zero-based page number of the page visible in the
|
||||
scrollable view. If there is no current page, it holds -1.
|
||||
|
||||
This property is read-only, and is typically used in a binding (or
|
||||
\c onCurrentPageChanged script) to update the part of the user interface
|
||||
that shows the current page number, such as a \l SpinBox.
|
||||
|
||||
\sa PdfPageNavigator::currentPage
|
||||
*/
|
||||
property alias currentPage: pageNavigator.currentPage
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PdfPageView::backEnabled
|
||||
\readonly
|
||||
|
||||
This property indicates if it is possible to go back in the navigation
|
||||
history to a previous-viewed page.
|
||||
|
||||
\sa PdfPageNavigator::backAvailable, back()
|
||||
*/
|
||||
property alias backEnabled: pageNavigator.backAvailable
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PdfPageView::forwardEnabled
|
||||
\readonly
|
||||
|
||||
This property indicates if it is possible to go to next location in the
|
||||
navigation history.
|
||||
|
||||
\sa PdfPageNavigator::forwardAvailable, forward()
|
||||
*/
|
||||
property alias forwardEnabled: pageNavigator.forwardAvailable
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::back()
|
||||
|
||||
Scrolls the view back to the previous page that the user visited most
|
||||
recently; or does nothing if there is no previous location on the
|
||||
navigation stack.
|
||||
|
||||
\sa PdfPageNavigator::back(), currentPage, backEnabled
|
||||
*/
|
||||
function back() { pageNavigator.back() }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::forward()
|
||||
|
||||
Scrolls the view to the page that the user was viewing when the back()
|
||||
method was called; or does nothing if there is no "next" location on the
|
||||
navigation stack.
|
||||
|
||||
\sa PdfPageNavigator::forward(), currentPage
|
||||
*/
|
||||
function forward() { pageNavigator.forward() }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::goToPage(int page)
|
||||
|
||||
Changes the view to the \a page, if possible.
|
||||
|
||||
\sa PdfPageNavigator::jump(), currentPage
|
||||
*/
|
||||
function goToPage(page) { goToLocation(page, Qt.point(0, 0), 0) }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::goToLocation(int page, point location, real zoom)
|
||||
|
||||
Scrolls the view to the \a location on the \a page, if possible,
|
||||
and sets the \a zoom level.
|
||||
|
||||
\sa PdfPageNavigator::jump(), currentPage
|
||||
*/
|
||||
function goToLocation(page, location, zoom) {
|
||||
if (zoom > 0)
|
||||
root.renderScale = zoom
|
||||
pageNavigator.jump(page, location, zoom)
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// page scaling
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PdfPageView::zoomEnabled
|
||||
|
||||
This property holds whether the user can use the pinch gesture or
|
||||
Control + mouse wheel to zoom. The default is \c true.
|
||||
|
||||
When the user zooms the page, the size of PdfPageView changes.
|
||||
*/
|
||||
property bool zoomEnabled: true
|
||||
|
||||
/*!
|
||||
\qmlproperty real PdfPageView::renderScale
|
||||
|
||||
This property holds the ratio of pixels to points. The default is \c 1,
|
||||
meaning one point (1/72 of an inch) equals 1 logical pixel.
|
||||
*/
|
||||
property real renderScale: 1
|
||||
|
||||
/*!
|
||||
\qmlproperty size PdfPageView::sourceSize
|
||||
|
||||
This property holds the scaled width and height of the full-frame image.
|
||||
|
||||
\sa {QtQuick::Image::sourceSize}{Image.sourceSize}
|
||||
*/
|
||||
property alias sourceSize: image.sourceSize
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::resetScale()
|
||||
|
||||
Sets \l renderScale back to its default value of \c 1.
|
||||
*/
|
||||
function resetScale() {
|
||||
image.sourceSize.width = 0
|
||||
image.sourceSize.height = 0
|
||||
root.scale = 1
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::scaleToWidth(real width, real height)
|
||||
|
||||
Sets \l renderScale such that the width of the first page will fit into a
|
||||
viewport with the given \a width and \a height. If the page is not rotated,
|
||||
it will be scaled so that its width fits \a width. If it is rotated +/- 90
|
||||
degrees, it will be scaled so that its width fits \a height.
|
||||
*/
|
||||
function scaleToWidth(width, height) {
|
||||
const halfRotation = Math.abs(root.rotation % 180)
|
||||
image.sourceSize = Qt.size((halfRotation > 45 && halfRotation < 135) ? height : width, 0)
|
||||
image.centerInSize = Qt.size(width, height)
|
||||
image.centerOnLoad = true
|
||||
image.vCenterOnLoad = (halfRotation > 45 && halfRotation < 135)
|
||||
root.scale = 1
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::scaleToPage(real width, real height)
|
||||
|
||||
Sets \l renderScale such that the whole first page will fit into a viewport
|
||||
with the given \a width and \a height. The resulting \l renderScale depends
|
||||
on page rotation: the page will fit into the viewport at a larger size if it
|
||||
is first rotated to have a matching aspect ratio.
|
||||
*/
|
||||
function scaleToPage(width, height) {
|
||||
const windowAspect = width / height
|
||||
const halfRotation = Math.abs(root.rotation % 180)
|
||||
const pagePointSize = document.pagePointSize(pageNavigator.currentPage)
|
||||
const pageAspect = pagePointSize.height / pagePointSize.width
|
||||
if (halfRotation > 45 && halfRotation < 135) {
|
||||
// rotated 90 or 270º
|
||||
if (windowAspect > pageAspect) {
|
||||
image.sourceSize = Qt.size(height, 0)
|
||||
} else {
|
||||
image.sourceSize = Qt.size(0, width)
|
||||
}
|
||||
} else {
|
||||
if (windowAspect > pageAspect) {
|
||||
image.sourceSize = Qt.size(0, height)
|
||||
} else {
|
||||
image.sourceSize = Qt.size(width, 0)
|
||||
}
|
||||
}
|
||||
image.centerInSize = Qt.size(width, height)
|
||||
image.centerOnLoad = true
|
||||
image.vCenterOnLoad = true
|
||||
root.scale = 1
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// text search
|
||||
|
||||
/*!
|
||||
\qmlproperty PdfSearchModel PdfPageView::searchModel
|
||||
|
||||
This property holds a PdfSearchModel containing the list of search results
|
||||
for a given \l searchString.
|
||||
|
||||
\sa PdfSearchModel
|
||||
*/
|
||||
property alias searchModel: searchModel
|
||||
|
||||
/*!
|
||||
\qmlproperty string PdfPageView::searchString
|
||||
|
||||
This property holds the search string that the user may choose to search
|
||||
for. It is typically used in a binding to the \c text property of a
|
||||
TextField.
|
||||
|
||||
\sa searchModel
|
||||
*/
|
||||
property alias searchString: searchModel.searchString
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::searchBack()
|
||||
|
||||
Decrements the
|
||||
\l{PdfSearchModel::currentResult}{searchModel's current result}
|
||||
so that the view will jump to the previous search result.
|
||||
*/
|
||||
function searchBack() { --searchModel.currentResult }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfPageView::searchForward()
|
||||
|
||||
Increments the
|
||||
\l{PdfSearchModel::currentResult}{searchModel's current result}
|
||||
so that the view will jump to the next search result.
|
||||
*/
|
||||
function searchForward() { ++searchModel.currentResult }
|
||||
|
||||
// --------------------------------
|
||||
// implementation
|
||||
id: root
|
||||
width: image.width
|
||||
height: image.height
|
||||
|
||||
PdfSelection {
|
||||
id: selection
|
||||
document: root.document
|
||||
page: pageNavigator.currentPage
|
||||
from: Qt.point(textSelectionDrag.centroid.pressPosition.x / image.pageScale, textSelectionDrag.centroid.pressPosition.y / image.pageScale)
|
||||
to: Qt.point(textSelectionDrag.centroid.position.x / image.pageScale, textSelectionDrag.centroid.position.y / image.pageScale)
|
||||
hold: !textSelectionDrag.active && !tapHandler.pressed
|
||||
}
|
||||
|
||||
PdfSearchModel {
|
||||
id: searchModel
|
||||
document: root.document === undefined ? null : root.document
|
||||
onCurrentPageChanged: root.goToPage(currentPage)
|
||||
}
|
||||
|
||||
PdfPageNavigator {
|
||||
id: pageNavigator
|
||||
onCurrentPageChanged: searchModel.currentPage = currentPage
|
||||
onCurrentZoomChanged: root.renderScale = currentZoom
|
||||
|
||||
property url documentSource: root.document.source
|
||||
onDocumentSourceChanged: {
|
||||
pageNavigator.clear()
|
||||
root.goToPage(0)
|
||||
}
|
||||
}
|
||||
|
||||
PdfPageImage {
|
||||
id: image
|
||||
document: root.document
|
||||
currentFrame: pageNavigator.currentPage
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectFit
|
||||
property bool centerOnLoad: false
|
||||
property bool vCenterOnLoad: false
|
||||
property size centerInSize
|
||||
property real pageScale: image.paintedWidth / document.pagePointSize(pageNavigator.currentPage).width
|
||||
function reRenderIfNecessary() {
|
||||
const newSourceWidth = image.sourceSize.width * root.scale * Screen.devicePixelRatio
|
||||
const ratio = newSourceWidth / image.sourceSize.width
|
||||
if (ratio > 1.1 || ratio < 0.9) {
|
||||
image.sourceSize.width = newSourceWidth
|
||||
image.sourceSize.height = 0
|
||||
root.scale = 1
|
||||
}
|
||||
}
|
||||
onStatusChanged:
|
||||
if (status == Image.Ready && centerOnLoad) {
|
||||
root.x = (centerInSize.width - image.implicitWidth) / 2
|
||||
root.y = vCenterOnLoad ? (centerInSize.height - image.implicitHeight) / 2 : 0
|
||||
centerOnLoad = false
|
||||
vCenterOnLoad = false
|
||||
}
|
||||
}
|
||||
onRenderScaleChanged: {
|
||||
image.sourceSize.width = document.pagePointSize(pageNavigator.currentPage).width * renderScale
|
||||
image.sourceSize.height = 0
|
||||
root.scale = 1
|
||||
}
|
||||
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
opacity: 0.25
|
||||
visible: image.status === Image.Ready
|
||||
ShapePath {
|
||||
strokeWidth: 1
|
||||
strokeColor: "cyan"
|
||||
fillColor: "steelblue"
|
||||
scale: Qt.size(image.pageScale, image.pageScale)
|
||||
PathMultiline {
|
||||
paths: searchModel.currentPageBoundingPolygons
|
||||
}
|
||||
}
|
||||
ShapePath {
|
||||
strokeWidth: 1
|
||||
strokeColor: "orange"
|
||||
fillColor: "cyan"
|
||||
scale: Qt.size(image.pageScale, image.pageScale)
|
||||
PathMultiline {
|
||||
paths: searchModel.currentResultBoundingPolygons
|
||||
}
|
||||
}
|
||||
ShapePath {
|
||||
fillColor: "orange"
|
||||
scale: Qt.size(image.pageScale, image.pageScale)
|
||||
PathMultiline {
|
||||
paths: selection.geometry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: PdfLinkModel {
|
||||
id: linkModel
|
||||
document: root.document
|
||||
page: pageNavigator.currentPage
|
||||
}
|
||||
delegate: PdfLinkDelegate {
|
||||
x: rectangle.x * image.pageScale
|
||||
y: rectangle.y * image.pageScale
|
||||
width: rectangle.width * image.pageScale
|
||||
height: rectangle.height * image.pageScale
|
||||
visible: image.status === Image.Ready
|
||||
onTapped:
|
||||
(link) => {
|
||||
if (link.page >= 0)
|
||||
pageNavigator.jump(link)
|
||||
else
|
||||
Qt.openUrlExternally(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PinchHandler {
|
||||
id: pinch
|
||||
enabled: root.zoomEnabled && root.scale * root.renderScale <= 10 && root.scale * root.renderScale >= 0.1
|
||||
minimumScale: 0.1
|
||||
maximumScale: 10
|
||||
minimumRotation: 0
|
||||
maximumRotation: 0
|
||||
onActiveChanged: if (!active) image.reRenderIfNecessary()
|
||||
grabPermissions: PinchHandler.TakeOverForbidden // don't allow takeover if pinch has started
|
||||
}
|
||||
WheelHandler {
|
||||
enabled: pinch.enabled
|
||||
acceptedModifiers: Qt.ControlModifier
|
||||
property: "scale"
|
||||
onActiveChanged: if (!active) image.reRenderIfNecessary()
|
||||
}
|
||||
DragHandler {
|
||||
id: textSelectionDrag
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
|
||||
target: null
|
||||
}
|
||||
TapHandler {
|
||||
id: tapHandler
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Pdf
|
||||
import QtQuick.Shapes
|
||||
|
||||
/*!
|
||||
\qmltype PdfScrollablePageView
|
||||
\inqmlmodule QtQuick.Pdf
|
||||
\brief A complete PDF viewer component to show one page a time, with scrolling.
|
||||
|
||||
PdfScrollablePageView provides a PDF viewer component that shows one page
|
||||
at a time, with scrollbars to move around the page. It also supports
|
||||
selecting text and copying it to the clipboard, zooming in and out,
|
||||
clicking an internal link to jump to another section in the document,
|
||||
rotating the view, and searching for text. The pdfviewer example
|
||||
demonstrates how to use these features in an application.
|
||||
|
||||
The implementation is a QML assembly of smaller building blocks that are
|
||||
available separately. In case you want to make changes in your own version
|
||||
of this component, you can copy the QML, which is installed into the
|
||||
\c QtQuick/Pdf/qml module directory, and modify it as needed.
|
||||
|
||||
\sa PdfPageView, PdfMultiPageView, PdfStyle
|
||||
*/
|
||||
Flickable {
|
||||
/*!
|
||||
\qmlproperty PdfDocument PdfScrollablePageView::document
|
||||
|
||||
A PdfDocument object with a valid \c source URL is required:
|
||||
|
||||
\snippet multipageview.qml 0
|
||||
*/
|
||||
required property PdfDocument document
|
||||
|
||||
/*!
|
||||
\qmlproperty int PdfScrollablePageView::status
|
||||
|
||||
This property holds the \l {QtQuick::Image::status}{rendering status} of
|
||||
the \l {currentPage}{current page}.
|
||||
*/
|
||||
property alias status: image.status
|
||||
|
||||
/*!
|
||||
\qmlproperty PdfDocument PdfScrollablePageView::selectedText
|
||||
|
||||
The selected text.
|
||||
*/
|
||||
property alias selectedText: selection.text
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::selectAll()
|
||||
|
||||
Selects all the text on the \l {currentPage}{current page}, and makes it
|
||||
available as the system \l {QClipboard::Selection}{selection} on systems
|
||||
that support that feature.
|
||||
|
||||
\sa copySelectionToClipboard()
|
||||
*/
|
||||
function selectAll() {
|
||||
selection.selectAll()
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::copySelectionToClipboard()
|
||||
|
||||
Copies the selected text (if any) to the
|
||||
\l {QClipboard::Clipboard}{system clipboard}.
|
||||
|
||||
\sa selectAll()
|
||||
*/
|
||||
function copySelectionToClipboard() {
|
||||
selection.copyToClipboard()
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// page navigation
|
||||
|
||||
/*!
|
||||
\qmlproperty int PdfScrollablePageView::currentPage
|
||||
\readonly
|
||||
|
||||
This property holds the zero-based page number of the page visible in the
|
||||
scrollable view. If there is no current page, it holds -1.
|
||||
|
||||
This property is read-only, and is typically used in a binding (or
|
||||
\c onCurrentPageChanged script) to update the part of the user interface
|
||||
that shows the current page number, such as a \l SpinBox.
|
||||
|
||||
\sa PdfPageNavigator::currentPage
|
||||
*/
|
||||
property alias currentPage: pageNavigator.currentPage
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PdfScrollablePageView::backEnabled
|
||||
\readonly
|
||||
|
||||
This property indicates if it is possible to go back in the navigation
|
||||
history to a previous-viewed page.
|
||||
|
||||
\sa PdfPageNavigator::backAvailable, back()
|
||||
*/
|
||||
property alias backEnabled: pageNavigator.backAvailable
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PdfScrollablePageView::forwardEnabled
|
||||
\readonly
|
||||
|
||||
This property indicates if it is possible to go to next location in the
|
||||
navigation history.
|
||||
|
||||
\sa PdfPageNavigator::forwardAvailable, forward()
|
||||
*/
|
||||
property alias forwardEnabled: pageNavigator.forwardAvailable
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::back()
|
||||
|
||||
Scrolls the view back to the previous page that the user visited most
|
||||
recently; or does nothing if there is no previous location on the
|
||||
navigation stack.
|
||||
|
||||
\sa PdfPageNavigator::back(), currentPage, backEnabled
|
||||
*/
|
||||
function back() { pageNavigator.back() }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::forward()
|
||||
|
||||
Scrolls the view to the page that the user was viewing when the back()
|
||||
method was called; or does nothing if there is no "next" location on the
|
||||
navigation stack.
|
||||
|
||||
\sa PdfPageNavigator::forward(), currentPage
|
||||
*/
|
||||
function forward() { pageNavigator.forward() }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::goToPage(int page)
|
||||
|
||||
Changes the view to the \a page, if possible.
|
||||
|
||||
\sa PdfPageNavigator::jump(), currentPage
|
||||
*/
|
||||
function goToPage(page) {
|
||||
if (page === pageNavigator.currentPage)
|
||||
return
|
||||
goToLocation(page, Qt.point(0, 0), 0)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::goToLocation(int page, point location, real zoom)
|
||||
|
||||
Scrolls the view to the \a location on the \a page, if possible,
|
||||
and sets the \a zoom level.
|
||||
|
||||
\sa PdfPageNavigator::jump(), currentPage
|
||||
*/
|
||||
function goToLocation(page, location, zoom) {
|
||||
if (zoom > 0)
|
||||
root.renderScale = zoom
|
||||
pageNavigator.jump(page, location, zoom)
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// page scaling
|
||||
|
||||
/*!
|
||||
\qmlproperty real PdfScrollablePageView::renderScale
|
||||
|
||||
This property holds the ratio of pixels to points. The default is \c 1,
|
||||
meaning one point (1/72 of an inch) equals 1 logical pixel.
|
||||
*/
|
||||
property real renderScale: 1
|
||||
|
||||
/*!
|
||||
\qmlproperty real PdfScrollablePageView::pageRotation
|
||||
|
||||
This property holds the clockwise rotation of the pages.
|
||||
|
||||
The default value is \c 0 degrees (that is, no rotation relative to the
|
||||
orientation of the pages as stored in the PDF file).
|
||||
*/
|
||||
property real pageRotation: 0
|
||||
|
||||
/*!
|
||||
\qmlproperty size PdfScrollablePageView::sourceSize
|
||||
|
||||
This property holds the scaled width and height of the full-frame image.
|
||||
|
||||
\sa {QtQuick::Image::sourceSize}{Image.sourceSize}
|
||||
*/
|
||||
property alias sourceSize: image.sourceSize
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::resetScale()
|
||||
|
||||
Sets \l renderScale back to its default value of \c 1.
|
||||
*/
|
||||
function resetScale() {
|
||||
paper.scale = 1
|
||||
root.renderScale = 1
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::scaleToWidth(real width, real height)
|
||||
|
||||
Sets \l renderScale such that the width of the first page will fit into a
|
||||
viewport with the given \a width and \a height. If the page is not rotated,
|
||||
it will be scaled so that its width fits \a width. If it is rotated +/- 90
|
||||
degrees, it will be scaled so that its width fits \a height.
|
||||
*/
|
||||
function scaleToWidth(width, height) {
|
||||
const pagePointSize = document.pagePointSize(pageNavigator.currentPage)
|
||||
root.renderScale = root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width)
|
||||
console.log(lcSPV, "scaling", pagePointSize, "to fit", root.width, "rotated?", paper.rot90, "scale", root.renderScale)
|
||||
root.contentX = 0
|
||||
root.contentY = 0
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::scaleToPage(real width, real height)
|
||||
|
||||
Sets \l renderScale such that the whole first page will fit into a viewport
|
||||
with the given \a width and \a height. The resulting \l renderScale depends
|
||||
on \l pageRotation: the page will fit into the viewport at a larger size if
|
||||
it is first rotated to have a matching aspect ratio.
|
||||
*/
|
||||
function scaleToPage(width, height) {
|
||||
const pagePointSize = document.pagePointSize(pageNavigator.currentPage)
|
||||
root.renderScale = Math.min(
|
||||
root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width),
|
||||
root.height / (paper.rot90 ? pagePointSize.width : pagePointSize.height) )
|
||||
root.contentX = 0
|
||||
root.contentY = 0
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// text search
|
||||
|
||||
/*!
|
||||
\qmlproperty PdfSearchModel PdfScrollablePageView::searchModel
|
||||
|
||||
This property holds a PdfSearchModel containing the list of search results
|
||||
for a given \l searchString.
|
||||
|
||||
\sa PdfSearchModel
|
||||
*/
|
||||
property alias searchModel: searchModel
|
||||
|
||||
/*!
|
||||
\qmlproperty string PdfScrollablePageView::searchString
|
||||
|
||||
This property holds the search string that the user may choose to search
|
||||
for. It is typically used in a binding to the \c text property of a
|
||||
TextField.
|
||||
|
||||
\sa searchModel
|
||||
*/
|
||||
property alias searchString: searchModel.searchString
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::searchBack()
|
||||
|
||||
Decrements the
|
||||
\l{PdfSearchModel::currentResult}{searchModel's current result}
|
||||
so that the view will jump to the previous search result.
|
||||
*/
|
||||
function searchBack() { --searchModel.currentResult }
|
||||
|
||||
/*!
|
||||
\qmlmethod void PdfScrollablePageView::searchForward()
|
||||
|
||||
Increments the
|
||||
\l{PdfSearchModel::currentResult}{searchModel's current result}
|
||||
so that the view will jump to the next search result.
|
||||
*/
|
||||
function searchForward() { ++searchModel.currentResult }
|
||||
|
||||
// --------------------------------
|
||||
// implementation
|
||||
id: root
|
||||
PdfStyle { id: style }
|
||||
contentWidth: paper.width
|
||||
contentHeight: paper.height
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
onActiveChanged:
|
||||
if (!active ) {
|
||||
const currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
|
||||
(root.contentY + root.height / 2) / root.renderScale)
|
||||
pageNavigator.update(pageNavigator.currentPage, currentLocation, root.renderScale)
|
||||
}
|
||||
}
|
||||
ScrollBar.horizontal: ScrollBar {
|
||||
onActiveChanged:
|
||||
if (!active ) {
|
||||
const currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
|
||||
(root.contentY + root.height / 2) / root.renderScale)
|
||||
pageNavigator.update(pageNavigator.currentPage, currentLocation, root.renderScale)
|
||||
}
|
||||
}
|
||||
|
||||
onRenderScaleChanged: {
|
||||
paper.scale = 1
|
||||
const currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
|
||||
(root.contentY + root.height / 2) / root.renderScale)
|
||||
pageNavigator.update(pageNavigator.currentPage, currentLocation, root.renderScale)
|
||||
}
|
||||
|
||||
PdfSearchModel {
|
||||
id: searchModel
|
||||
document: root.document === undefined ? null : root.document
|
||||
onCurrentResultChanged: pageNavigator.jump(currentResultLink)
|
||||
}
|
||||
|
||||
PdfPageNavigator {
|
||||
id: pageNavigator
|
||||
onJumped: function(current) {
|
||||
root.renderScale = current.zoom
|
||||
const dx = Math.max(0, current.location.x * root.renderScale - root.width / 2) - root.contentX
|
||||
const dy = Math.max(0, current.location.y * root.renderScale - root.height / 2) - root.contentY
|
||||
// don't jump if location is in the viewport already, i.e. if the "error" between desired and actual contentX/Y is small
|
||||
if (Math.abs(dx) > root.width / 3)
|
||||
root.contentX += dx
|
||||
if (Math.abs(dy) > root.height / 3)
|
||||
root.contentY += dy
|
||||
console.log(lcSPV, "going to zoom", current.zoom, "loc", current.location,
|
||||
"on page", current.page, "ended up @", root.contentX + ", " + root.contentY)
|
||||
}
|
||||
onCurrentPageChanged: searchModel.currentPage = currentPage
|
||||
|
||||
property url documentSource: root.document.source
|
||||
onDocumentSourceChanged: {
|
||||
pageNavigator.clear()
|
||||
root.resetScale()
|
||||
root.contentX = 0
|
||||
root.contentY = 0
|
||||
}
|
||||
}
|
||||
|
||||
LoggingCategory {
|
||||
id: lcSPV
|
||||
name: "qt.pdf.singlepageview"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: paper
|
||||
width: rot90 ? image.height : image.width
|
||||
height: rot90 ? image.width : image.height
|
||||
property real rotationModulus: Math.abs(root.pageRotation % 180)
|
||||
property bool rot90: rotationModulus > 45 && rotationModulus < 135
|
||||
property real minScale: 0.1
|
||||
property real maxScale: 10
|
||||
|
||||
PdfPageImage {
|
||||
id: image
|
||||
document: root.document
|
||||
currentFrame: pageNavigator.currentPage
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectFit
|
||||
rotation: root.pageRotation
|
||||
anchors.centerIn: parent
|
||||
property real pageScale: image.paintedWidth / document.pagePointSize(pageNavigator.currentPage).width
|
||||
width: document.pagePointSize(pageNavigator.currentPage).width * root.renderScale
|
||||
height: document.pagePointSize(pageNavigator.currentPage).height * root.renderScale
|
||||
sourceSize.width: width * Screen.devicePixelRatio
|
||||
sourceSize.height: 0
|
||||
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
visible: image.status === Image.Ready
|
||||
ShapePath {
|
||||
strokeWidth: -1
|
||||
fillColor: style.pageSearchResultsColor
|
||||
scale: Qt.size(image.pageScale, image.pageScale)
|
||||
PathMultiline {
|
||||
paths: searchModel.currentPageBoundingPolygons
|
||||
}
|
||||
}
|
||||
ShapePath {
|
||||
strokeWidth: style.currentSearchResultStrokeWidth
|
||||
strokeColor: style.currentSearchResultStrokeColor
|
||||
fillColor: "transparent"
|
||||
scale: Qt.size(image.pageScale, image.pageScale)
|
||||
PathMultiline {
|
||||
paths: searchModel.currentResultBoundingPolygons
|
||||
}
|
||||
}
|
||||
ShapePath {
|
||||
fillColor: style.selectionColor
|
||||
scale: Qt.size(image.pageScale, image.pageScale)
|
||||
PathMultiline {
|
||||
paths: selection.geometry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: PdfLinkModel {
|
||||
id: linkModel
|
||||
document: root.document
|
||||
page: pageNavigator.currentPage
|
||||
}
|
||||
delegate: PdfLinkDelegate {
|
||||
x: rectangle.x * image.pageScale
|
||||
y: rectangle.y * image.pageScale
|
||||
width: rectangle.width * image.pageScale
|
||||
height: rectangle.height * image.pageScale
|
||||
visible: image.status === Image.Ready
|
||||
onTapped:
|
||||
(link) => {
|
||||
if (link.page >= 0)
|
||||
pageNavigator.jump(link.page, link.location, link.zoom)
|
||||
else
|
||||
Qt.openUrlExternally(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
DragHandler {
|
||||
id: textSelectionDrag
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
|
||||
target: null
|
||||
}
|
||||
TapHandler {
|
||||
id: mouseClickHandler
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
|
||||
}
|
||||
TapHandler {
|
||||
id: touchTapHandler
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
onTapped: {
|
||||
selection.clear()
|
||||
selection.focus = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PdfSelection {
|
||||
id: selection
|
||||
anchors.fill: parent
|
||||
document: root.document
|
||||
page: pageNavigator.currentPage
|
||||
renderScale: image.pageScale == 0 ? 1.0 : image.pageScale
|
||||
from: textSelectionDrag.centroid.pressPosition
|
||||
to: textSelectionDrag.centroid.position
|
||||
hold: !textSelectionDrag.active && !mouseClickHandler.pressed
|
||||
focus: true
|
||||
}
|
||||
|
||||
PinchHandler {
|
||||
id: pinch
|
||||
minimumScale: paper.minScale / root.renderScale
|
||||
maximumScale: Math.max(1, paper.maxScale / root.renderScale)
|
||||
minimumRotation: 0
|
||||
maximumRotation: 0
|
||||
onActiveChanged:
|
||||
if (!active) {
|
||||
const centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
|
||||
pinch.centroid.position.y / root.renderScale)
|
||||
const centroidInFlickable = root.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
|
||||
const newSourceWidth = image.sourceSize.width * paper.scale
|
||||
const ratio = newSourceWidth / image.sourceSize.width
|
||||
console.log(lcSPV, "pinch ended with centroid", pinch.centroid.position, centroidInPoints, "wrt flickable", centroidInFlickable,
|
||||
"page at", paper.x.toFixed(2), paper.y.toFixed(2),
|
||||
"contentX/Y were", root.contentX.toFixed(2), root.contentY.toFixed(2))
|
||||
if (ratio > 1.1 || ratio < 0.9) {
|
||||
const centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
|
||||
paper.scale = 1
|
||||
paper.x = 0
|
||||
paper.y = 0
|
||||
root.contentX = centroidOnPage.x - centroidInFlickable.x
|
||||
root.contentY = centroidOnPage.y - centroidInFlickable.y
|
||||
root.renderScale *= ratio // onRenderScaleChanged calls pageNavigator.update() so we don't need to here
|
||||
console.log(lcSPV, "contentX/Y adjusted to", root.contentX.toFixed(2), root.contentY.toFixed(2))
|
||||
} else {
|
||||
paper.x = 0
|
||||
paper.y = 0
|
||||
}
|
||||
}
|
||||
grabPermissions: PointerHandler.CanTakeOverFromAnything
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
import QtQuick
|
||||
|
||||
/*!
|
||||
\qmltype PdfStyle
|
||||
\inqmlmodule QtQuick.Pdf
|
||||
\brief A styling interface for the PDF viewer components.
|
||||
|
||||
PdfStyle provides properties to modify the appearance of PdfMultiPageView,
|
||||
PdfScrollablePageView, and PdfPageView.
|
||||
|
||||
Default styles are provided to match the
|
||||
\l {Styling Qt Quick Controls}{styles in Qt Quick Controls}.
|
||||
\l {Using File Selectors with Qt Quick Controls}{File selectors}
|
||||
are used to load the PDF style corresponding to the Controls style in use.
|
||||
Custom styles are possible, using different \l {QFileSelector}{file selectors}.
|
||||
*/
|
||||
QtObject {
|
||||
/*! \internal
|
||||
\qmlproperty SystemPalette PdfStyle::palette
|
||||
*/
|
||||
property SystemPalette palette: SystemPalette { }
|
||||
|
||||
/*! \internal
|
||||
\qmlmethod color PdfStyle::withAlpha()
|
||||
*/
|
||||
function withAlpha(color, alpha) {
|
||||
return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty color PdfStyle::selectionColor
|
||||
|
||||
The color of translucent rectangles that are overlaid on
|
||||
\l {PdfMultiPageView::selectedText}{selected text}.
|
||||
|
||||
\sa PdfSelection
|
||||
*/
|
||||
property color selectionColor: withAlpha(palette.highlight, 0.5)
|
||||
|
||||
/*!
|
||||
\qmlproperty color PdfStyle::pageSearchResultsColor
|
||||
|
||||
The color of translucent rectangles that are overlaid on text that
|
||||
matches the \l {PdfMultiPageView::searchString}{search string}.
|
||||
|
||||
\sa PdfSearchModel
|
||||
*/
|
||||
property color pageSearchResultsColor: "#80B0C4DE"
|
||||
|
||||
/*!
|
||||
\qmlproperty color PdfStyle::currentSearchResultStrokeColor
|
||||
|
||||
The color of the box outline around the
|
||||
\l {PdfSearchModel::currentResult}{current search result}.
|
||||
|
||||
\sa PdfMultiPageView::searchBack(), PdfMultiPageView::searchForward(), PdfSearchModel::currentResult
|
||||
*/
|
||||
property color currentSearchResultStrokeColor: "cyan"
|
||||
|
||||
/*!
|
||||
\qmlproperty real PdfStyle::currentSearchResultStrokeWidth
|
||||
|
||||
The line width of the box outline around the
|
||||
\l {PdfSearchModel::currentResult}{current search result}.
|
||||
|
||||
\sa PdfMultiPageView::searchBack(), PdfMultiPageView::searchForward(), PdfSearchModel::currentResult
|
||||
*/
|
||||
property real currentSearchResultStrokeWidth: 2
|
||||
}
|
||||
BIN
venv/lib/python3.12/site-packages/PyQt6/Qt6/qml/QtQuick/Pdf/libpdfquickplugin.so
Executable file
BIN
venv/lib/python3.12/site-packages/PyQt6/Qt6/qml/QtQuick/Pdf/libpdfquickplugin.so
Executable file
Binary file not shown.
@@ -0,0 +1,894 @@
|
||||
import QtQuick.tooling 1.2
|
||||
|
||||
// This file describes the plugin-supplied types contained in the library.
|
||||
// It is used for QML tooling purposes only.
|
||||
//
|
||||
// This file was auto-generated by qmltyperegistrar.
|
||||
|
||||
Module {
|
||||
Component {
|
||||
file: "qpdfbookmarkmodel.h"
|
||||
lineNumber: 15
|
||||
name: "QPdfBookmarkModel"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QAbstractItemModel"
|
||||
Enum {
|
||||
name: "Role"
|
||||
isScoped: true
|
||||
type: "int"
|
||||
lineNumber: 22
|
||||
values: ["Title", "Level", "Page", "Location", "Zoom", "NRoles"]
|
||||
}
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 19
|
||||
}
|
||||
Signal {
|
||||
name: "documentChanged"
|
||||
lineNumber: 48
|
||||
Parameter { name: "document"; type: "QPdfDocument"; isPointer: true }
|
||||
}
|
||||
Method { name: "_q_documentStatusChanged"; lineNumber: 53 }
|
||||
}
|
||||
Component {
|
||||
file: "qpdfdocument.h"
|
||||
lineNumber: 20
|
||||
name: "QPdfDocument"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QObject"
|
||||
Enum {
|
||||
name: "Status"
|
||||
isScoped: true
|
||||
lineNumber: 30
|
||||
values: ["Null", "Loading", "Ready", "Unloading", "Error"]
|
||||
}
|
||||
Enum {
|
||||
name: "Error"
|
||||
isScoped: true
|
||||
lineNumber: 39
|
||||
values: [
|
||||
"None",
|
||||
"Unknown",
|
||||
"DataNotYetAvailable",
|
||||
"FileNotFound",
|
||||
"InvalidFileFormat",
|
||||
"IncorrectPassword",
|
||||
"UnsupportedSecurityScheme"
|
||||
]
|
||||
}
|
||||
Enum {
|
||||
name: "MetaDataField"
|
||||
isScoped: true
|
||||
lineNumber: 50
|
||||
values: [
|
||||
"Title",
|
||||
"Subject",
|
||||
"Author",
|
||||
"Keywords",
|
||||
"Producer",
|
||||
"Creator",
|
||||
"CreationDate",
|
||||
"ModificationDate"
|
||||
]
|
||||
}
|
||||
Enum {
|
||||
name: "PageModelRole"
|
||||
isScoped: true
|
||||
lineNumber: 62
|
||||
values: ["Label", "PointSize", "NRoles"]
|
||||
}
|
||||
Property {
|
||||
name: "pageCount"
|
||||
type: "int"
|
||||
read: "pageCount"
|
||||
notify: "pageCountChanged"
|
||||
index: 0
|
||||
lineNumber: 24
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "password"
|
||||
type: "QString"
|
||||
read: "password"
|
||||
write: "setPassword"
|
||||
notify: "passwordChanged"
|
||||
index: 1
|
||||
lineNumber: 25
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "status"
|
||||
type: "Status"
|
||||
read: "status"
|
||||
notify: "statusChanged"
|
||||
index: 2
|
||||
lineNumber: 26
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "pageModel"
|
||||
type: "QAbstractListModel"
|
||||
isPointer: true
|
||||
read: "pageModel"
|
||||
notify: "pageModelChanged"
|
||||
index: 3
|
||||
lineNumber: 27
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Signal { name: "passwordChanged"; lineNumber: 103 }
|
||||
Signal { name: "passwordRequired"; lineNumber: 104 }
|
||||
Signal {
|
||||
name: "statusChanged"
|
||||
lineNumber: 105
|
||||
Parameter { name: "status"; type: "QPdfDocument::Status" }
|
||||
}
|
||||
Signal {
|
||||
name: "pageCountChanged"
|
||||
lineNumber: 106
|
||||
Parameter { name: "pageCount"; type: "int" }
|
||||
}
|
||||
Signal { name: "pageModelChanged"; lineNumber: 107 }
|
||||
Method { name: "_q_tryLoadingWithSizeFromContentHeader"; lineNumber: 120 }
|
||||
Method { name: "_q_copyFromSequentialSourceDevice"; lineNumber: 121 }
|
||||
Method {
|
||||
name: "pagePointSize"
|
||||
type: "QSizeF"
|
||||
isMethodConstant: true
|
||||
lineNumber: 89
|
||||
Parameter { name: "page"; type: "int" }
|
||||
}
|
||||
Method {
|
||||
name: "pageLabel"
|
||||
type: "QString"
|
||||
lineNumber: 91
|
||||
Parameter { name: "page"; type: "int" }
|
||||
}
|
||||
Method {
|
||||
name: "pageIndexForLabel"
|
||||
type: "int"
|
||||
lineNumber: 92
|
||||
Parameter { name: "label"; type: "QString" }
|
||||
}
|
||||
Method {
|
||||
name: "getSelection"
|
||||
type: "QPdfSelection"
|
||||
lineNumber: 98
|
||||
Parameter { name: "page"; type: "int" }
|
||||
Parameter { name: "start"; type: "QPointF" }
|
||||
Parameter { name: "end"; type: "QPointF" }
|
||||
}
|
||||
Method {
|
||||
name: "getSelectionAtIndex"
|
||||
type: "QPdfSelection"
|
||||
lineNumber: 99
|
||||
Parameter { name: "page"; type: "int" }
|
||||
Parameter { name: "startIndex"; type: "int" }
|
||||
Parameter { name: "maxLength"; type: "int" }
|
||||
}
|
||||
Method {
|
||||
name: "getAllText"
|
||||
type: "QPdfSelection"
|
||||
lineNumber: 100
|
||||
Parameter { name: "page"; type: "int" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdfpagenavigator_p.h"
|
||||
lineNumber: 26
|
||||
name: "QPdfLink"
|
||||
accessSemantics: "value"
|
||||
exports: ["QtQuick.Pdf/pdfLink 6.4"]
|
||||
isCreatable: false
|
||||
exportMetaObjectRevisions: [1540]
|
||||
Property { name: "valid"; type: "bool"; read: "isValid"; index: 0; lineNumber: 23; isReadonly: true }
|
||||
Property { name: "page"; type: "int"; read: "page"; index: 1; lineNumber: 24; isReadonly: true }
|
||||
Property {
|
||||
name: "location"
|
||||
type: "QPointF"
|
||||
read: "location"
|
||||
index: 2
|
||||
lineNumber: 25
|
||||
isReadonly: true
|
||||
}
|
||||
Property { name: "zoom"; type: "double"; read: "zoom"; index: 3; lineNumber: 26; isReadonly: true }
|
||||
Property { name: "url"; type: "QUrl"; read: "url"; index: 4; lineNumber: 27; isReadonly: true }
|
||||
Property {
|
||||
name: "contextBefore"
|
||||
type: "QString"
|
||||
read: "contextBefore"
|
||||
index: 5
|
||||
lineNumber: 28
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "contextAfter"
|
||||
type: "QString"
|
||||
read: "contextAfter"
|
||||
index: 6
|
||||
lineNumber: 29
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "rectangles"
|
||||
type: "QRectF"
|
||||
isList: true
|
||||
read: "rectangles"
|
||||
index: 7
|
||||
lineNumber: 30
|
||||
isReadonly: true
|
||||
}
|
||||
Method { name: "toString"; type: "QString"; isMethodConstant: true; lineNumber: 51 }
|
||||
Method {
|
||||
name: "copyToClipboard"
|
||||
isMethodConstant: true
|
||||
lineNumber: 52
|
||||
Parameter { name: "mode"; type: "QClipboard::Mode" }
|
||||
}
|
||||
Method { name: "copyToClipboard"; isCloned: true; isMethodConstant: true; lineNumber: 52 }
|
||||
}
|
||||
Component {
|
||||
file: "qpdflinkmodel.h"
|
||||
lineNumber: 19
|
||||
name: "QPdfLinkModel"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QAbstractListModel"
|
||||
Enum {
|
||||
name: "Role"
|
||||
isScoped: true
|
||||
lineNumber: 26
|
||||
values: [
|
||||
"Link",
|
||||
"Rectangle",
|
||||
"Url",
|
||||
"Page",
|
||||
"Location",
|
||||
"Zoom",
|
||||
"NRoles"
|
||||
]
|
||||
}
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 22
|
||||
}
|
||||
Property {
|
||||
name: "page"
|
||||
type: "int"
|
||||
read: "page"
|
||||
write: "setPage"
|
||||
notify: "pageChanged"
|
||||
index: 1
|
||||
lineNumber: 23
|
||||
}
|
||||
Signal { name: "documentChanged"; lineNumber: 54 }
|
||||
Signal {
|
||||
name: "pageChanged"
|
||||
lineNumber: 55
|
||||
Parameter { name: "page"; type: "int" }
|
||||
}
|
||||
Method {
|
||||
name: "setDocument"
|
||||
lineNumber: 50
|
||||
Parameter { name: "document"; type: "QPdfDocument"; isPointer: true }
|
||||
}
|
||||
Method {
|
||||
name: "setPage"
|
||||
lineNumber: 51
|
||||
Parameter { name: "page"; type: "int" }
|
||||
}
|
||||
Method {
|
||||
name: "onStatusChanged"
|
||||
lineNumber: 58
|
||||
Parameter { name: "status"; type: "QPdfDocument::Status" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
file: "qpdfpagenavigator.h"
|
||||
lineNumber: 15
|
||||
name: "QPdfPageNavigator"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QObject"
|
||||
Property {
|
||||
name: "currentPage"
|
||||
type: "int"
|
||||
read: "currentPage"
|
||||
notify: "currentPageChanged"
|
||||
index: 0
|
||||
lineNumber: 19
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "currentLocation"
|
||||
type: "QPointF"
|
||||
read: "currentLocation"
|
||||
notify: "currentLocationChanged"
|
||||
index: 1
|
||||
lineNumber: 20
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "currentZoom"
|
||||
type: "double"
|
||||
read: "currentZoom"
|
||||
notify: "currentZoomChanged"
|
||||
index: 2
|
||||
lineNumber: 21
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "backAvailable"
|
||||
type: "bool"
|
||||
read: "backAvailable"
|
||||
notify: "backAvailableChanged"
|
||||
index: 3
|
||||
lineNumber: 22
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "forwardAvailable"
|
||||
type: "bool"
|
||||
read: "forwardAvailable"
|
||||
notify: "forwardAvailableChanged"
|
||||
index: 4
|
||||
lineNumber: 23
|
||||
isReadonly: true
|
||||
}
|
||||
Signal {
|
||||
name: "currentPageChanged"
|
||||
lineNumber: 46
|
||||
Parameter { name: "page"; type: "int" }
|
||||
}
|
||||
Signal {
|
||||
name: "currentLocationChanged"
|
||||
lineNumber: 47
|
||||
Parameter { name: "location"; type: "QPointF" }
|
||||
}
|
||||
Signal {
|
||||
name: "currentZoomChanged"
|
||||
lineNumber: 48
|
||||
Parameter { name: "zoom"; type: "double" }
|
||||
}
|
||||
Signal {
|
||||
name: "backAvailableChanged"
|
||||
lineNumber: 49
|
||||
Parameter { name: "available"; type: "bool" }
|
||||
}
|
||||
Signal {
|
||||
name: "forwardAvailableChanged"
|
||||
lineNumber: 50
|
||||
Parameter { name: "available"; type: "bool" }
|
||||
}
|
||||
Signal {
|
||||
name: "jumped"
|
||||
lineNumber: 51
|
||||
Parameter { name: "current"; type: "QPdfLink" }
|
||||
}
|
||||
Method { name: "clear"; lineNumber: 38 }
|
||||
Method {
|
||||
name: "jump"
|
||||
lineNumber: 39
|
||||
Parameter { name: "destination"; type: "QPdfLink" }
|
||||
}
|
||||
Method {
|
||||
name: "jump"
|
||||
lineNumber: 40
|
||||
Parameter { name: "page"; type: "int" }
|
||||
Parameter { name: "location"; type: "QPointF" }
|
||||
Parameter { name: "zoom"; type: "double" }
|
||||
}
|
||||
Method {
|
||||
name: "jump"
|
||||
isCloned: true
|
||||
lineNumber: 40
|
||||
Parameter { name: "page"; type: "int" }
|
||||
Parameter { name: "location"; type: "QPointF" }
|
||||
}
|
||||
Method {
|
||||
name: "update"
|
||||
lineNumber: 41
|
||||
Parameter { name: "page"; type: "int" }
|
||||
Parameter { name: "location"; type: "QPointF" }
|
||||
Parameter { name: "zoom"; type: "double" }
|
||||
}
|
||||
Method { name: "forward"; lineNumber: 42 }
|
||||
Method { name: "back"; lineNumber: 43 }
|
||||
}
|
||||
Component {
|
||||
file: "qpdfsearchmodel.h"
|
||||
lineNumber: 17
|
||||
name: "QPdfSearchModel"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QAbstractListModel"
|
||||
Enum {
|
||||
name: "Role"
|
||||
isScoped: true
|
||||
type: "int"
|
||||
lineNumber: 25
|
||||
values: [
|
||||
"Page",
|
||||
"IndexOnPage",
|
||||
"Location",
|
||||
"ContextBefore",
|
||||
"ContextAfter",
|
||||
"NRoles"
|
||||
]
|
||||
}
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 20
|
||||
}
|
||||
Property {
|
||||
name: "searchString"
|
||||
type: "QString"
|
||||
read: "searchString"
|
||||
write: "setSearchString"
|
||||
notify: "searchStringChanged"
|
||||
index: 1
|
||||
lineNumber: 21
|
||||
}
|
||||
Property {
|
||||
name: "count"
|
||||
revision: 1544
|
||||
type: "int"
|
||||
read: "count"
|
||||
notify: "countChanged"
|
||||
index: 2
|
||||
lineNumber: 22
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Signal { name: "documentChanged"; lineNumber: 55 }
|
||||
Signal { name: "searchStringChanged"; lineNumber: 56 }
|
||||
Signal { name: "countChanged"; revision: 1544; lineNumber: 57 }
|
||||
Method {
|
||||
name: "setSearchString"
|
||||
lineNumber: 51
|
||||
Parameter { name: "searchString"; type: "QString" }
|
||||
}
|
||||
Method {
|
||||
name: "setDocument"
|
||||
lineNumber: 52
|
||||
Parameter { name: "document"; type: "QPdfDocument"; isPointer: true }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdfbookmarkmodel_p.h"
|
||||
lineNumber: 26
|
||||
name: "QQuickPdfBookmarkModel"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QPdfBookmarkModel"
|
||||
exports: ["QtQuick.Pdf/PdfBookmarkModel 6.4"]
|
||||
exportMetaObjectRevisions: [1540]
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QQuickPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 29
|
||||
}
|
||||
Signal { name: "documentChanged"; lineNumber: 41 }
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdfdocument_p.h"
|
||||
lineNumber: 30
|
||||
name: "QQuickPdfDocument"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QObject"
|
||||
extension: "QPdfDocument"
|
||||
interfaces: ["QQmlParserStatus"]
|
||||
exports: [
|
||||
"QtQuick.Pdf/PdfDocument 5.15",
|
||||
"QtQuick.Pdf/PdfDocument 6.0"
|
||||
]
|
||||
exportMetaObjectRevisions: [1295, 1536]
|
||||
Property {
|
||||
name: "source"
|
||||
type: "QUrl"
|
||||
read: "source"
|
||||
write: "setSource"
|
||||
notify: "sourceChanged"
|
||||
index: 0
|
||||
lineNumber: 35
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "maxPageWidth"
|
||||
type: "double"
|
||||
read: "maxPageWidth"
|
||||
notify: "metaDataChanged"
|
||||
index: 1
|
||||
lineNumber: 36
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "maxPageHeight"
|
||||
type: "double"
|
||||
read: "maxPageHeight"
|
||||
notify: "metaDataChanged"
|
||||
index: 2
|
||||
lineNumber: 37
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "error"
|
||||
type: "QString"
|
||||
read: "error"
|
||||
notify: "errorChanged"
|
||||
index: 3
|
||||
lineNumber: 38
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "title"
|
||||
type: "QString"
|
||||
read: "title"
|
||||
notify: "metaDataChanged"
|
||||
index: 4
|
||||
lineNumber: 40
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "subject"
|
||||
type: "QString"
|
||||
read: "subject"
|
||||
notify: "metaDataChanged"
|
||||
index: 5
|
||||
lineNumber: 41
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "author"
|
||||
type: "QString"
|
||||
read: "author"
|
||||
notify: "metaDataChanged"
|
||||
index: 6
|
||||
lineNumber: 42
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "keywords"
|
||||
type: "QString"
|
||||
read: "keywords"
|
||||
notify: "metaDataChanged"
|
||||
index: 7
|
||||
lineNumber: 43
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "producer"
|
||||
type: "QString"
|
||||
read: "producer"
|
||||
notify: "metaDataChanged"
|
||||
index: 8
|
||||
lineNumber: 44
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "creator"
|
||||
type: "QString"
|
||||
read: "creator"
|
||||
notify: "metaDataChanged"
|
||||
index: 9
|
||||
lineNumber: 45
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "creationDate"
|
||||
type: "QDateTime"
|
||||
read: "creationDate"
|
||||
notify: "metaDataChanged"
|
||||
index: 10
|
||||
lineNumber: 46
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Property {
|
||||
name: "modificationDate"
|
||||
type: "QDateTime"
|
||||
read: "modificationDate"
|
||||
notify: "metaDataChanged"
|
||||
index: 11
|
||||
lineNumber: 47
|
||||
isReadonly: true
|
||||
isFinal: true
|
||||
}
|
||||
Signal { name: "sourceChanged"; lineNumber: 78 }
|
||||
Signal { name: "errorChanged"; lineNumber: 79 }
|
||||
Signal { name: "metaDataChanged"; lineNumber: 80 }
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdflinkmodel_p.h"
|
||||
lineNumber: 26
|
||||
name: "QQuickPdfLinkModel"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QPdfLinkModel"
|
||||
exports: [
|
||||
"QtQuick.Pdf/PdfLinkModel 5.15",
|
||||
"QtQuick.Pdf/PdfLinkModel 6.0",
|
||||
"QtQuick.Pdf/PdfLinkModel 6.4"
|
||||
]
|
||||
exportMetaObjectRevisions: [1295, 1536, 1540]
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QQuickPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 29
|
||||
}
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdfpageimage_p.h"
|
||||
lineNumber: 25
|
||||
name: "QQuickPdfPageImage"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QQuickImage"
|
||||
exports: [
|
||||
"QtQuick.Pdf/PdfPageImage 6.4",
|
||||
"QtQuick.Pdf/PdfPageImage 6.7",
|
||||
"QtQuick.Pdf/PdfPageImage 6.8"
|
||||
]
|
||||
exportMetaObjectRevisions: [1540, 1543, 1544]
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QQuickPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 28
|
||||
isFinal: true
|
||||
}
|
||||
Signal { name: "documentChanged"; lineNumber: 40 }
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdfpagenavigator_p.h"
|
||||
lineNumber: 34
|
||||
name: "QQuickPdfPageNavigator"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QObject"
|
||||
extension: "QPdfPageNavigator"
|
||||
exports: [
|
||||
"QtQuick.Pdf/PdfPageNavigator 5.15",
|
||||
"QtQuick.Pdf/PdfPageNavigator 6.0"
|
||||
]
|
||||
exportMetaObjectRevisions: [1295, 1536]
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdfsearchmodel_p.h"
|
||||
lineNumber: 26
|
||||
name: "QQuickPdfSearchModel"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QPdfSearchModel"
|
||||
exports: [
|
||||
"QtQuick.Pdf/PdfSearchModel 5.15",
|
||||
"QtQuick.Pdf/PdfSearchModel 6.0",
|
||||
"QtQuick.Pdf/PdfSearchModel 6.4",
|
||||
"QtQuick.Pdf/PdfSearchModel 6.8"
|
||||
]
|
||||
exportMetaObjectRevisions: [1295, 1536, 1540, 1544]
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QQuickPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 29
|
||||
}
|
||||
Property {
|
||||
name: "currentPage"
|
||||
type: "int"
|
||||
read: "currentPage"
|
||||
write: "setCurrentPage"
|
||||
notify: "currentPageChanged"
|
||||
index: 1
|
||||
lineNumber: 30
|
||||
}
|
||||
Property {
|
||||
name: "currentResult"
|
||||
type: "int"
|
||||
read: "currentResult"
|
||||
write: "setCurrentResult"
|
||||
notify: "currentResultChanged"
|
||||
index: 2
|
||||
lineNumber: 31
|
||||
}
|
||||
Property {
|
||||
name: "currentResultLink"
|
||||
type: "QPdfLink"
|
||||
read: "currentResultLink"
|
||||
notify: "currentResultLinkChanged"
|
||||
index: 3
|
||||
lineNumber: 32
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "currentPageBoundingPolygons"
|
||||
type: "QPolygonF"
|
||||
isList: true
|
||||
read: "currentPageBoundingPolygons"
|
||||
notify: "currentPageBoundingPolygonsChanged"
|
||||
index: 4
|
||||
lineNumber: 33
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "currentResultBoundingPolygons"
|
||||
type: "QPolygonF"
|
||||
isList: true
|
||||
read: "currentResultBoundingPolygons"
|
||||
notify: "currentResultBoundingPolygonsChanged"
|
||||
index: 5
|
||||
lineNumber: 34
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "currentResultBoundingRect"
|
||||
type: "QRectF"
|
||||
read: "currentResultBoundingRect"
|
||||
notify: "currentResultBoundingRectChanged"
|
||||
index: 6
|
||||
lineNumber: 35
|
||||
isReadonly: true
|
||||
}
|
||||
Signal { name: "currentPageChanged"; lineNumber: 60 }
|
||||
Signal { name: "currentResultChanged"; lineNumber: 61 }
|
||||
Signal { name: "currentResultLinkChanged"; lineNumber: 62 }
|
||||
Signal { name: "currentPageBoundingPolygonsChanged"; lineNumber: 63 }
|
||||
Signal { name: "currentResultBoundingPolygonsChanged"; lineNumber: 64 }
|
||||
Signal { name: "currentResultBoundingRectChanged"; lineNumber: 65 }
|
||||
Method {
|
||||
name: "boundingPolygonsOnPage"
|
||||
type: "QPolygonF"
|
||||
isList: true
|
||||
lineNumber: 46
|
||||
Parameter { name: "page"; type: "int" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
file: "private/qquickpdfselection_p.h"
|
||||
lineNumber: 30
|
||||
name: "QQuickPdfSelection"
|
||||
accessSemantics: "reference"
|
||||
defaultProperty: "data"
|
||||
parentProperty: "parent"
|
||||
prototype: "QQuickItem"
|
||||
exports: [
|
||||
"QtQuick.Pdf/PdfSelection 5.15",
|
||||
"QtQuick.Pdf/PdfSelection 6.0",
|
||||
"QtQuick.Pdf/PdfSelection 6.3",
|
||||
"QtQuick.Pdf/PdfSelection 6.7"
|
||||
]
|
||||
exportMetaObjectRevisions: [1295, 1536, 1539, 1543]
|
||||
Property {
|
||||
name: "document"
|
||||
type: "QQuickPdfDocument"
|
||||
isPointer: true
|
||||
read: "document"
|
||||
write: "setDocument"
|
||||
notify: "documentChanged"
|
||||
index: 0
|
||||
lineNumber: 33
|
||||
}
|
||||
Property {
|
||||
name: "page"
|
||||
type: "int"
|
||||
read: "page"
|
||||
write: "setPage"
|
||||
notify: "pageChanged"
|
||||
index: 1
|
||||
lineNumber: 34
|
||||
}
|
||||
Property {
|
||||
name: "renderScale"
|
||||
type: "double"
|
||||
read: "renderScale"
|
||||
write: "setRenderScale"
|
||||
notify: "renderScaleChanged"
|
||||
index: 2
|
||||
lineNumber: 35
|
||||
}
|
||||
Property {
|
||||
name: "from"
|
||||
type: "QPointF"
|
||||
read: "from"
|
||||
write: "setFrom"
|
||||
notify: "fromChanged"
|
||||
index: 3
|
||||
lineNumber: 36
|
||||
}
|
||||
Property {
|
||||
name: "to"
|
||||
type: "QPointF"
|
||||
read: "to"
|
||||
write: "setTo"
|
||||
notify: "toChanged"
|
||||
index: 4
|
||||
lineNumber: 37
|
||||
}
|
||||
Property {
|
||||
name: "hold"
|
||||
type: "bool"
|
||||
read: "hold"
|
||||
write: "setHold"
|
||||
notify: "holdChanged"
|
||||
index: 5
|
||||
lineNumber: 38
|
||||
}
|
||||
Property {
|
||||
name: "text"
|
||||
type: "QString"
|
||||
read: "text"
|
||||
notify: "textChanged"
|
||||
index: 6
|
||||
lineNumber: 40
|
||||
isReadonly: true
|
||||
}
|
||||
Property {
|
||||
name: "geometry"
|
||||
type: "QPolygonF"
|
||||
isList: true
|
||||
read: "geometry"
|
||||
notify: "selectedAreaChanged"
|
||||
index: 7
|
||||
lineNumber: 41
|
||||
isReadonly: true
|
||||
}
|
||||
Signal { name: "documentChanged"; lineNumber: 72 }
|
||||
Signal { name: "pageChanged"; lineNumber: 73 }
|
||||
Signal { name: "renderScaleChanged"; lineNumber: 74 }
|
||||
Signal { name: "fromChanged"; lineNumber: 75 }
|
||||
Signal { name: "toChanged"; lineNumber: 76 }
|
||||
Signal { name: "holdChanged"; lineNumber: 77 }
|
||||
Signal { name: "textChanged"; lineNumber: 78 }
|
||||
Signal { name: "selectedAreaChanged"; lineNumber: 79 }
|
||||
Method { name: "clear"; lineNumber: 65 }
|
||||
Method { name: "selectAll"; lineNumber: 66 }
|
||||
Method { name: "copyToClipboard"; isMethodConstant: true; lineNumber: 68 }
|
||||
Method {
|
||||
name: "inputMethodQuery"
|
||||
type: "QVariant"
|
||||
isMethodConstant: true
|
||||
lineNumber: 85
|
||||
Parameter { name: "query"; type: "Qt::InputMethodQuery" }
|
||||
Parameter { name: "argument"; type: "QVariant" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
module QtQuick.Pdf
|
||||
linktarget Qt6::PdfQuickplugin
|
||||
optional plugin pdfquickplugin
|
||||
classname QtQuick_PdfPlugin
|
||||
typeinfo plugins.qmltypes
|
||||
depends QtQuick auto
|
||||
prefer :/qt-project.org/imports/QtQuick/Pdf/
|
||||
PdfStyle 6.0 +Material/PdfStyle.qml
|
||||
PdfStyle 5.0 +Material/PdfStyle.qml
|
||||
PdfStyle 6.0 +Universal/PdfStyle.qml
|
||||
PdfStyle 5.0 +Universal/PdfStyle.qml
|
||||
PdfLinkDelegate 6.0 PdfLinkDelegate.qml
|
||||
PdfLinkDelegate 5.0 PdfLinkDelegate.qml
|
||||
PdfMultiPageView 6.0 PdfMultiPageView.qml
|
||||
PdfMultiPageView 5.0 PdfMultiPageView.qml
|
||||
PdfPageView 6.0 PdfPageView.qml
|
||||
PdfPageView 5.0 PdfPageView.qml
|
||||
PdfScrollablePageView 6.0 PdfScrollablePageView.qml
|
||||
PdfScrollablePageView 5.0 PdfScrollablePageView.qml
|
||||
PdfStyle 6.0 PdfStyle.qml
|
||||
PdfStyle 5.0 PdfStyle.qml
|
||||
depends QtQuick
|
||||
|
||||
Reference in New Issue
Block a user