summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-03-10 12:57:32 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2020-03-11 08:31:44 +0100
commit5dc78ed4e2891205a7162b696b3439a87253140f (patch)
tree09778a7d19015f627be5efa813bf4730a82c1ed1
parentf253884934cbdbc16fd9b783a2b115960d11af10 (diff)
PdfSelection: add selectAll() function; use in examples
The usual shortcut (control-A) now selects all text on the current page, it is highlighted, and it can be copied to the clipboard. Change-Id: I5e6d9cae675862808f8b9027cb47024ca65cf2fd Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--examples/pdf/multipage/resources/edit-select-all.svg13
-rw-r--r--examples/pdf/multipage/viewer.qml7
-rw-r--r--examples/pdf/multipage/viewer.qrc1
-rw-r--r--examples/pdf/pdfviewer/resources/edit-select-all.svg13
-rw-r--r--examples/pdf/pdfviewer/viewer.qml7
-rw-r--r--examples/pdf/pdfviewer/viewer.qrc1
-rw-r--r--src/pdf/api/qpdfdocument.h1
-rw-r--r--src/pdf/api/qpdfdocument_p.h1
-rw-r--r--src/pdf/qpdfdocument.cpp43
-rw-r--r--src/pdf/quick/qml/PdfMultiPageView.qml5
-rw-r--r--src/pdf/quick/qml/PdfPageView.qml3
-rw-r--r--src/pdf/quick/qml/PdfScrollablePageView.qml3
-rw-r--r--src/pdf/quick/qquickpdfselection.cpp16
-rw-r--r--src/pdf/quick/qquickpdfselection_p.h1
14 files changed, 109 insertions, 6 deletions
diff --git a/examples/pdf/multipage/resources/edit-select-all.svg b/examples/pdf/multipage/resources/edit-select-all.svg
new file mode 100644
index 000000000..5f21950a0
--- /dev/null
+++ b/examples/pdf/multipage/resources/edit-select-all.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4 4 L 4 5 L 4 8 L 5 8 L 5 5 L 8 5 L 8 4 L 5 4 L 4 4 z M 16 4 L 16 5 L 19 5 L 19 8 L 20 8 L 20 4 L 16 4 z M 6 6 L 6 11 L 11 11 L 11 6 L 6 6 z M 13 6 L 13 11 L 18 11 L 18 6 L 13 6 z M 7 7 L 10 7 L 10 10 L 7 10 L 7 7 z M 14 7 L 17 7 L 17 10 L 14 10 L 14 7 z M 6 13 L 6 18 L 11 18 L 11 13 L 6 13 z M 13 13 L 13 18 L 18 18 L 18 13 L 13 13 z M 7 14 L 10 14 L 10 17 L 7 17 L 7 14 z M 14 14 L 17 14 L 17 17 L 14 17 L 14 14 z M 4 16 L 4 20 L 5 20 L 8 20 L 8 19 L 5 19 L 5 16 L 4 16 z M 19 16 L 19 19 L 16 19 L 16 20 L 20 20 L 20 19 L 20 16 L 19 16 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/examples/pdf/multipage/viewer.qml b/examples/pdf/multipage/viewer.qml
index 282636564..02513fa5b 100644
--- a/examples/pdf/multipage/viewer.qml
+++ b/examples/pdf/multipage/viewer.qml
@@ -161,6 +161,13 @@ ApplicationWindow {
}
ToolButton {
action: Action {
+ shortcut: StandardKey.SelectAll
+ icon.source: "resources/edit-select-all.svg"
+ onTriggered: view.selectAll()
+ }
+ }
+ ToolButton {
+ action: Action {
shortcut: StandardKey.Copy
icon.source: "resources/edit-copy.svg"
enabled: view.selectedText !== ""
diff --git a/examples/pdf/multipage/viewer.qrc b/examples/pdf/multipage/viewer.qrc
index 1b6fa52f7..ffca51679 100644
--- a/examples/pdf/multipage/viewer.qrc
+++ b/examples/pdf/multipage/viewer.qrc
@@ -4,6 +4,7 @@
<file>resources/document-open.svg</file>
<file>resources/edit-clear.svg</file>
<file>resources/edit-copy.svg</file>
+ <file>resources/edit-select-all.svg</file>
<file>resources/go-down-search.svg</file>
<file>resources/go-next-view-page.svg</file>
<file>resources/go-previous-view-page.svg</file>
diff --git a/examples/pdf/pdfviewer/resources/edit-select-all.svg b/examples/pdf/pdfviewer/resources/edit-select-all.svg
new file mode 100644
index 000000000..5f21950a0
--- /dev/null
+++ b/examples/pdf/pdfviewer/resources/edit-select-all.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4 4 L 4 5 L 4 8 L 5 8 L 5 5 L 8 5 L 8 4 L 5 4 L 4 4 z M 16 4 L 16 5 L 19 5 L 19 8 L 20 8 L 20 4 L 16 4 z M 6 6 L 6 11 L 11 11 L 11 6 L 6 6 z M 13 6 L 13 11 L 18 11 L 18 6 L 13 6 z M 7 7 L 10 7 L 10 10 L 7 10 L 7 7 z M 14 7 L 17 7 L 17 10 L 14 10 L 14 7 z M 6 13 L 6 18 L 11 18 L 11 13 L 6 13 z M 13 13 L 13 18 L 18 18 L 18 13 L 13 13 z M 7 14 L 10 14 L 10 17 L 7 17 L 7 14 z M 14 14 L 17 14 L 17 17 L 14 17 L 14 14 z M 4 16 L 4 20 L 5 20 L 8 20 L 8 19 L 5 19 L 5 16 L 4 16 z M 19 16 L 19 19 L 16 19 L 16 20 L 20 20 L 20 19 L 20 16 L 19 16 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/examples/pdf/pdfviewer/viewer.qml b/examples/pdf/pdfviewer/viewer.qml
index 40469afcf..75d2daab0 100644
--- a/examples/pdf/pdfviewer/viewer.qml
+++ b/examples/pdf/pdfviewer/viewer.qml
@@ -164,6 +164,13 @@ ApplicationWindow {
}
ToolButton {
action: Action {
+ shortcut: StandardKey.SelectAll
+ icon.source: "resources/edit-select-all.svg"
+ onTriggered: view.selectAll()
+ }
+ }
+ ToolButton {
+ action: Action {
shortcut: StandardKey.Copy
icon.source: "resources/edit-copy.svg"
enabled: view.selectedText !== ""
diff --git a/examples/pdf/pdfviewer/viewer.qrc b/examples/pdf/pdfviewer/viewer.qrc
index 1b6fa52f7..ffca51679 100644
--- a/examples/pdf/pdfviewer/viewer.qrc
+++ b/examples/pdf/pdfviewer/viewer.qrc
@@ -4,6 +4,7 @@
<file>resources/document-open.svg</file>
<file>resources/edit-clear.svg</file>
<file>resources/edit-copy.svg</file>
+ <file>resources/edit-select-all.svg</file>
<file>resources/go-down-search.svg</file>
<file>resources/go-next-view-page.svg</file>
<file>resources/go-previous-view-page.svg</file>
diff --git a/src/pdf/api/qpdfdocument.h b/src/pdf/api/qpdfdocument.h
index 40df181f4..027cdeb47 100644
--- a/src/pdf/api/qpdfdocument.h
+++ b/src/pdf/api/qpdfdocument.h
@@ -113,6 +113,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..2dcb70407 100644
--- a/src/pdf/api/qpdfdocument_p.h
+++ b/src/pdf/api/qpdfdocument_p.h
@@ -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/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index 1e8a0f527..d56edf4e9 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -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/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml
index 579c9a1ce..70bb5454f 100644
--- a/src/pdf/quick/qml/PdfMultiPageView.qml
+++ b/src/pdf/quick/qml/PdfMultiPageView.qml
@@ -47,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)
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 4c43972c9..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()
}
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 a0e6d1a8d..bb4a50fed 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