summaryrefslogtreecommitdiffstats
path: root/src/pdf
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-04-27 10:03:12 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-04-27 10:03:43 +0200
commit10e66c6dd0b8a8dd17252d6408c13b689fac6995 (patch)
treefbdddb33a818b5495b24f3949f7406b0b916e78c /src/pdf
parentd0852f90a24673ccc9ef0b93e224ba37b674644d (diff)
parent75412200db05ddc5ee2b9aea367b580d8b0c438e (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: configure.pri src/pdf/api/qpdfpagerenderer.h Change-Id: I7e68277080e29238bbfe8511539ea75b2db89489
Diffstat (limited to 'src/pdf')
-rw-r--r--src/pdf/api/qpdfbookmarkmodel.h4
-rw-r--r--src/pdf/api/qpdfdestination.h5
-rw-r--r--src/pdf/api/qpdfdocument.h3
-rw-r--r--src/pdf/api/qpdfdocument_p.h11
-rw-r--r--src/pdf/api/qpdfdocumentrenderoptions.h51
-rw-r--r--src/pdf/api/qpdfnamespace.h3
-rw-r--r--src/pdf/api/qpdfpagenavigation.h3
-rw-r--r--src/pdf/api/qpdfpagerenderer.h9
-rw-r--r--src/pdf/api/qpdfsearchmodel.h9
-rw-r--r--src/pdf/api/qpdfsearchresult.h11
-rw-r--r--src/pdf/api/qpdfsearchresult_p.h8
-rw-r--r--src/pdf/api/qpdfselection.h14
-rw-r--r--src/pdf/api/qtpdfglobal.h2
-rw-r--r--src/pdf/configure.json2
-rw-r--r--src/pdf/gn_run.pro3
-rw-r--r--src/pdf/jsbridge.cpp2
-rw-r--r--src/pdf/qpdfbookmarkmodel.cpp2
-rw-r--r--src/pdf/qpdfdestination.cpp5
-rw-r--r--src/pdf/qpdfdocument.cpp45
-rw-r--r--src/pdf/qpdflinkmodel.cpp86
-rw-r--r--src/pdf/qpdfpagerenderer.cpp18
-rw-r--r--src/pdf/qpdfsearchmodel.cpp42
-rw-r--r--src/pdf/qpdfsearchresult.cpp16
-rw-r--r--src/pdf/qpdfselection.cpp11
-rw-r--r--src/pdf/quick/plugin.cpp4
-rw-r--r--src/pdf/quick/qml/+material/PdfStyle.qml54
-rw-r--r--src/pdf/quick/qml/+universal/PdfStyle.qml55
-rw-r--r--src/pdf/quick/qml/PdfMultiPageView.qml147
-rw-r--r--src/pdf/quick/qml/PdfPageView.qml3
-rw-r--r--src/pdf/quick/qml/PdfScrollablePageView.qml150
-rw-r--r--src/pdf/quick/qml/PdfStyle.qml54
-rw-r--r--src/pdf/quick/qquickpdfselection.cpp16
-rw-r--r--src/pdf/quick/qquickpdfselection_p.h1
-rw-r--r--src/pdf/quick/resources.qrc3
34 files changed, 606 insertions, 246 deletions
diff --git a/src/pdf/api/qpdfbookmarkmodel.h b/src/pdf/api/qpdfbookmarkmodel.h
index 503a29100..8e06a1547 100644
--- a/src/pdf/api/qpdfbookmarkmodel.h
+++ b/src/pdf/api/qpdfbookmarkmodel.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -38,7 +38,7 @@
#define QPDFBOOKMARKMODEL_H
#include <QtPdf/qtpdfglobal.h>
-#include <QAbstractItemModel>
+#include <QtCore/qabstractitemmodel.h>
QT_BEGIN_NAMESPACE
diff --git a/src/pdf/api/qpdfdestination.h b/src/pdf/api/qpdfdestination.h
index 325863226..f9c186ff6 100644
--- a/src/pdf/api/qpdfdestination.h
+++ b/src/pdf/api/qpdfdestination.h
@@ -56,10 +56,11 @@ class Q_PDF_EXPORT QPdfDestination
Q_PROPERTY(qreal zoom READ zoom)
public:
- QPdfDestination(const QPdfDestination &other);
~QPdfDestination();
+ QPdfDestination(const QPdfDestination &other);
QPdfDestination &operator=(const QPdfDestination &other);
- inline QPdfDestination &operator=(QPdfDestination &&other) noexcept { swap(other); return *this; }
+ QPdfDestination(QPdfDestination &&other) noexcept;
+ QPdfDestination &operator=(QPdfDestination &&other) noexcept { swap(other); return *this; }
void swap(QPdfDestination &other) noexcept { d.swap(other.d); }
bool isValid() const;
int page() const;
diff --git a/src/pdf/api/qpdfdocument.h b/src/pdf/api/qpdfdocument.h
index 290a7b170..f80a7832b 100644
--- a/src/pdf/api/qpdfdocument.h
+++ b/src/pdf/api/qpdfdocument.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -114,6 +114,7 @@ public:
QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions());
Q_INVOKABLE QPdfSelection getSelection(int page, QPointF start, QPointF end);
+ Q_INVOKABLE QPdfSelection getAllText(int page);
Q_SIGNALS:
void passwordChanged();
diff --git a/src/pdf/api/qpdfdocument_p.h b/src/pdf/api/qpdfdocument_p.h
index 15d8b8259..b69b6f19e 100644
--- a/src/pdf/api/qpdfdocument_p.h
+++ b/src/pdf/api/qpdfdocument_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -53,10 +53,10 @@
#include "third_party/pdfium/public/fpdfview.h"
#include "third_party/pdfium/public/fpdf_dataavail.h"
-#include <qbuffer.h>
-#include <qmutex.h>
-#include <qnetworkreply.h>
-#include <qpointer.h>
+#include <QtCore/qbuffer.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qpointer.h>
+#include <QtNetwork/qnetworkreply.h>
QT_BEGIN_NAMESPACE
@@ -105,6 +105,7 @@ public:
static int fpdf_GetBlock(void* param, unsigned long position, unsigned char* pBuf, unsigned long size);
static void fpdf_AddSegment(struct _FX_DOWNLOADHINTS* pThis, size_t offset, size_t size);
void updateLastError();
+ QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count);
};
QT_END_NAMESPACE
diff --git a/src/pdf/api/qpdfdocumentrenderoptions.h b/src/pdf/api/qpdfdocumentrenderoptions.h
index 873be0085..cafb4716f 100644
--- a/src/pdf/api/qpdfdocumentrenderoptions.h
+++ b/src/pdf/api/qpdfdocumentrenderoptions.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+** 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.
@@ -38,56 +39,50 @@
#define QPDFDOCUMENTRENDEROPTIONS_H
#include <QtPdf/qpdfnamespace.h>
-#include <QtCore/QObject>
-#include <QtCore/QRect>
+#include <QtCore/qobject.h>
+#include <QtCore/qrect.h>
QT_BEGIN_NAMESPACE
class QPdfDocumentRenderOptions
{
public:
- Q_DECL_CONSTEXPR QPdfDocumentRenderOptions() Q_DECL_NOTHROW : data(0) {}
+ Q_DECL_CONSTEXPR QPdfDocumentRenderOptions() noexcept : m_renderFlags(0), m_rotation(0), m_reserved(0) {}
- Q_DECL_CONSTEXPR QPdf::Rotation rotation() const Q_DECL_NOTHROW { return static_cast<QPdf::Rotation>(bits.rotation); }
- Q_DECL_RELAXED_CONSTEXPR void setRotation(QPdf::Rotation _rotation) Q_DECL_NOTHROW { bits.rotation = _rotation; }
+ Q_DECL_CONSTEXPR QPdf::Rotation rotation() const noexcept { return static_cast<QPdf::Rotation>(m_rotation); }
+ Q_DECL_RELAXED_CONSTEXPR void setRotation(QPdf::Rotation r) noexcept { m_rotation = r; }
- Q_DECL_CONSTEXPR QPdf::RenderFlags renderFlags() const Q_DECL_NOTHROW { return static_cast<QPdf::RenderFlags>(bits.renderFlags); }
- Q_DECL_RELAXED_CONSTEXPR void setRenderFlags(QPdf::RenderFlags _renderFlags) Q_DECL_NOTHROW { bits.renderFlags = _renderFlags; }
+ Q_DECL_CONSTEXPR QPdf::RenderFlags renderFlags() const noexcept { return static_cast<QPdf::RenderFlags>(m_renderFlags); }
+ Q_DECL_RELAXED_CONSTEXPR void setRenderFlags(QPdf::RenderFlags r) noexcept { m_renderFlags = r; }
- Q_DECL_CONSTEXPR QRect scaledClipRect() const Q_DECL_NOTHROW { return m_clipRect; }
- Q_DECL_RELAXED_CONSTEXPR void setScaledClipRect(const QRect &r) Q_DECL_NOTHROW { m_clipRect = r; }
+ Q_DECL_CONSTEXPR QRect scaledClipRect() const noexcept { return m_clipRect; }
+ Q_DECL_RELAXED_CONSTEXPR void setScaledClipRect(const QRect &r) noexcept { m_clipRect = r; }
- Q_DECL_CONSTEXPR QSize scaledSize() const Q_DECL_NOTHROW { return m_scaledSize; }
- Q_DECL_RELAXED_CONSTEXPR void setScaledSize(const QSize &s) Q_DECL_NOTHROW { m_scaledSize = s; }
+ Q_DECL_CONSTEXPR QSize scaledSize() const noexcept { return m_scaledSize; }
+ Q_DECL_RELAXED_CONSTEXPR void setScaledSize(const QSize &s) noexcept { m_scaledSize = s; }
private:
- friend Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW;
-
-
- struct Bits {
- quint32 renderFlags : 8;
- quint32 rotation : 3;
- quint32 reserved : 21;
- quint32 reserved2 : 32;
- };
-
- union {
- Bits bits;
- quint64 data;
- };
+ friend Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept;
QRect m_clipRect;
QSize m_scaledSize;
+
+ quint32 m_renderFlags : 8;
+ quint32 m_rotation : 3;
+ quint32 m_reserved : 21;
+ quint32 m_reserved2 = 0;
};
Q_DECLARE_TYPEINFO(QPdfDocumentRenderOptions, Q_PRIMITIVE_TYPE);
-Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW
+Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept
{
- return lhs.data == rhs.data && lhs.m_clipRect == rhs.m_clipRect && lhs.m_scaledSize == rhs.m_scaledSize;
+ return lhs.m_clipRect == rhs.m_clipRect && lhs.m_scaledSize == rhs.m_scaledSize &&
+ lhs.m_renderFlags == rhs.m_renderFlags && lhs.m_rotation == rhs.m_rotation &&
+ lhs.m_reserved == rhs.m_reserved && lhs.m_reserved2 == rhs.m_reserved2; // fix -Wunused-private-field
}
-Q_DECL_CONSTEXPR inline bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) Q_DECL_NOTHROW
+Q_DECL_CONSTEXPR inline bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept
{
return !operator==(lhs, rhs);
}
diff --git a/src/pdf/api/qpdfnamespace.h b/src/pdf/api/qpdfnamespace.h
index c8fd8a580..e76d0abd9 100644
--- a/src/pdf/api/qpdfnamespace.h
+++ b/src/pdf/api/qpdfnamespace.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+** 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.
@@ -37,7 +38,7 @@
#ifndef QPDFNAMESPACE_H
#define QPDFNAMESPACE_H
-#include <QObject>
+#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
diff --git a/src/pdf/api/qpdfpagenavigation.h b/src/pdf/api/qpdfpagenavigation.h
index 8da809646..0f416bf77 100644
--- a/src/pdf/api/qpdfpagenavigation.h
+++ b/src/pdf/api/qpdfpagenavigation.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+** 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.
@@ -38,7 +39,7 @@
#define QPDFPAGENAVIGATION_H
#include <QtPdf/qtpdfglobal.h>
-#include <QObject>
+#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
diff --git a/src/pdf/api/qpdfpagerenderer.h b/src/pdf/api/qpdfpagerenderer.h
index 0f8152cba..bb5505462 100644
--- a/src/pdf/api/qpdfpagerenderer.h
+++ b/src/pdf/api/qpdfpagerenderer.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+** 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.
@@ -56,15 +57,15 @@ class Q_PDF_EXPORT QPdfPageRenderer : public QObject
Q_PROPERTY(RenderMode renderMode READ renderMode WRITE setRenderMode NOTIFY renderModeChanged)
public:
- enum RenderMode
+ enum class RenderMode
{
- MultiThreadedRenderMode,
- SingleThreadedRenderMode
+ MultiThreaded,
+ SingleThreaded
};
Q_ENUM(RenderMode)
explicit QPdfPageRenderer(QObject *parent = nullptr);
- ~QPdfPageRenderer();
+ ~QPdfPageRenderer() override;
RenderMode renderMode() const;
void setRenderMode(RenderMode mode);
diff --git a/src/pdf/api/qpdfsearchmodel.h b/src/pdf/api/qpdfsearchmodel.h
index cc91e214a..eb0fb831f 100644
--- a/src/pdf/api/qpdfsearchmodel.h
+++ b/src/pdf/api/qpdfsearchmodel.h
@@ -37,11 +37,11 @@
#ifndef QPDFSEARCHMODEL_H
#define QPDFSEARCHMODEL_H
-#include "qtpdfglobal.h"
-#include "qpdfdocument.h"
-#include "qpdfsearchresult.h"
+#include <QtPdf/qtpdfglobal.h>
#include <QtCore/qabstractitemmodel.h>
+#include <QtPdf/qpdfdocument.h>
+#include <QtPdf/qpdfsearchresult.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +58,8 @@ public:
Page = Qt::UserRole,
IndexOnPage,
Location,
- Context,
+ ContextBefore,
+ ContextAfter,
_Count
};
Q_ENUM(Role)
diff --git a/src/pdf/api/qpdfsearchresult.h b/src/pdf/api/qpdfsearchresult.h
index db7af3dd9..2dfca2dc4 100644
--- a/src/pdf/api/qpdfsearchresult.h
+++ b/src/pdf/api/qpdfsearchresult.h
@@ -37,11 +37,10 @@
#ifndef QPDFSEARCHRESULT_H
#define QPDFSEARCHRESULT_H
-#include "qpdfdestination.h"
-
#include <QtCore/qdebug.h>
#include <QtCore/qrect.h>
#include <QtCore/qvector.h>
+#include <QtPdf/qpdfdestination.h>
QT_BEGIN_NAMESPACE
@@ -50,18 +49,20 @@ class QPdfSearchResultPrivate;
class Q_PDF_EXPORT QPdfSearchResult : public QPdfDestination
{
Q_GADGET
- Q_PROPERTY(QString context READ context)
+ Q_PROPERTY(QString contextBefore READ contextBefore)
+ Q_PROPERTY(QString contextAfter READ contextAfter)
Q_PROPERTY(QVector<QRectF> rectangles READ rectangles)
public:
QPdfSearchResult();
~QPdfSearchResult() {}
- QString context() const;
+ QString contextBefore() const;
+ QString contextAfter() const;
QVector<QRectF> rectangles() const;
private:
- QPdfSearchResult(int page, QVector<QRectF> rects, QString context);
+ QPdfSearchResult(int page, QVector<QRectF> rects, QString contextBefore, QString contextAfter);
QPdfSearchResult(QPdfSearchResultPrivate *d);
friend class QPdfDocument;
friend class QPdfSearchModelPrivate;
diff --git a/src/pdf/api/qpdfsearchresult_p.h b/src/pdf/api/qpdfsearchresult_p.h
index a0f8e4457..615dce4e0 100644
--- a/src/pdf/api/qpdfsearchresult_p.h
+++ b/src/pdf/api/qpdfsearchresult_p.h
@@ -56,12 +56,14 @@ class QPdfSearchResultPrivate : public QPdfDestinationPrivate
{
public:
QPdfSearchResultPrivate() = default;
- QPdfSearchResultPrivate(int page, QVector<QRectF> rects, QString context) :
+ QPdfSearchResultPrivate(int page, QVector<QRectF> rects, QString contextBefore, QString contextAfter) :
QPdfDestinationPrivate(page, rects.first().topLeft(), 0),
- context(context),
+ contextBefore(contextBefore),
+ contextAfter(contextAfter),
rects(rects) {}
- QString context;
+ QString contextBefore;
+ QString contextAfter;
QVector<QRectF> rects;
};
diff --git a/src/pdf/api/qpdfselection.h b/src/pdf/api/qpdfselection.h
index 900b203cf..5a6a1cddc 100644
--- a/src/pdf/api/qpdfselection.h
+++ b/src/pdf/api/qpdfselection.h
@@ -38,10 +38,11 @@
#define QPDFSELECTION_H
#include <QtPdf/qtpdfglobal.h>
-#include <QClipboard>
-#include <QExplicitlySharedDataPointer>
-#include <QObject>
-#include <QPolygonF>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
+#include <QtGui/qclipboard.h>
+#include <QtGui/qpolygon.h>
QT_BEGIN_NAMESPACE
@@ -55,10 +56,11 @@ class Q_PDF_EXPORT QPdfSelection
Q_PROPERTY(QString text READ text)
public:
- QPdfSelection(const QPdfSelection &other);
~QPdfSelection();
+ QPdfSelection(const QPdfSelection &other);
QPdfSelection &operator=(const QPdfSelection &other);
- inline QPdfSelection &operator=(QPdfSelection &&other) noexcept { swap(other); return *this; }
+ QPdfSelection(QPdfSelection &&other) noexcept;
+ QPdfSelection &operator=(QPdfSelection &&other) noexcept { swap(other); return *this; }
void swap(QPdfSelection &other) noexcept { d.swap(other.d); }
bool isValid() const;
QVector<QPolygonF> bounds() const;
diff --git a/src/pdf/api/qtpdfglobal.h b/src/pdf/api/qtpdfglobal.h
index 34cfc46d9..223ec4bcb 100644
--- a/src/pdf/api/qtpdfglobal.h
+++ b/src/pdf/api/qtpdfglobal.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
diff --git a/src/pdf/configure.json b/src/pdf/configure.json
index 1f21183a2..ddc0e99dc 100644
--- a/src/pdf/configure.json
+++ b/src/pdf/configure.json
@@ -2,7 +2,7 @@
"module": "pdf",
"depends" : [ "buildtools-private" ],
"testDir": "../../config.tests",
- "condition": "features.build-qtpdf",
+ "condition": "features.build-qtpdf && features.webengine-qtpdf-support",
"libraries": {
},
"tests": {
diff --git a/src/pdf/gn_run.pro b/src/pdf/gn_run.pro
index 7fd4d4ffc..87070fd81 100644
--- a/src/pdf/gn_run.pro
+++ b/src/pdf/gn_run.pro
@@ -3,7 +3,8 @@ QT_FOR_CONFIG += buildtools-private
TEMPLATE = aux
-qtConfig(debug_and_release): CONFIG += debug_and_release build_all
+qtConfig(debug_and_release): CONFIG += debug_and_release
+qtConfig(build_all): CONFIG += build_all
qtConfig(webengine-system-ninja) {
QT_TOOL.ninja.binary = ninja
diff --git a/src/pdf/jsbridge.cpp b/src/pdf/jsbridge.cpp
index 95b813929..33d3b2465 100644
--- a/src/pdf/jsbridge.cpp
+++ b/src/pdf/jsbridge.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
diff --git a/src/pdf/qpdfbookmarkmodel.cpp b/src/pdf/qpdfbookmarkmodel.cpp
index e648657ba..c9c365568 100644
--- a/src/pdf/qpdfbookmarkmodel.cpp
+++ b/src/pdf/qpdfbookmarkmodel.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
diff --git a/src/pdf/qpdfdestination.cpp b/src/pdf/qpdfdestination.cpp
index b347445e9..b70e031ca 100644
--- a/src/pdf/qpdfdestination.cpp
+++ b/src/pdf/qpdfdestination.cpp
@@ -73,6 +73,11 @@ QPdfDestination::QPdfDestination(const QPdfDestination &other)
{
}
+QPdfDestination::QPdfDestination(QPdfDestination &&other) noexcept
+ : d(std::move(other.d))
+{
+}
+
QPdfDestination::~QPdfDestination()
{
}
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index 1e8a0f527..89b27da8b 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -393,6 +393,15 @@ void QPdfDocumentPrivate::fpdf_AddSegment(_FX_DOWNLOADHINTS *pThis, size_t offse
Q_UNUSED(size);
}
+QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int count)
+{
+ QVector<ushort> buf(count + 1);
+ // TODO is that enough space in case one unicode character is more than one in utf-16?
+ int len = FPDFText_GetText(textPage, startIndex, count, buf.data());
+ Q_ASSERT(len - 1 <= count); // len is number of characters written, including the terminator
+ return QString::fromUtf16(buf.constData(), len - 1);
+}
+
/*!
\class QPdfDocument
\since 5.10
@@ -737,15 +746,10 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
int endIndex = FPDFText_GetCharIndexAtPos(textPage, end.x(), pageHeight - end.y(),
CharacterHitTolerance, CharacterHitTolerance);
if (startIndex >= 0 && endIndex != startIndex) {
- QString text;
if (startIndex > endIndex)
qSwap(startIndex, endIndex);
int count = endIndex - startIndex + 1;
- QVector<ushort> buf(count + 1);
- // TODO is that enough space in case one unicode character is more than one in utf-16?
- int len = FPDFText_GetText(textPage, startIndex, count, buf.data());
- Q_ASSERT(len - 1 <= count); // len is number of characters written, including the terminator
- text = QString::fromUtf16(buf.constData(), len - 1);
+ QString text = d->getText(textPage, startIndex, count);
QVector<QPolygonF> bounds;
int rectCount = FPDFText_CountRects(textPage, startIndex, endIndex - startIndex);
for (int i = 0; i < rectCount; ++i) {
@@ -767,6 +771,33 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
return QPdfSelection();
}
+QPdfSelection QPdfDocument::getAllText(int page)
+{
+ const QPdfMutexLocker lock;
+ FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
+ double pageHeight = FPDF_GetPageHeight(pdfPage);
+ FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
+ int count = FPDFText_CountChars(textPage);
+ if (count < 1)
+ return QPdfSelection();
+ QString text = d->getText(textPage, 0, count);
+ QVector<QPolygonF> bounds;
+ int rectCount = FPDFText_CountRects(textPage, 0, count);
+ for (int i = 0; i < rectCount; ++i) {
+ double l, r, b, t;
+ FPDFText_GetRect(textPage, i, &l, &t, &r, &b);
+ QPolygonF poly;
+ poly << QPointF(l, pageHeight - t);
+ poly << QPointF(r, pageHeight - t);
+ poly << QPointF(r, pageHeight - b);
+ poly << QPointF(l, pageHeight - b);
+ poly << QPointF(l, pageHeight - t);
+ bounds << poly;
+ }
+ qCDebug(qLcDoc) << "on page" << page << "got" << count << "chars" << rectCount << "rects";
+ return QPdfSelection(text, bounds);
+}
+
QT_END_NAMESPACE
#include "moc_qpdfdocument.cpp"
diff --git a/src/pdf/qpdflinkmodel.cpp b/src/pdf/qpdflinkmodel.cpp
index 96e6ddd5c..900d3cd9e 100644
--- a/src/pdf/qpdflinkmodel.cpp
+++ b/src/pdf/qpdflinkmodel.cpp
@@ -104,7 +104,8 @@ void QPdfLinkModel::setDocument(QPdfDocument *document)
Q_D(QPdfLinkModel);
if (d->document == document)
return;
- disconnect(d->document, &QPdfDocument::statusChanged, this, &QPdfLinkModel::onStatusChanged);
+ if (d->document)
+ disconnect(d->document, &QPdfDocument::statusChanged, this, &QPdfLinkModel::onStatusChanged);
connect(document, &QPdfDocument::statusChanged, this, &QPdfLinkModel::onStatusChanged);
d->document = document;
emit documentChanged();
@@ -144,7 +145,7 @@ void QPdfLinkModelPrivate::update()
const QPdfMutexLocker lock;
FPDF_PAGE pdfPage = FPDF_LoadPage(doc, page);
if (!pdfPage) {
- qWarning() << "failed to load page" << page;
+ qCWarning(qLcLink) << "failed to load page" << page;
return;
}
double pageHeight = FPDF_GetPageHeight(pdfPage);
@@ -153,35 +154,76 @@ void QPdfLinkModelPrivate::update()
// Iterate the ordinary links
int linkStart = 0;
- bool ok = true;
- while (ok) {
+ bool hasNext = true;
+ while (hasNext) {
FPDF_LINK linkAnnot;
- ok = FPDFLink_Enumerate(pdfPage, &linkStart, &linkAnnot);
- if (!ok)
+ hasNext = FPDFLink_Enumerate(pdfPage, &linkStart, &linkAnnot);
+ if (!hasNext)
break;
FS_RECTF rect;
- ok = FPDFLink_GetAnnotRect(linkAnnot, &rect);
- if (!ok)
- break;
+ bool ok = FPDFLink_GetAnnotRect(linkAnnot, &rect);
+ if (!ok) {
+ qCWarning(qLcLink) << "skipping link with invalid bounding box";
+ continue; // while enumerating links
+ }
Link linkData;
linkData.rect = QRectF(rect.left, pageHeight - rect.top,
rect.right - rect.left, rect.top - rect.bottom);
FPDF_DEST dest = FPDFLink_GetDest(doc, linkAnnot);
FPDF_ACTION action = FPDFLink_GetAction(linkAnnot);
- if (FPDFAction_GetType(action) != PDFACTION_GOTO) {
- qWarning() << "link action type" << FPDFAction_GetType(action) << "is not yet supported";
- continue;
+ switch (FPDFAction_GetType(action)) {
+ case PDFACTION_UNSUPPORTED: // this happens with valid links in some PDFs
+ case PDFACTION_GOTO: {
+ linkData.page = FPDFDest_GetDestPageIndex(doc, dest);
+ if (linkData.page < 0) {
+ qCWarning(qLcLink) << "skipping link with invalid page number";
+ continue; // while enumerating links
+ }
+ FPDF_BOOL hasX, hasY, hasZoom;
+ FS_FLOAT x, y, zoom;
+ ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom);
+ if (!ok) {
+ qCWarning(qLcLink) << "link with invalid location and/or zoom @" << linkData.rect;
+ break; // at least we got a page number, so the link will jump there
+ }
+ if (hasX && hasY)
+ linkData.location = QPointF(x, pageHeight - y);
+ if (hasZoom)
+ linkData.zoom = zoom;
+ break;
+ }
+ case PDFACTION_URI: {
+ unsigned long len = FPDFAction_GetURIPath(doc, action, nullptr, 0);
+ if (len < 1) {
+ qCWarning(qLcLink) << "skipping link with empty URI @" << linkData.rect;
+ continue; // while enumerating links
+ } else {
+ QByteArray buf(len, 0);
+ unsigned long got = FPDFAction_GetURIPath(doc, action, buf.data(), len);
+ Q_ASSERT(got == len);
+ linkData.url = QString::fromLatin1(buf.data(), got - 1);
+ }
+ break;
}
- linkData.page = FPDFDest_GetDestPageIndex(doc, dest);
- FPDF_BOOL hasX, hasY, hasZoom;
- FS_FLOAT x, y, zoom;
- ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom);
- if (!ok)
+ case PDFACTION_LAUNCH:
+ case PDFACTION_REMOTEGOTO: {
+ unsigned long len = FPDFAction_GetFilePath(action, nullptr, 0);
+ if (len < 1) {
+ qCWarning(qLcLink) << "skipping link with empty file path @" << linkData.rect;
+ continue; // while enumerating links
+ } else {
+ QByteArray buf(len, 0);
+ unsigned long got = FPDFAction_GetFilePath(action, buf.data(), len);
+ Q_ASSERT(got == len);
+ linkData.url = QUrl::fromLocalFile(QString::fromLatin1(buf.data(), got - 1)).toString();
+
+ // Unfortunately, according to comments in fpdf_doc.h, if it's PDFACTION_REMOTEGOTO,
+ // we can't get the page and location without first opening the linked document
+ // and then calling FPDFAction_GetDest() again.
+ }
break;
- if (hasX && hasY)
- linkData.location = QPointF(x, pageHeight - y);
- if (hasZoom)
- linkData.zoom = zoom;
+ }
+ }
links << linkData;
}
@@ -195,7 +237,7 @@ void QPdfLinkModelPrivate::update()
Link linkData;
int len = FPDFLink_GetURL(webLinks, i, nullptr, 0);
if (len < 1) {
- qWarning() << "URL" << i << "has length" << len;
+ qCWarning(qLcLink) << "skipping link" << i << "with empty URL";
} else {
QVector<unsigned short> buf(len);
int got = FPDFLink_GetURL(webLinks, i, buf.data(), len);
diff --git a/src/pdf/qpdfpagerenderer.cpp b/src/pdf/qpdfpagerenderer.cpp
index 90fb0319e..460e95bed 100644
--- a/src/pdf/qpdfpagerenderer.cpp
+++ b/src/pdf/qpdfpagerenderer.cpp
@@ -78,7 +78,7 @@ public:
void requestFinished(int page, QSize imageSize, const QImage &image,
QPdfDocumentRenderOptions options, quint64 requestId);
- QPdfPageRenderer::RenderMode m_renderMode = QPdfPageRenderer::SingleThreadedRenderMode;
+ QPdfPageRenderer::RenderMode m_renderMode = QPdfPageRenderer::RenderMode::SingleThreaded;
QPointer<QPdfDocument> m_document;
struct PageRequest
@@ -163,6 +163,8 @@ void QPdfPageRendererPrivate::handleNextRequest()
void QPdfPageRendererPrivate::requestFinished(int page, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions options, quint64 requestId)
{
+ Q_UNUSED(image);
+ Q_UNUSED(requestId);
const auto it = std::find_if(m_pendingRequests.begin(), m_pendingRequests.end(),
[page, imageSize, options](const PageRequest &request){ return request.pageNumber == page && request.imageSize == imageSize && request.options == options; });
@@ -179,8 +181,8 @@ void QPdfPageRendererPrivate::requestFinished(int page, QSize imageSize, const Q
The QPdfPageRenderer contains a queue that collects all render requests that are invoked through
requestPage(). Depending on the configured RenderMode the QPdfPageRenderer processes this queue
- in the main UI thread on next event loop invocation (SingleThreadedRenderMode) or in a separate worker thread
- (MultiThreadedRenderMode) and emits the result through the pageRendered() signal for each request once
+ in the main UI thread on next event loop invocation (\c RenderMode::SingleThreaded) or in a separate worker thread
+ (\c RenderMode::MultiThreaded) and emits the result through the pageRendered() signal for each request once
the rendering is done.
\sa QPdfDocument
@@ -217,8 +219,8 @@ QPdfPageRenderer::~QPdfPageRenderer()
This enum describes how the pages are rendered.
- \value MultiThreadedRenderMode All pages are rendered in a separate worker thread.
- \value SingleThreadedRenderMode All pages are rendered in the main UI thread (default).
+ \value MultiThreaded All pages are rendered in a separate worker thread.
+ \value SingleThreaded All pages are rendered in the main UI thread (default).
\sa renderMode(), setRenderMode()
*/
@@ -227,7 +229,7 @@ QPdfPageRenderer::~QPdfPageRenderer()
\property QPdfPageRenderer::renderMode
\brief The mode the renderer uses to render the pages.
- By default, this property is \c QPdfPageRenderer::SingleThreaded.
+ By default, this property is \c RenderMode::SingleThreaded.
\sa setRenderMode(), RenderMode
*/
@@ -259,7 +261,7 @@ void QPdfPageRenderer::setRenderMode(RenderMode mode)
d->m_renderMode = mode;
emit renderModeChanged(d->m_renderMode);
- if (d->m_renderMode == MultiThreadedRenderMode) {
+ if (d->m_renderMode == RenderMode::MultiThreaded) {
d->m_renderThread = new QThread;
d->m_renderWorker->moveToThread(d->m_renderThread);
d->m_renderThread->start();
@@ -331,7 +333,7 @@ quint64 QPdfPageRenderer::requestPage(int pageNumber, QSize imageSize,
if (!d->m_document || d->m_document->status() != QPdfDocument::Ready)
return 0;
- for (const auto request : qAsConst(d->m_pendingRequests)) {
+ for (const auto &request : qAsConst(d->m_pendingRequests)) {
if (request.pageNumber == pageNumber
&& request.imageSize == imageSize
&& request.options == options)
diff --git a/src/pdf/qpdfsearchmodel.cpp b/src/pdf/qpdfsearchmodel.cpp
index 4129c7cb7..27b7833fc 100644
--- a/src/pdf/qpdfsearchmodel.cpp
+++ b/src/pdf/qpdfsearchmodel.cpp
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcS, "qt.pdf.search")
static const int UpdateTimerInterval = 100;
-static const int ContextChars = 20;
+static const int ContextChars = 64;
static const double CharacterHitTolerance = 6.0;
QPdfSearchModel::QPdfSearchModel(QObject *parent)
@@ -95,13 +95,19 @@ QVariant QPdfSearchModel::data(const QModelIndex &index, int role) const
return pi.index;
case Role::Location:
return d->searchResults[pi.page][pi.index].location();
- case Role::Context:
- return d->searchResults[pi.page][pi.index].context();
+ case Role::ContextBefore:
+ return d->searchResults[pi.page][pi.index].contextBefore();
+ case Role::ContextAfter:
+ return d->searchResults[pi.page][pi.index].contextAfter();
case Role::_Count:
break;
}
- if (role == Qt::DisplayRole)
- return d->searchResults[pi.page][pi.index].context();
+ if (role == Qt::DisplayRole) {
+ const QString ret = d->searchResults[pi.page][pi.index].contextBefore() +
+ QLatin1String("<b>") + d->searchString + QLatin1String("</b>") +
+ d->searchResults[pi.page][pi.index].contextAfter();
+ return ret;
+ }
return QVariant();
}
@@ -124,9 +130,9 @@ void QPdfSearchModel::setSearchString(QString searchString)
return;
d->searchString = searchString;
- emit searchStringChanged();
beginResetModel();
d->clearResults();
+ emit searchStringChanged();
endResetModel();
}
@@ -161,8 +167,8 @@ void QPdfSearchModel::setDocument(QPdfDocument *document)
return;
d->document = document;
- emit documentChanged();
d->clearResults();
+ emit documentChanged();
}
void QPdfSearchModel::timerEvent(QTimerEvent *event)
@@ -179,7 +185,7 @@ void QPdfSearchModel::timerEvent(QTimerEvent *event)
d->doSearch(d->nextPageToUpdate++);
}
-QPdfSearchModelPrivate::QPdfSearchModelPrivate()
+QPdfSearchModelPrivate::QPdfSearchModelPrivate() : QAbstractItemModelPrivate()
{
}
@@ -246,7 +252,7 @@ bool QPdfSearchModelPrivate::doSearch(int page)
}
qCDebug(qLcS) << rects.last() << "char idx" << startIndex << "->" << endIndex;
}
- QString context;
+ QString contextBefore, contextAfter;
if (startIndex >= 0 || endIndex >= 0) {
startIndex = qMax(0, startIndex - ContextChars);
endIndex += ContextChars;
@@ -255,13 +261,21 @@ bool QPdfSearchModelPrivate::doSearch(int page)
QVector<ushort> buf(count + 1);
int len = FPDFText_GetText(textPage, startIndex, count, buf.data());
Q_ASSERT(len - 1 <= count); // len is number of characters written, including the terminator
- context = QString::fromUtf16(buf.constData(), len - 1);
- context = context.replace(QLatin1Char('\n'), QLatin1Char(' '));
- context = context.replace(searchString,
- QLatin1String("<b>") + searchString + QLatin1String("</b>"));
+ QString context = QString::fromUtf16(buf.constData(), len - 1);
+ context = context.replace(QLatin1Char('\n'), QStringLiteral("\u23CE"));
+ context = context.remove(QLatin1Char('\r'));
+ // try to find the search string near the middle of the context if possible
+ int si = context.indexOf(searchString, ContextChars - 5, Qt::CaseInsensitive);
+ if (si < 0)
+ si = context.indexOf(searchString, Qt::CaseInsensitive);
+ if (si < 0)
+ qWarning() << "search string" << searchString << "not found in context" << context;
+ contextBefore = context.mid(0, si);
+ contextAfter = context.mid(si + searchString.length());
}
}
- newSearchResults << QPdfSearchResult(page, rects, context);
+ if (!rects.isEmpty())
+ newSearchResults << QPdfSearchResult(page, rects, contextBefore, contextAfter);
}
FPDFText_FindClose(sh);
FPDFText_ClosePage(textPage);
diff --git a/src/pdf/qpdfsearchresult.cpp b/src/pdf/qpdfsearchresult.cpp
index 1164a1d43..53da1c165 100644
--- a/src/pdf/qpdfsearchresult.cpp
+++ b/src/pdf/qpdfsearchresult.cpp
@@ -42,15 +42,20 @@ QT_BEGIN_NAMESPACE
QPdfSearchResult::QPdfSearchResult() :
QPdfSearchResult(new QPdfSearchResultPrivate()) { }
-QPdfSearchResult::QPdfSearchResult(int page, QVector<QRectF> rects, QString context) :
- QPdfSearchResult(new QPdfSearchResultPrivate(page, rects, context)) { }
+QPdfSearchResult::QPdfSearchResult(int page, QVector<QRectF> rects, QString contextBefore, QString contextAfter) :
+ QPdfSearchResult(new QPdfSearchResultPrivate(page, rects, contextBefore, contextAfter)) { }
QPdfSearchResult::QPdfSearchResult(QPdfSearchResultPrivate *d) :
QPdfDestination(static_cast<QPdfDestinationPrivate *>(d)) { }
-QString QPdfSearchResult::context() const
+QString QPdfSearchResult::contextBefore() const
{
- return static_cast<QPdfSearchResultPrivate *>(d.data())->context;
+ return static_cast<QPdfSearchResultPrivate *>(d.data())->contextBefore;
+}
+
+QString QPdfSearchResult::contextAfter() const
+{
+ return static_cast<QPdfSearchResultPrivate *>(d.data())->contextAfter;
}
QVector<QRectF> QPdfSearchResult::rectangles() const
@@ -63,7 +68,8 @@ QDebug operator<<(QDebug dbg, const QPdfSearchResult &searchResult)
QDebugStateSaver saver(dbg);
dbg.nospace();
dbg << "QPdfSearchResult(page=" << searchResult.page()
- << " context=" << searchResult.context()
+ << " contextBefore=" << searchResult.contextBefore()
+ << " contextAfter=" << searchResult.contextAfter()
<< " rects=" << searchResult.rectangles();
dbg << ')';
return dbg;
diff --git a/src/pdf/qpdfselection.cpp b/src/pdf/qpdfselection.cpp
index 8c3d6fde0..e334f0fb6 100644
--- a/src/pdf/qpdfselection.cpp
+++ b/src/pdf/qpdfselection.cpp
@@ -82,10 +82,21 @@ QPdfSelection::QPdfSelection(const QPdfSelection &other)
{
}
+QPdfSelection::QPdfSelection(QPdfSelection &&other) noexcept
+ : d(std::move(other.d))
+{
+}
+
QPdfSelection::~QPdfSelection()
{
}
+QPdfSelection &QPdfSelection::operator=(const QPdfSelection &other)
+{
+ d = other.d;
+ return *this;
+}
+
/*!
\property QPdfSelection::valid
diff --git a/src/pdf/quick/plugin.cpp b/src/pdf/quick/plugin.cpp
index bb68a817e..670fe0bf9 100644
--- a/src/pdf/quick/plugin.cpp
+++ b/src/pdf/quick/plugin.cpp
@@ -71,7 +71,9 @@ public:
void initializeEngine(QQmlEngine *engine, const char *uri) override {
Q_UNUSED(uri);
-#ifndef QT_STATIC
+#ifdef QT_STATIC
+ Q_UNUSED(engine);
+#else
engine->addImportPath(QStringLiteral("qrc:/"));
#endif
}
diff --git a/src/pdf/quick/qml/+material/PdfStyle.qml b/src/pdf/quick/qml/+material/PdfStyle.qml
new file mode 100644
index 000000000..12df30466
--- /dev/null
+++ b/src/pdf/quick/qml/+material/PdfStyle.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+import QtQml 2.14
+import QtQuick.Controls 2.14
+import QtQuick.Controls.Material 2.14
+import QtQuick.Shapes 1.14
+
+QtObject {
+ property Control prototypeControl: Control { }
+ function withAlpha(color, alpha) {
+ return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
+ }
+ property color selectionColor: withAlpha(prototypeControl.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
+ property color linkUnderscoreColor: prototypeControl.palette.link
+ property real linkUnderscoreStrokeWidth: 1
+ property var linkUnderscoreStrokeStyle: ShapePath.DashLine
+ property var linkUnderscoreDashPattern: [ 1, 4 ]
+}
diff --git a/src/pdf/quick/qml/+universal/PdfStyle.qml b/src/pdf/quick/qml/+universal/PdfStyle.qml
new file mode 100644
index 000000000..e92f2a080
--- /dev/null
+++ b/src/pdf/quick/qml/+universal/PdfStyle.qml
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+import QtQml 2.14
+import QtQuick 2.14
+import QtQuick.Controls 2.14
+import QtQuick.Controls.Universal 2.14
+import QtQuick.Shapes 1.14
+
+QtObject {
+ property Control prototypeControl: Control { }
+ function withAlpha(color, alpha) {
+ return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
+ }
+ property color selectionColor: withAlpha(prototypeControl.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
+ property color linkUnderscoreColor: prototypeControl.palette.link
+ property real linkUnderscoreStrokeWidth: 1
+ property var linkUnderscoreStrokeStyle: ShapePath.DashLine
+ property var linkUnderscoreDashPattern: [ 1, 4 ]
+}
diff --git a/src/pdf/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml
index e8eccaf3b..70bb5454f 100644
--- a/src/pdf/quick/qml/PdfMultiPageView.qml
+++ b/src/pdf/quick/qml/PdfMultiPageView.qml
@@ -1,48 +1,34 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
+** Contact: http://www.qt.io/licensing/
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the QtPDF module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:BSD$
+** $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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
+** 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.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** 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$
**
@@ -61,6 +47,11 @@ Item {
property bool debug: false
property string selectedText
+ function selectAll() {
+ var currentItem = tableView.itemAtPos(0, tableView.contentY + root.height / 2)
+ if (currentItem !== null)
+ currentItem.selection.selectAll()
+ }
function copySelectionToClipboard() {
var currentItem = tableView.itemAtPos(0, tableView.contentY + root.height / 2)
if (debug)
@@ -84,6 +75,7 @@ Item {
if (zoom > 0)
root.renderScale = zoom
navigationStack.push(page, location, zoom)
+ searchModel.currentPage = page
}
// page scaling
@@ -118,16 +110,18 @@ Item {
function searchForward() { ++searchModel.currentResult }
id: root
+ PdfStyle { id: style }
TableView {
id: tableView
anchors.fill: parent
+ anchors.leftMargin: 2
model: root.document === undefined ? 0 : root.document.pageCount
rowSpacing: 6
- property real rotationModulus: Math.abs(root.pageRotation % 180)
- property bool rot90: rotationModulus > 45 && rotationModulus < 135
+ property real rotationNorm: Math.round((360 + (root.pageRotation % 360)) % 360)
+ property bool rot90: rotationNorm == 90 || rotationNorm == 270
onRot90Changed: forceLayout()
property size firstPagePointSize: document === undefined ? Qt.size(0, 0) : document.pagePointSize(0)
- contentWidth: document === undefined ? 0 : document.maxPageWidth * root.renderScale
+ contentWidth: document === undefined ? 0 : (rot90 ? document.maxPageHeight : document.maxPageWidth) * root.renderScale + vscroll.width + 2
// workaround for missing function (see https://codereview.qt-project.org/c/qt/qtdeclarative/+/248464)
function itemAtPos(x, y, includeSpacing) {
// we don't care about x (assume col 0), and assume includeSpacing is true
@@ -139,7 +133,7 @@ Item {
if (child.y < y && (!ret || child.y > ret.y))
ret = child
}
- if (root.debug)
+ if (root.debug && ret !== null)
console.log("given y", y, "found", ret, "@", ret.y)
return ret // the delegate with the largest y that is less than the given y
}
@@ -164,7 +158,7 @@ Item {
width: image.width
height: image.height
rotation: root.pageRotation
- anchors.centerIn: parent
+ anchors.centerIn: pinch.active ? undefined : parent
property size pagePointSize: document.pagePointSize(index)
property real pageScale: image.paintedWidth / pagePointSize.width
Image {
@@ -181,38 +175,47 @@ Item {
image.sourceSize.width = paper.pagePointSize.width * renderScale
image.sourceSize.height = 0
paper.scale = 1
+ searchHighlights.update()
}
}
Shape {
anchors.fill: parent
- opacity: 0.25
visible: image.status === Image.Ready
+ onVisibleChanged: searchHighlights.update()
ShapePath {
- strokeWidth: 1
- strokeColor: "cyan"
- fillColor: "steelblue"
+ strokeWidth: -1
+ fillColor: style.pageSearchResultsColor
scale: Qt.size(paper.pageScale, paper.pageScale)
PathMultiline {
- paths: searchModel.boundingPolygonsOnPage(index)
+ id: searchHighlights
+ function update() {
+ // paths could be a binding, but we need to be able to "kick" it sometimes
+ paths = searchModel.boundingPolygonsOnPage(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 {
- fillColor: "orange"
+ strokeWidth: -1
+ fillColor: style.selectionColor
scale: Qt.size(paper.pageScale, paper.pageScale)
PathMultiline {
- id: selectionBoundaries
paths: selection.geometry
}
}
}
Shape {
anchors.fill: parent
- opacity: 0.5
visible: image.status === Image.Ready && searchModel.currentPage === index
ShapePath {
- strokeWidth: 1
- strokeColor: "blue"
- fillColor: "cyan"
+ strokeWidth: style.currentSearchResultStrokeWidth
+ strokeColor: style.currentSearchResultStrokeColor
+ fillColor: "transparent"
scale: Qt.size(paper.pageScale, paper.pageScale)
PathMultiline {
paths: searchModel.currentResultBoundingPolygons
@@ -223,19 +226,46 @@ Item {
id: pinch
minimumScale: 0.1
maximumScale: root.renderScale < 4 ? 2 : 1
- minimumRotation: 0
- maximumRotation: 0
+ minimumRotation: root.pageRotation
+ maximumRotation: root.pageRotation
enabled: image.sourceSize.width < 5000
onActiveChanged:
if (active) {
paper.z = 10
} else {
paper.z = 0
+ var centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
+ pinch.centroid.position.y / root.renderScale)
+ var centroidInFlickable = tableView.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
var newSourceWidth = image.sourceSize.width * paper.scale
var ratio = newSourceWidth / image.sourceSize.width
+ if (root.debug)
+ console.log("pinch ended on page", index, "with 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) {
+ var centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
paper.scale = 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
+ }
+ if (root.debug)
+ console.log("contentX/Y adjusted to", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2), "y @top", pageHolder.y)
+ tableView.returnToBounds()
}
}
grabPermissions: PointerHandler.CanTakeOverFromAnything
@@ -255,13 +285,19 @@ Item {
document: root.document
page: image.currentFrame
}
- delegate: Rectangle {
- color: "transparent"
- border.color: "lightgrey"
+ delegate: Shape {
x: rect.x * paper.pageScale
y: rect.y * paper.pageScale
width: rect.width * paper.pageScale
height: rect.height * paper.pageScale
+ ShapePath {
+ strokeWidth: style.linkUnderscoreStrokeWidth
+ strokeColor: style.linkUnderscoreColor
+ strokeStyle: style.linkUnderscoreStrokeStyle
+ dashPattern: style.linkUnderscoreDashPattern
+ startX: 0; startY: height
+ PathLine { x: width; y: height }
+ }
MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
id: linkMA
anchors.fill: parent
@@ -298,6 +334,7 @@ Item {
}
}
ScrollBar.vertical: ScrollBar {
+ id: vscroll
property bool moved: false
onPositionChanged: moved = true
onActiveChanged: {
@@ -337,6 +374,6 @@ Item {
PdfSearchModel {
id: searchModel
document: root.document === undefined ? null : root.document
- onCurrentPageChanged: root.goToPage(currentPage)
+ onCurrentPageChanged: if (currentPage != navigationStack.currentPage) root.goToPage(currentPage)
}
}
diff --git a/src/pdf/quick/qml/PdfPageView.qml b/src/pdf/quick/qml/PdfPageView.qml
index dfd00a1a8..b90ad2d7f 100644
--- a/src/pdf/quick/qml/PdfPageView.qml
+++ b/src/pdf/quick/qml/PdfPageView.qml
@@ -46,6 +46,9 @@ Rectangle {
property alias status: image.status
property alias selectedText: selection.text
+ function selectAll() {
+ selection.selectAll()
+ }
function copySelectionToClipboard() {
selection.copyToClipboard()
}
diff --git a/src/pdf/quick/qml/PdfScrollablePageView.qml b/src/pdf/quick/qml/PdfScrollablePageView.qml
index 55aa44bbf..6076e57df 100644
--- a/src/pdf/quick/qml/PdfScrollablePageView.qml
+++ b/src/pdf/quick/qml/PdfScrollablePageView.qml
@@ -47,6 +47,9 @@ Flickable {
property alias status: image.status
property alias selectedText: selection.text
+ function selectAll() {
+ selection.selectAll()
+ }
function copySelectionToClipboard() {
selection.copyToClipboard()
}
@@ -101,6 +104,7 @@ Flickable {
// implementation
id: root
+ PdfStyle { id: style }
contentWidth: paper.width
contentHeight: paper.height
ScrollBar.vertical: ScrollBar {
@@ -175,63 +179,76 @@ Flickable {
rotation: root.pageRotation
anchors.centerIn: parent
property real pageScale: image.paintedWidth / document.pagePointSize(navigationStack.currentPage).width
- }
- 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
+ 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: 1
- strokeColor: "orange"
- fillColor: "cyan"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
+ ShapePath {
+ strokeWidth: style.currentSearchResultStrokeWidth
+ strokeColor: style.currentSearchResultStrokeColor
+ fillColor: "transparent"
+ 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
+ ShapePath {
+ fillColor: style.selectionColor
+ scale: Qt.size(image.pageScale, image.pageScale)
+ PathMultiline {
+ paths: selection.geometry
+ }
}
}
- }
- Repeater {
- model: PdfLinkModel {
- id: linkModel
- document: root.document
- page: navigationStack.currentPage
- }
- delegate: Rectangle {
- color: "transparent"
- border.color: "lightgrey"
- x: rect.x * image.pageScale
- y: rect.y * image.pageScale
- width: rect.width * image.pageScale
- height: rect.height * image.pageScale
- MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (page >= 0)
- navigationStack.push(page, Qt.point(0, 0), root.renderScale)
- else
- Qt.openUrlExternally(url)
+ Repeater {
+ model: PdfLinkModel {
+ id: linkModel
+ document: root.document
+ page: navigationStack.currentPage
+ }
+ delegate: Shape {
+ x: rect.x * image.pageScale
+ y: rect.y * image.pageScale
+ width: rect.width * image.pageScale
+ height: rect.height * image.pageScale
+ ShapePath {
+ strokeWidth: style.linkUnderscoreStrokeWidth
+ strokeColor: style.linkUnderscoreColor
+ strokeStyle: style.linkUnderscoreStrokeStyle
+ dashPattern: style.linkUnderscoreDashPattern
+ startX: 0; startY: height
+ PathLine { x: width; y: height }
+ }
+ MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ if (page >= 0)
+ navigationStack.push(page, Qt.point(0, 0), root.renderScale)
+ else
+ Qt.openUrlExternally(url)
+ }
}
}
}
+ DragHandler {
+ id: textSelectionDrag
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ target: null
+ }
+ TapHandler {
+ id: tapHandler
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ }
}
PinchHandler {
@@ -243,32 +260,31 @@ Flickable {
enabled: image.sourceSize.width < 5000
onActiveChanged:
if (!active) {
+ var centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
+ pinch.centroid.position.y / root.renderScale)
+ var centroidInFlickable = root.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
var newSourceWidth = image.sourceSize.width * paper.scale
var ratio = newSourceWidth / image.sourceSize.width
+ if (root.debug)
+ console.log("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) {
+ var centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
paper.scale = 1
- root.renderScale *= ratio
+ paper.x = 0
+ paper.y = 0
+ root.contentX = centroidOnPage.x - centroidInFlickable.x
+ root.contentY = centroidOnPage.y - centroidInFlickable.y
+ root.renderScale *= ratio // onRenderScaleChanged calls navigationStack.update() so we don't need to here
+ if (root.debug)
+ console.log("contentX/Y adjusted to", root.contentX.toFixed(2), root.contentY.toFixed(2))
+ } else {
+ paper.x = 0
+ paper.y = 0
}
- // TODO adjust contentX/Y to position the page so the same region is visible
- paper.x = 0
- paper.y = 0
}
grabPermissions: PointerHandler.CanTakeOverFromAnything
}
- DragHandler {
- id: pageMovingMiddleMouseDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- 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/qml/PdfStyle.qml b/src/pdf/quick/qml/PdfStyle.qml
new file mode 100644
index 000000000..090465ce6
--- /dev/null
+++ b/src/pdf/quick/qml/PdfStyle.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+import QtQml 2.14
+import QtQuick 2.14
+import QtQuick.Controls 2.14
+import QtQuick.Shapes 1.14
+
+QtObject {
+ property Control prototypeControl: Control { }
+ function withAlpha(color, alpha) {
+ return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
+ }
+ property color selectionColor: withAlpha(prototypeControl.palette.highlight, 0.5)
+ property color pageSearchResultsColor: "#80B0C4DE"
+ property color currentSearchResultStrokeColor: "cyan"
+ property real currentSearchResultStrokeWidth: 2
+ property color linkUnderscoreColor: prototypeControl.palette.link
+ property real linkUnderscoreStrokeWidth: 1
+ property var linkUnderscoreStrokeStyle: ShapePath.DashLine
+ property var linkUnderscoreDashPattern: [ 1, 4 ]
+}
diff --git a/src/pdf/quick/qquickpdfselection.cpp b/src/pdf/quick/qquickpdfselection.cpp
index d313820ba..5371e85e5 100644
--- a/src/pdf/quick/qquickpdfselection.cpp
+++ b/src/pdf/quick/qquickpdfselection.cpp
@@ -124,6 +124,22 @@ QVector<QPolygonF> QQuickPdfSelection::geometry() const
return m_geometry;
}
+void QQuickPdfSelection::selectAll()
+{
+ QPdfSelection sel = m_document->m_doc.getAllText(m_page);
+ 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();
+ }
+}
+
void QQuickPdfSelection::resetPoints()
{
bool wasHolding = m_hold;
diff --git a/src/pdf/quick/qquickpdfselection_p.h b/src/pdf/quick/qquickpdfselection_p.h
index bba2a4861..d231c0d11 100644
--- a/src/pdf/quick/qquickpdfselection_p.h
+++ b/src/pdf/quick/qquickpdfselection_p.h
@@ -86,6 +86,7 @@ public:
QString text() const;
QVector<QPolygonF> geometry() const;
+ Q_INVOKABLE void selectAll();
#if QT_CONFIG(clipboard)
Q_INVOKABLE void copyToClipboard() const;
#endif
diff --git a/src/pdf/quick/resources.qrc b/src/pdf/quick/resources.qrc
index 20cac4827..8270a2028 100644
--- a/src/pdf/quick/resources.qrc
+++ b/src/pdf/quick/resources.qrc
@@ -1,5 +1,8 @@
<RCC>
<qresource prefix="/qt-project.org/qtpdf">
+ <file>qml/+material/PdfStyle.qml</file>
+ <file>qml/+universal/PdfStyle.qml</file>
+ <file>qml/PdfStyle.qml</file>
<file>qml/PdfMultiPageView.qml</file>
<file>qml/PdfPageView.qml</file>
<file>qml/PdfScrollablePageView.qml</file>