summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/pdf/multipage/doc/src/multipage.qdoc79
-rw-r--r--examples/pdf/multipage/viewer.qml2
-rw-r--r--src/pdf/doc/images/multipageviewer.pngbin0 -> 55795 bytes
-rw-r--r--src/pdf/doc/qtpdf.qdocconf1
-rw-r--r--src/pdf/doc/snippets/multipageview.qml8
-rw-r--r--src/pdfquick/PdfMultiPageView.qml229
-rw-r--r--src/pdfquick/qquickpdfpageimage.cpp2
7 files changed, 312 insertions, 9 deletions
diff --git a/examples/pdf/multipage/doc/src/multipage.qdoc b/examples/pdf/multipage/doc/src/multipage.qdoc
new file mode 100644
index 000000000..ecb8127b1
--- /dev/null
+++ b/examples/pdf/multipage/doc/src/multipage.qdoc
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example multipage
+ \ingroup qtpdf-examples
+
+ \title PDF Multipage Viewer Example
+ \brief A PDF viewer that allows scrolling through the pages.
+
+ \image multipageviewer.png
+
+ \e {PDF Multipage Viewer} demonstrates how to use the PdfMultiPageView
+ component to render PDF documents and search for text in them.
+
+ \include examples-run.qdocinc
+
+ \section1 Creating the Main Window
+
+ Instantiate an \l ApplicationWindow, bind its title to the title of the
+ PDF document, and create a toolbar:
+
+ \quotefromfile multipage/viewer.qml
+ \skipto ApplicationWindow
+ \printuntil rightMargin
+
+ The toolbar has buttons for most of the common actions:
+
+ \printuntil ZoomOut
+
+ Declare a PdfDocument and bind the \c status property and
+ \c passwordRequired signal to inform the user when an error occurs or a
+ password is required:
+
+ \skipto onAccepted
+ \skipto Dialog
+ \printto PdfMultiPageView
+
+ Add the main component, PdfMultiPageView:
+
+ \printto onCurrentPageChanged
+ \printto Drawer
+
+ A \l Drawer holds a ListView to show search results from the
+ \l {PdfMultiPageView::searchModel}{searchModel}:
+
+ \printto ToolBar
+
+ Finally, add a second toolbar as a footer, to hold the search field,
+ search up/down buttons and some status information:
+
+ \printuntil
+
+ \section1 Files and Attributions
+*/
diff --git a/examples/pdf/multipage/viewer.qml b/examples/pdf/multipage/viewer.qml
index 7b085ee91..9289e3cee 100644
--- a/examples/pdf/multipage/viewer.qml
+++ b/examples/pdf/multipage/viewer.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
diff --git a/src/pdf/doc/images/multipageviewer.png b/src/pdf/doc/images/multipageviewer.png
new file mode 100644
index 000000000..f6ebd2d83
--- /dev/null
+++ b/src/pdf/doc/images/multipageviewer.png
Binary files differ
diff --git a/src/pdf/doc/qtpdf.qdocconf b/src/pdf/doc/qtpdf.qdocconf
index 75d41af1d..24f7d8b51 100644
--- a/src/pdf/doc/qtpdf.qdocconf
+++ b/src/pdf/doc/qtpdf.qdocconf
@@ -44,6 +44,7 @@ sourcedirs += ../ \
../../pdfquick
exampledirs += ../../../examples/pdfwidgets \
+ ../../../examples/pdf \
snippets/
# add a generic thumbnail for an example that has no \image in its doc
diff --git a/src/pdf/doc/snippets/multipageview.qml b/src/pdf/doc/snippets/multipageview.qml
new file mode 100644
index 000000000..ee695c03a
--- /dev/null
+++ b/src/pdf/doc/snippets/multipageview.qml
@@ -0,0 +1,8 @@
+//! [0]
+import QtQuick
+import QtQuick.Pdf
+
+PdfMultiPageView {
+ document: PdfDocument { source: "my.pdf" }
+}
+//! [0]
diff --git a/src/pdfquick/PdfMultiPageView.qml b/src/pdfquick/PdfMultiPageView.qml
index 0008b138b..dca052d87 100644
--- a/src/pdfquick/PdfMultiPageView.qml
+++ b/src/pdfquick/PdfMultiPageView.qml
@@ -41,16 +41,69 @@ 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 {
- // public API
+ /*!
+ \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))
if (currentItem)
currentItem.selection.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))
console.log(lcMPV, "currentItem", currentItem, "sel", currentItem.selection.text)
@@ -58,17 +111,89 @@ Item {
currentItem.selection.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 PdfNavigationStack::currentPage
+ */
property alias currentPage: navigationStack.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 PdfNavigationStack::backAvailable, back()
+ */
property alias backEnabled: navigationStack.backAvailable
+
+ /*!
+ \qmlproperty bool PdfMultiPageView::forwardEnabled
+ \readonly
+
+ This property indicates if it is possible to go to next location in the
+ navigation history.
+
+ \sa PdfNavigationStack::forwardAvailable, forward()
+ */
property alias forwardEnabled: navigationStack.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 PdfNavigationStack::back(), currentPage, backEnabled
+ */
function back() { navigationStack.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 PdfNavigationStack::forward(), currentPage
+ */
function forward() { navigationStack.forward() }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::goToPage(int page)
+
+ Scrolls the view to the given \a page number, if possible.
+
+ \sa PdfNavigationStack::push(), currentPage
+ */
function goToPage(page) {
if (page === navigationStack.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 PdfNavigationStack::push(), currentPage
+ */
function goToLocation(page, location, zoom) {
if (zoom > 0) {
navigationStack.jumping = true // don't call navigationStack.update() because we will push() instead
@@ -78,16 +203,69 @@ Item {
}
navigationStack.push(page, location, zoom) // actually jump
}
- property vector2d jumpLocationMargin: Qt.vector2d(10, 10) // px from top-left corner
+
+ /*!
+ \qmlproperty int PdfMultiPageView::currentPageRenderingStatus
+
+ This property holds the \l {QtQuick::Image::status}{rendering status} of
+ the \l {currentPage}{current page}.
+
+ \sa PdfPageImage::status
+ */
property int currentPageRenderingStatus: Image.Null
- // page scaling
+ // --------------------------------
+ // page navigation
+
+ /*!
+ \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.
+
+ \sa PdfPageImage::status
+ */
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).
+
+ \sa PdfPageImage::rotation
+ */
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
@@ -106,10 +284,46 @@ Item {
}
}
+ // --------------------------------
// 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
+ \l {QtQuick.Controls::TextField::text}{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 {
@@ -122,6 +336,7 @@ Item {
TableView {
id: tableView
property bool debug: false
+ property vector2d jumpLocationMargin: Qt.vector2d(10, 10) // px from top-left corner
anchors.fill: parent
anchors.leftMargin: 2
model: modelInUse && root.document ? root.document.pageCount : 0
@@ -380,8 +595,8 @@ Item {
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 + jumpLocationMargin.x) / root.renderScale,
- (tableView.contentY - currentItem.y + jumpLocationMargin.y) / root.renderScale)
+ const currentLocation = Qt.point((tableView.contentX - currentItem.x + tableView.jumpLocationMargin.x) / root.renderScale,
+ (tableView.contentY - currentItem.y + tableView.jumpLocationMargin.y) / root.renderScale)
navigationStack.update(cell.y, currentLocation, renderScale)
}
}
@@ -409,8 +624,8 @@ Item {
pageSize.height *= root.renderScale
const xOffsetLimit = Math.max(0, pageSize.width - root.width) / 2
const offset = Qt.point(Math.max(-xOffsetLimit, Math.min(xOffsetLimit,
- location.x * root.renderScale - jumpLocationMargin.x)),
- Math.max(0, location.y * root.renderScale - jumpLocationMargin.y))
+ location.x * root.renderScale - tableView.jumpLocationMargin.x)),
+ Math.max(0, location.y * root.renderScale - tableView.jumpLocationMargin.y))
tableView.positionViewAtCell(0, page, Qt.AlignLeft | Qt.AlignTop, offset)
console.log(lcMPV, "going to zoom", zoom, "loc", location, "on page", page,
"ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
diff --git a/src/pdfquick/qquickpdfpageimage.cpp b/src/pdfquick/qquickpdfpageimage.cpp
index 60853454f..26d3bd9d6 100644
--- a/src/pdfquick/qquickpdfpageimage.cpp
+++ b/src/pdfquick/qquickpdfpageimage.cpp
@@ -52,7 +52,7 @@ Q_LOGGING_CATEGORY(qLcImg, "qt.pdf.image")
\instantiates QQuickPdfPageImage
\inqmlmodule QtPdf
\ingroup pdf
- \inherits Item
+ \inherits Image
\brief Displays one page from a PDF document.
\since 6.4