summaryrefslogtreecommitdiffstats
path: root/src/pdf/quick
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-01-20 18:29:05 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2020-01-30 16:26:27 +0100
commitbc1d6ddeb5076f68e0a758725a20c3f2a6d081f0 (patch)
treec730d9ffbe79b262fbe6962fa2daa3f14adf0fc5 /src/pdf/quick
parent4f5f0705bc161ff95899fdb2c5fcdb4581bf15bb (diff)
Add QPdfSelection and QQuickPdfSelection
So now you can select text by mouse-drag and copy it to the clipboard. Task-number: QTBUG-77509 Change-Id: I689ee4158974de8bc541c319a5a5cc2f8f3c2ae6 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'src/pdf/quick')
-rw-r--r--src/pdf/quick/plugin.cpp2
-rw-r--r--src/pdf/quick/qml/PdfPageView.qml30
-rw-r--r--src/pdf/quick/qquickpdfsearchmodel_p.h1
-rw-r--r--src/pdf/quick/qquickpdfselection.cpp268
-rw-r--r--src/pdf/quick/qquickpdfselection_p.h122
-rw-r--r--src/pdf/quick/quick.pro2
6 files changed, 425 insertions, 0 deletions
diff --git a/src/pdf/quick/plugin.cpp b/src/pdf/quick/plugin.cpp
index 664ba51ab..72aa12d6a 100644
--- a/src/pdf/quick/plugin.cpp
+++ b/src/pdf/quick/plugin.cpp
@@ -40,6 +40,7 @@
#include <QtQml/qqmlextensionplugin.h>
#include "qquickpdfdocument_p.h"
#include "qquickpdfsearchmodel_p.h"
+#include "qquickpdfselection_p.h"
QT_BEGIN_NAMESPACE
@@ -81,6 +82,7 @@ public:
qmlRegisterType<QQuickPdfDocument>(uri, 5, 15, "PdfDocument");
qmlRegisterType<QQuickPdfSearchModel>(uri, 5, 15, "PdfSearchModel");
+ qmlRegisterType<QQuickPdfSelection>(uri, 5, 15, "PdfSelection");
qmlRegisterType(QUrl("qrc:/qt-project.org/qtpdf/qml/PdfPageView.qml"), uri, 5, 15, "PdfPageView");
}
diff --git a/src/pdf/quick/qml/PdfPageView.qml b/src/pdf/quick/qml/PdfPageView.qml
index b7f75f4c2..2f9c5ef99 100644
--- a/src/pdf/quick/qml/PdfPageView.qml
+++ b/src/pdf/quick/qml/PdfPageView.qml
@@ -51,10 +51,23 @@ Rectangle {
property alias currentPage: image.currentFrame
property alias pageCount: image.frameCount
property alias searchString: searchModel.searchString
+ property alias selectedText: selection.text
property alias status: image.status
property real __pageScale: image.paintedWidth / document.pagePointSize(image.currentFrame).width
+ PdfSelection {
+ id: selection
+ document: paper.document
+ page: image.currentFrame
+ fromPoint: Qt.point(textSelectionDrag.centroid.pressPosition.x / paper.__pageScale, textSelectionDrag.centroid.pressPosition.y / paper.__pageScale)
+ toPoint: Qt.point(textSelectionDrag.centroid.position.x / paper.__pageScale, textSelectionDrag.centroid.position.y / paper.__pageScale)
+ hold: !textSelectionDrag.active && !tapHandler.pressed
+ }
+ function copySelectionToClipboard() {
+ selection.copyToClipboard()
+ }
+
PdfSearchModel {
id: searchModel
document: paper.document
@@ -96,6 +109,14 @@ Rectangle {
paths: searchModel.matchGeometry
}
}
+ ShapePath {
+ fillColor: "orange"
+ scale: Qt.size(paper.__pageScale, paper.__pageScale)
+ PathMultiline {
+ id: selectionBoundaries
+ paths: selection.geometry
+ }
+ }
}
PinchHandler {
id: pinch
@@ -116,4 +137,13 @@ Rectangle {
acceptedButtons: Qt.MiddleButton
snapMode: DragHandler.NoSnap
}
+ DragHandler {
+ id: textSelectionDrag
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ target: null
+ }
+ TapHandler {
+ id: tapHandler
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ }
}
diff --git a/src/pdf/quick/qquickpdfsearchmodel_p.h b/src/pdf/quick/qquickpdfsearchmodel_p.h
index 799ef825f..82a6289d0 100644
--- a/src/pdf/quick/qquickpdfsearchmodel_p.h
+++ b/src/pdf/quick/qquickpdfsearchmodel_p.h
@@ -99,5 +99,6 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickPdfSearchModel)
+QML_DECLARE_TYPE(QPdfSelection)
#endif // QQUICKPDFSEARCHMODEL_P_H
diff --git a/src/pdf/quick/qquickpdfselection.cpp b/src/pdf/quick/qquickpdfselection.cpp
new file mode 100644
index 000000000..d313820ba
--- /dev/null
+++ b/src/pdf/quick/qquickpdfselection.cpp
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpdfselection_p.h"
+#include "qquickpdfdocument_p.h"
+#include <QClipboard>
+#include <QQuickItem>
+#include <QQmlEngine>
+#include <QStandardPaths>
+#include <private/qguiapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype PdfSelection
+ \instantiates QQuickPdfSelection
+ \inqmlmodule QtQuick.Pdf
+ \ingroup pdf
+ \brief A representation of a text selection within a PDF Document.
+ \since 5.15
+
+ PdfSelection provides the text string and its geometry within a bounding box
+ from one point to another.
+*/
+
+/*!
+ Constructs a SearchModel.
+*/
+QQuickPdfSelection::QQuickPdfSelection(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQuickPdfDocument *QQuickPdfSelection::document() const
+{
+ return m_document;
+}
+
+void QQuickPdfSelection::setDocument(QQuickPdfDocument *document)
+{
+ if (m_document == document)
+ return;
+
+ if (m_document) {
+ disconnect(m_document, &QQuickPdfDocument::sourceChanged,
+ this, &QQuickPdfSelection::resetPoints);
+ }
+ m_document = document;
+ emit documentChanged();
+ resetPoints();
+ connect(m_document, &QQuickPdfDocument::sourceChanged,
+ this, &QQuickPdfSelection::resetPoints);
+}
+
+/*!
+ \qmlproperty list<list<point>> PdfSelection::geometry
+
+ A set of paths in a form that can be bound to the \c paths property of a
+ \l {QtQuick::PathMultiline}{PathMultiline} instance to render a batch of
+ rectangles around the text regions that are included in the selection:
+
+ \qml
+ PdfDocument {
+ id: doc
+ }
+ PdfSelection {
+ id: selection
+ document: doc
+ fromPoint: textSelectionDrag.centroid.pressPosition
+ toPoint: textSelectionDrag.centroid.position
+ hold: !textSelectionDrag.active
+ }
+ Shape {
+ ShapePath {
+ PathMultiline {
+ paths: selection.geometry
+ }
+ }
+ }
+ DragHandler {
+ id: textSelectionDrag
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ target: null
+ }
+ \endqml
+
+ \sa PathMultiline
+*/
+QVector<QPolygonF> QQuickPdfSelection::geometry() const
+{
+ return m_geometry;
+}
+
+void QQuickPdfSelection::resetPoints()
+{
+ bool wasHolding = m_hold;
+ m_hold = false;
+ setFromPoint(QPointF());
+ setToPoint(QPointF());
+ m_hold = wasHolding;
+}
+
+/*!
+ \qmlproperty int PdfSelection::page
+
+ The page number on which to search.
+
+ \sa QtQuick::Image::currentFrame
+*/
+int QQuickPdfSelection::page() const
+{
+ return m_page;
+}
+
+void QQuickPdfSelection::setPage(int page)
+{
+ if (m_page == page)
+ return;
+
+ m_page = page;
+ emit pageChanged();
+ resetPoints();
+}
+
+/*!
+ \qmlproperty point PdfSelection::fromPoint
+
+ The beginning location, in \l {https://en.wikipedia.org/wiki/Point_(typography)}{points}
+ from the upper-left corner of the page, from which to find selected text.
+ This can be bound to a scaled version of the \c centroid.pressPosition
+ of a \l DragHandler to begin selecting text from the position where the user
+ presses the mouse button and begins dragging, for example.
+*/
+QPointF QQuickPdfSelection::fromPoint() const
+{
+ return m_fromPoint;
+}
+
+void QQuickPdfSelection::setFromPoint(QPointF fromPoint)
+{
+ if (m_hold || m_fromPoint == fromPoint)
+ return;
+
+ m_fromPoint = fromPoint;
+ emit fromPointChanged();
+ updateResults();
+}
+
+/*!
+ \qmlproperty point PdfSelection::toPoint
+
+ The ending location, in \l {https://en.wikipedia.org/wiki/Point_(typography)}{points}
+ from the upper-left corner of the page, from which to find selected text.
+ This can be bound to a scaled version of the \c centroid.position
+ of a \l DragHandler to end selection of text at the position where the user
+ is currently dragging the mouse, for example.
+*/
+QPointF QQuickPdfSelection::toPoint() const
+{
+ return m_toPoint;
+}
+
+void QQuickPdfSelection::setToPoint(QPointF toPoint)
+{
+ if (m_hold || m_toPoint == toPoint)
+ return;
+
+ m_toPoint = toPoint;
+ emit toPointChanged();
+ updateResults();
+}
+
+/*!
+ \qmlproperty bool PdfSelection::hold
+
+ Controls whether to hold the existing selection regardless of changes to
+ \l fromPoint and \l toPoint. This property can be set to \c true when the mouse
+ or touchpoint is released, so that the selection is not lost due to the
+ point bindings changing.
+*/
+bool QQuickPdfSelection::hold() const
+{
+ return m_hold;
+}
+
+void QQuickPdfSelection::setHold(bool hold)
+{
+ if (m_hold == hold)
+ return;
+
+ m_hold = hold;
+ emit holdChanged();
+}
+
+/*!
+ \qmlproperty string PdfSelection::string
+
+ The string found.
+*/
+QString QQuickPdfSelection::text() const
+{
+ return m_text;
+}
+
+#if QT_CONFIG(clipboard)
+/*!
+ \qmlmethod void PdfSelection::copyToClipboard()
+
+ Copies plain text from the \l string property to the system clipboard.
+*/
+void QQuickPdfSelection::copyToClipboard() const
+{
+ QGuiApplication::clipboard()->setText(m_text);
+}
+#endif
+
+void QQuickPdfSelection::updateResults()
+{
+ if (!m_document)
+ return;
+ QPdfSelection sel = m_document->document().getSelection(m_page, m_fromPoint, m_toPoint);
+ if (sel.text() != m_text) {
+ m_text = sel.text();
+ if (QGuiApplication::clipboard()->supportsSelection())
+ sel.copyToClipboard(QClipboard::Selection);
+ emit textChanged();
+ }
+
+ if (sel.bounds() != m_geometry) {
+ m_geometry = sel.bounds();
+ emit geometryChanged();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/pdf/quick/qquickpdfselection_p.h b/src/pdf/quick/qquickpdfselection_p.h
new file mode 100644
index 000000000..a0e6d1a8d
--- /dev/null
+++ b/src/pdf/quick/qquickpdfselection_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtPDF module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPDFSELECTION_P_H
+#define QQUICKPDFSELECTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QPointF>
+#include <QPolygonF>
+#include <QVariant>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPdfDocument;
+
+class QQuickPdfSelection : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(int page READ page WRITE setPage NOTIFY pageChanged)
+ Q_PROPERTY(QPointF fromPoint READ fromPoint WRITE setFromPoint NOTIFY fromPointChanged)
+ Q_PROPERTY(QPointF toPoint READ toPoint WRITE setToPoint NOTIFY toPointChanged)
+ Q_PROPERTY(bool hold READ hold WRITE setHold NOTIFY holdChanged)
+
+ Q_PROPERTY(QString text READ text NOTIFY textChanged)
+ Q_PROPERTY(QVector<QPolygonF> geometry READ geometry NOTIFY geometryChanged)
+
+public:
+ explicit QQuickPdfSelection(QObject *parent = nullptr);
+
+ QQuickPdfDocument *document() const;
+ void setDocument(QQuickPdfDocument * document);
+ int page() const;
+ void setPage(int page);
+ QPointF fromPoint() const;
+ void setFromPoint(QPointF fromPoint);
+ QPointF toPoint() const;
+ void setToPoint(QPointF toPoint);
+ bool hold() const;
+ void setHold(bool hold);
+
+ QString text() const;
+ QVector<QPolygonF> geometry() const;
+
+#if QT_CONFIG(clipboard)
+ Q_INVOKABLE void copyToClipboard() const;
+#endif
+
+signals:
+ void documentChanged();
+ void pageChanged();
+ void fromPointChanged();
+ void toPointChanged();
+ void holdChanged();
+ void textChanged();
+ void geometryChanged();
+
+private:
+ void resetPoints();
+ void updateResults();
+
+private:
+ QQuickPdfDocument *m_document = nullptr;
+ QPointF m_fromPoint;
+ QPointF m_toPoint;
+ QString m_text;
+ QVector<QPolygonF> m_geometry;
+ int m_page = 0;
+ bool m_hold = false;
+
+ Q_DISABLE_COPY(QQuickPdfSelection)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPdfSelection)
+\
+#endif // QQUICKPDFSELECTION_P_H
diff --git a/src/pdf/quick/quick.pro b/src/pdf/quick/quick.pro
index cda768369..d999ffb0b 100644
--- a/src/pdf/quick/quick.pro
+++ b/src/pdf/quick/quick.pro
@@ -16,10 +16,12 @@ SOURCES += \
plugin.cpp \
qquickpdfdocument.cpp \
qquickpdfsearchmodel.cpp \
+ qquickpdfselection.cpp \
HEADERS += \
qquickpdfdocument_p.h \
qquickpdfsearchmodel_p.h \
+ qquickpdfselection_p.h \
QT += pdf quick-private gui gui-private core core-private qml qml-private