summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2023-03-14 11:52:11 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2023-03-17 12:35:47 +0100
commit496c4ec76963acdfb09cd5b444e3c3840eb21489 (patch)
tree3be164f1267dbb1103614ae99deba9d749d066af /examples
parent288e9be6ba2be40761333036f3397298df5e1018 (diff)
downloadqtwebengine-496c4ec76963acdfb09cd5b444e3c3840eb21489.tar.gz
Add search feature to PDF widget example
Task-number: QTBUG-16211 Task-number: QTBUG-77507 Fixes: QTBUG-92973 Change-Id: I650bed9392e5e098e46368c60fb7c5dbebde666f Reviewed-by: <irfan.omair@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/pdfwidgets/pdfviewer/CMakeLists.txt3
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-down-search.svgzbin0 -> 330 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-up-search.svgzbin0 -> 241 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.cpp51
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.h7
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.ui72
-rw-r--r--examples/pdfwidgets/pdfviewer/pdfviewer.pro2
-rw-r--r--examples/pdfwidgets/pdfviewer/resources.qrc2
-rw-r--r--examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp46
-rw-r--r--examples/pdfwidgets/pdfviewer/searchresultdelegate.h20
10 files changed, 203 insertions, 0 deletions
diff --git a/examples/pdfwidgets/pdfviewer/CMakeLists.txt b/examples/pdfwidgets/pdfviewer/CMakeLists.txt
index 901509f62..59cf13310 100644
--- a/examples/pdfwidgets/pdfviewer/CMakeLists.txt
+++ b/examples/pdfwidgets/pdfviewer/CMakeLists.txt
@@ -18,6 +18,7 @@ find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets PdfWidgets)
qt_add_executable(pdfviewerwidgets
main.cpp
mainwindow.cpp mainwindow.h mainwindow.ui
+ searchresultdelegate.cpp searchresultdelegate.h
zoomselector.cpp zoomselector.h
)
@@ -46,6 +47,8 @@ set(resources_resource_files
"images/zoom-previous.svgz"
"images/document-open.svgz"
"images/go-next-view.svgz"
+ "images/go-down-search.svgz"
+ "images/go-up-search.svgz"
)
qt_add_resources(pdfviewerwidgets "resources"
diff --git a/examples/pdfwidgets/pdfviewer/images/go-down-search.svgz b/examples/pdfwidgets/pdfviewer/images/go-down-search.svgz
new file mode 100644
index 000000000..f845473e7
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-down-search.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-up-search.svgz b/examples/pdfwidgets/pdfviewer/images/go-up-search.svgz
new file mode 100644
index 000000000..6378721fa
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-up-search.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp
index f5dae88e1..277f9cfb3 100644
--- a/examples/pdfwidgets/pdfviewer/mainwindow.cpp
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.cpp
@@ -4,14 +4,18 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
+#include "searchresultdelegate.h"
#include "zoomselector.h"
#include <QFileDialog>
+#include <QLineEdit>
#include <QMessageBox>
#include <QPdfBookmarkModel>
#include <QPdfDocument>
#include <QPdfPageNavigator>
#include <QPdfPageSelector>
+#include <QPdfSearchModel>
+#include <QShortcut>
#include <QStandardPaths>
#include <QtMath>
@@ -24,6 +28,8 @@ MainWindow::MainWindow(QWidget *parent)
, ui(new Ui::MainWindow)
, m_zoomSelector(new ZoomSelector(this))
, m_pageSelector(new QPdfPageSelector(this))
+ , m_searchModel(new QPdfSearchModel(this))
+ , m_searchField(new QLineEdit(this))
, m_document(new QPdfDocument(this))
{
ui->setupUi(this);
@@ -51,6 +57,23 @@ MainWindow::MainWindow(QWidget *parent)
ui->thumbnailsView->setModel(m_document->pageModel());
+ m_searchModel->setDocument(m_document);
+ ui->pdfView->setSearchModel(m_searchModel);
+ ui->searchToolBar->insertWidget(ui->actionFindPrevious, m_searchField);
+ connect(new QShortcut(QKeySequence::Find, this), &QShortcut::activated, this, [this]() {
+ m_searchField->setFocus(Qt::ShortcutFocusReason);
+ });
+ m_searchField->setPlaceholderText(tr("Find in document"));
+ m_searchField->setMaximumWidth(400);
+ connect(m_searchField, &QLineEdit::textEdited, this, [this](const QString &text) {
+ m_searchModel->setSearchString(text);
+ ui->tabWidget->setCurrentWidget(ui->searchResultsTab);
+ });
+ ui->searchResultsView->setModel(m_searchModel);
+ ui->searchResultsView->setItemDelegate(new SearchResultDelegate(this));
+ connect(ui->searchResultsView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &MainWindow::searchResultSelected);
+
ui->pdfView->setDocument(m_document);
connect(ui->pdfView, &QPdfView::zoomFactorChanged,
@@ -96,6 +119,18 @@ void MainWindow::pageSelected(int page)
m_pageSelector->text(), QString::number(page + 1), QString::number(m_document->pageCount())));
}
+void MainWindow::searchResultSelected(const QModelIndex &current, const QModelIndex &previous)
+{
+ Q_UNUSED(previous);
+ if (!current.isValid())
+ return;
+
+ const int page = current.data(int(QPdfSearchModel::Role::Page)).toInt();
+ const QPointF location = current.data(int(QPdfSearchModel::Role::Location)).toPointF();
+ ui->pdfView->pageNavigator()->jump(page, location);
+ ui->pdfView->setCurrentSearchResult(current.row());
+}
+
void MainWindow::on_actionOpen_triggered()
{
if (m_fileDialog == nullptr) {
@@ -172,3 +207,19 @@ void MainWindow::on_actionForward_triggered()
{
ui->pdfView->pageNavigator()->forward();
}
+
+void MainWindow::on_actionFindNext_triggered()
+{
+ int next = ui->searchResultsView->currentIndex().row() + 1;
+ if (next >= m_searchModel->rowCount({}))
+ next = 0;
+ ui->searchResultsView->setCurrentIndex(m_searchModel->index(next));
+}
+
+void MainWindow::on_actionFindPrevious_triggered()
+{
+ int prev = ui->searchResultsView->currentIndex().row() - 1;
+ if (prev < 0)
+ prev = m_searchModel->rowCount({}) - 1;
+ ui->searchResultsView->setCurrentIndex(m_searchModel->index(prev));
+}
diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.h b/examples/pdfwidgets/pdfviewer/mainwindow.h
index 84b779be1..7f5a5dbca 100644
--- a/examples/pdfwidgets/pdfviewer/mainwindow.h
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.h
@@ -15,8 +15,10 @@ class MainWindow;
}
class QFileDialog;
+class QLineEdit;
class QPdfDocument;
class QPdfPageSelector;
+class QPdfSearchModel;
class QPdfView;
class QSpinBox;
QT_END_NAMESPACE
@@ -37,6 +39,7 @@ public slots:
private slots:
void bookmarkSelected(const QModelIndex &index);
void pageSelected(int page);
+ void searchResultSelected(const QModelIndex &current, const QModelIndex &previous);
// action handlers
void on_actionOpen_triggered();
@@ -51,11 +54,15 @@ private slots:
void on_actionContinuous_triggered();
void on_actionBack_triggered();
void on_actionForward_triggered();
+ void on_actionFindNext_triggered();
+ void on_actionFindPrevious_triggered();
private:
Ui::MainWindow *ui;
ZoomSelector *m_zoomSelector;
QPdfPageSelector *m_pageSelector;
+ QPdfSearchModel *m_searchModel;
+ QLineEdit *m_searchField;
QFileDialog *m_fileDialog = nullptr;
QPdfDocument *m_document;
diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.ui b/examples/pdfwidgets/pdfviewer/mainwindow.ui
index 458c5a8c9..881df2e1b 100644
--- a/examples/pdfwidgets/pdfviewer/mainwindow.ui
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.ui
@@ -151,6 +151,35 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="searchResultsTab">
+ <attribute name="title">
+ <string>Search Results</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QListView" name="searchResultsView">
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
<widget class="QPdfView" name="pdfView" native="true">
<property name="sizePolicy">
@@ -227,6 +256,19 @@
<addaction name="actionForward"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
+ <widget class="QToolBar" name="searchToolBar">
+ <property name="windowTitle">
+ <string>toolBar</string>
+ </property>
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ <addaction name="actionFindPrevious"/>
+ <addaction name="actionFindNext"/>
+ </widget>
<action name="actionOpen">
<property name="icon">
<iconset theme="document-open" resource="resources.qrc">
@@ -349,6 +391,36 @@
<string>forward to next view</string>
</property>
</action>
+ <action name="actionFindNext">
+ <property name="icon">
+ <iconset theme="go-down" resource=".rcc/resources.qrc">
+ <normaloff>:/icons/images/go-down-search.svgz</normaloff>:/icons/images/go-down-search.svgz</iconset>
+ </property>
+ <property name="text">
+ <string>Find Next</string>
+ </property>
+ <property name="toolTip">
+ <string>Find the next occurrence of the phrase</string>
+ </property>
+ <property name="shortcut">
+ <string>F3</string>
+ </property>
+ </action>
+ <action name="actionFindPrevious">
+ <property name="icon">
+ <iconset theme="go-up" resource=".rcc/resources.qrc">
+ <normaloff>:/icons/images/go-up-search.svgz</normaloff>:/icons/images/go-up-search.svgz</iconset>
+ </property>
+ <property name="text">
+ <string>Find Previous</string>
+ </property>
+ <property name="toolTip">
+ <string>Find the previous occurrence of the phrase</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+F3</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
diff --git a/examples/pdfwidgets/pdfviewer/pdfviewer.pro b/examples/pdfwidgets/pdfviewer/pdfviewer.pro
index 08807fa70..5e48edeb9 100644
--- a/examples/pdfwidgets/pdfviewer/pdfviewer.pro
+++ b/examples/pdfwidgets/pdfviewer/pdfviewer.pro
@@ -5,10 +5,12 @@ QT += core gui widgets pdfwidgets
SOURCES += \
main.cpp \
mainwindow.cpp \
+ searchresultdelegate.cpp \
zoomselector.cpp
HEADERS += \
mainwindow.h \
+ searchresultdelegate.h \
zoomselector.h
FORMS += \
diff --git a/examples/pdfwidgets/pdfviewer/resources.qrc b/examples/pdfwidgets/pdfviewer/resources.qrc
index db77763d2..ea408b825 100644
--- a/examples/pdfwidgets/pdfviewer/resources.qrc
+++ b/examples/pdfwidgets/pdfviewer/resources.qrc
@@ -1,10 +1,12 @@
<RCC>
<qresource prefix="/icons">
<file>images/document-open.svgz</file>
+ <file>images/go-down-search.svgz</file>
<file>images/go-next-view.svgz</file>
<file>images/go-previous-view.svgz</file>
<file>images/go-next-view-page.svgz</file>
<file>images/go-previous-view-page.svgz</file>
+ <file>images/go-up-search.svgz</file>
<file>images/zoom-in.svgz</file>
<file>images/zoom-out.svgz</file>
</qresource>
diff --git a/examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp b/examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp
new file mode 100644
index 000000000..87efd916d
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp
@@ -0,0 +1,46 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QFontMetrics>
+#include <QPainter>
+#include <QPdfSearchModel>
+
+#include "searchresultdelegate.h"
+
+SearchResultDelegate::SearchResultDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+void SearchResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ const QString displayText = index.data().toString();
+ const auto boldBegin = displayText.indexOf(u"<b>", 0, Qt::CaseInsensitive) + 3;
+ const auto boldEnd = displayText.indexOf(u"</b>", boldBegin, Qt::CaseInsensitive);
+ if (boldBegin >= 3 && boldEnd > boldBegin) {
+ const QString pageLabel = tr("Page %1: ").arg(index.data(int(QPdfSearchModel::Role::Page)).toInt());
+ const QString boldText = displayText.mid(boldBegin, boldEnd - boldBegin);
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(option.rect, option.palette.highlight());
+ const QFont defaultFont = painter->font();
+ QFontMetrics fm = painter->fontMetrics();
+ auto pageLabelWidth = fm.horizontalAdvance(pageLabel);
+ const int yOffset = (option.rect.height() - fm.height()) / 2 + fm.ascent();
+ painter->drawText(0, option.rect.y() + yOffset, pageLabel);
+ QFont boldFont = defaultFont;
+ boldFont.setBold(true);
+ auto boldWidth = QFontMetrics(boldFont).horizontalAdvance(boldText);
+ auto prefixSuffixWidth = (option.rect.width() - pageLabelWidth - boldWidth) / 2;
+ painter->setFont(boldFont);
+ painter->drawText(pageLabelWidth + prefixSuffixWidth, option.rect.y() + yOffset, boldText);
+ painter->setFont(defaultFont);
+ const QString suffix = fm.elidedText(displayText.mid(boldEnd + 4), Qt::ElideRight, prefixSuffixWidth);
+ painter->drawText(pageLabelWidth + prefixSuffixWidth + boldWidth, option.rect.y() + yOffset, suffix);
+ const QString prefix = fm.elidedText(displayText.left(boldBegin - 3), Qt::ElideLeft, prefixSuffixWidth);
+ painter->drawText(pageLabelWidth + prefixSuffixWidth - fm.horizontalAdvance(prefix),
+ option.rect.y() + yOffset, prefix);
+ } else {
+ QStyledItemDelegate::paint(painter, option, index);
+ }
+}
diff --git a/examples/pdfwidgets/pdfviewer/searchresultdelegate.h b/examples/pdfwidgets/pdfviewer/searchresultdelegate.h
new file mode 100644
index 000000000..dcf886111
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/searchresultdelegate.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef SEARCHRESULTDELEGATE_H
+#define SEARCHRESULTDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+//! [0]
+class SearchResultDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ SearchResultDelegate(QObject *parent = nullptr);
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+};
+
+#endif // SEARCHRESULTDELEGATE_H