Skip to content

Commit

Permalink
feat: improve search in document (KDAB#25)
Browse files Browse the repository at this point in the history
Fixes tasks:
QtUiDocument
QtTsDocument
  • Loading branch information
mgiroday committed Sep 2, 2024
1 parent 4a4a73a commit 3315cbf
Show file tree
Hide file tree
Showing 16 changed files with 522 additions and 27 deletions.
16 changes: 16 additions & 0 deletions docs/API/knut/qttsdocument.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import Knut
| | Name |
|-|-|
||**[addMessage](#addMessage)**(string context, string location, string source, string translation)|
|void |**[find](#find)**(string text, int options)|
|void |**[replace](#replace)**(string before, string after, bool onlyOne)|
||**[setLanguage](#setLanguage)**(string lang)|
||**[setMessageContext](#setMessageContext)**(string context, string comment, string source, string newContext)|
||**[setSourceLanguage](#setSourceLanguage)**(string lang)|
Expand All @@ -43,6 +45,20 @@ Returns the source language name.

Adds a new `source` text, its `translation` located in `location` within the given `context`.

#### <a name="find"></a>void **find**(string text, int options)

Searches the string `text` in the QtTsView table view.
Options:
- `QtTsDocumemt.FindBackward`: search backward
- `QtTsDocument.FindForward`: search forward
Trigger its parent 'QtTsView' search function connected to the emitted search signal.

#### <a name="replace"></a>void **replace**(string before, string after, bool onlyOne)

Search and replace the string `before` by the string `after`in the QtTsView table view.
Replace only the current match if `onlyOne` is true, otherwise replace all the matches.
Trigger its parent 'QtTsView' replace function connected to the emitted findAndReplace signal.

#### <a name="setLanguage"></a>**setLanguage**(string lang)

Changes the language.
Expand Down
16 changes: 16 additions & 0 deletions docs/API/knut/qtuidocument.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import Knut
|-|-|
|[QtUiWidget](../knut/qtuiwidget.md) |**[addCustomWidget](#addCustomWidget)**(string className, string baseClassName, string header, bool isContainer)|
|[QtUiWidget](../knut/qtuiwidget.md) |**[addWidget](#addWidget)**(string className, string name, [QtUiWidget](../knut/qtuiwidget.md) parent)|
|void |**[find](#find)**(string text, int options)|
|[QtUiWidget](../knut/qtuiwidget.md) |**[findWidget](#findWidget)**(string name)|
||**[preview](#preview)**()|
|void |**[replace](#replace)**(string before, string after, bool onlyOne)|

## Property Documentation

Expand All @@ -44,10 +46,24 @@ Creates a new widget with the given `className` and `name`, and adds it to the `

If `parent` is null, it creates the top level widget (there can only be one).

#### <a name="find"></a>void **find**(string text, int options)

Searches the string `text` in the QtUiView table view.
Options:
- `QtUiDocumemt.FindBackward`: search backward
- `QtUiDocument.FindForward`: search forward
Trigger its parent 'QtUiView' search function connected to the emitted search signal.

#### <a name="findWidget"></a>[QtUiWidget](../knut/qtuiwidget.md) **findWidget**(string name)

Returns the widget for the given `name`.

#### <a name="preview"></a>**preview**()

Opens a dialog to preview the current ui file.

#### <a name="replace"></a>void **replace**(string before, string after, bool onlyOne)

Search and replace the string `before` by the string `after`in the QtUiView table view.
Replace only the current match if `onlyOne` is true, otherwise replace all the matches.
Trigger its parent 'QtUiView' replace function connected to the emitted findAndReplace signal.
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ set(PROJECT_SOURCES
file.cpp
fileinfo.h
fileinfo.cpp
highlightsearchdelegate.h
highlightsearchdelegate.cpp
imagedocument.h
imagedocument.cpp
jsondocument.h
Expand Down
57 changes: 57 additions & 0 deletions src/core/highlightsearchdelegate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
This file is part of Knut.
SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
SPDX-License-Identifier: GPL-3.0-only
Contact KDAB at <[email protected]> for commercial licensing options.
*/

#include "highlightsearchdelegate.h"
#include <QPainter>

namespace Core {

HighlightSearchDelegate::HighlightSearchDelegate(QObject *parent)
: QItemDelegate(parent)
{
}

void HighlightSearchDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
const QString text = index.data().toString();
if (m_searchText.isEmpty() || !text.contains(m_searchText, Qt::CaseInsensitive)) {
QItemDelegate::paint(painter, option, index);
return;
}

// Find the substring to highlight
const QRegularExpression regex(m_searchText, QRegularExpression::CaseInsensitiveOption);
int start = regex.match(text).capturedStart();
int end = start + regex.match(text).capturedLength();

// Calculate the drawing positions
int x = option.rect.left();
int y = option.rect.top();
int height = option.rect.height();
int width = painter->fontMetrics().horizontalAdvance(text.left(start));

// Highlight
painter->save();
const QPen painterPen = painter->pen();
painter->setPen(painterPen);
painter->drawText(x, y, width, height, Qt::AlignLeft | Qt::AlignVCenter, text.left(start));
painter->setPen(Qt::blue);
x += width;
width = painter->fontMetrics().horizontalAdvance(text.mid(start, end - start));
painter->drawText(x, y, width, height, Qt::AlignLeft | Qt::AlignVCenter, text.mid(start, end - start));
painter->setPen(painterPen);
x += width;
width = painter->fontMetrics().horizontalAdvance(text.right(text.length() - end));
painter->drawText(x, y, width, height, Qt::AlignLeft | Qt::AlignVCenter, text.right(text.length() - end));
painter->restore();
}

} // namespace Core
33 changes: 33 additions & 0 deletions src/core/highlightsearchdelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
This file is part of Knut.
SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
SPDX-License-Identifier: GPL-3.0-only
Contact KDAB at <[email protected]> for commercial licensing options.
*/

#pragma once

#include <QItemDelegate>

namespace Core {

class HighlightSearchDelegate : public QItemDelegate
{
Q_OBJECT

public:
explicit HighlightSearchDelegate(QObject *parent = nullptr);

inline void setSearchText(const QString &searchText) { m_searchText = searchText; }

protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;

private:
QString m_searchText;
};

} // namespace Core
30 changes: 30 additions & 0 deletions src/core/qttsdocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,36 @@ void QtTsDocument::setMessageContext(const QString &context, const QString &comm
}
}

/*!
* \qmlmethod void QtTsDocument::find(string text, int options)
* Searches the string `text` in the QtTsView table view.
* Options:
* - `QtTsDocumemt.FindBackward`: search backward
* - `QtTsDocument.FindForward`: search forward
* Trigger its parent 'QtTsView' search function connected to the emitted search signal.
*/
void QtTsDocument::find(const QString &text, int options)
{
LOG("QtTsDocument::find", LOG_ARG("text", text), options);
emit search(text, options);
}

/*!
* \qmlmethod void QtTsDocument::replace(string before, string after, bool onlyOne)
* Search and replace the string `before` by the string `after`in the QtTsView table view.
* Replace only the current match if `onlyOne` is true, otherwise replace all the matches.
* Trigger its parent 'QtTsView' replace function connected to the emitted findAndReplace signal.
*/
void QtTsDocument::replace(const QString &before, const QString &after, bool onlyOne)
{
if (onlyOne) {
LOG("QtTsDocument::replaceOne", LOG_ARG("text", before), after);
} else {
LOG("QtTsDocument::replaceAll", LOG_ARG("text", before), after);
}
emit findAndReplace(before, after, onlyOne);
}

pugi::xml_node QtTsDocument::findOrCreateContext(const QString &context)
{
pugi::xml_node contextNode = findContext(context);
Expand Down
16 changes: 16 additions & 0 deletions src/core/qttsdocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,16 @@ class QtTsDocument : public Document
Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
Q_PROPERTY(QString sourceLanguage READ sourceLanguage WRITE setSourceLanguage NOTIFY sourceLanguageChanged)
Q_PROPERTY(QList<Core::QtTsMessage *> messages READ messages NOTIFY messagesChanged)

public:
enum FindFlag {
NoFindFlags = 0x0,
FindBackward = 0X2,
FindForward = 0x4,
};
Q_DECLARE_FLAGS(FindFlags, FindFlag)
Q_ENUM(FindFlag)

explicit QtTsDocument(QObject *parent = nullptr);

Q_INVOKABLE void setSourceLanguage(const QString &lang);
Expand All @@ -75,6 +84,9 @@ class QtTsDocument : public Document
const QString &translation, const QString &comment = QString());
Q_INVOKABLE void setMessageContext(const QString &context, const QString &comment, const QString &source,
const QString &newContext);
Q_INVOKABLE void find(const QString &text, int options);
Q_INVOKABLE void replace(const QString &before, const QString &after, bool onlyOne);

QString language() const;
QString sourceLanguage() const;
QList<QtTsMessage *> messages() const;
Expand All @@ -87,6 +99,8 @@ class QtTsDocument : public Document
void languageChanged();
void sourceLanguageChanged();
void messagesChanged();
void search(const QString &text, int options);
void findAndReplace(const QString &before, const QString &after, bool onlyOne);

private:
friend QtTsMessage;
Expand All @@ -102,3 +116,5 @@ class QtTsDocument : public Document
};

} // namespace Core

Q_DECLARE_OPERATORS_FOR_FLAGS(Core::QtTsDocument::FindFlags)
30 changes: 30 additions & 0 deletions src/core/qtuidocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,36 @@ Core::QtUiWidget *QtUiDocument::addWidget(const QString &className, const QStrin
return newWidget;
}

/*!
* \qmlmethod void QtUiDocument::find(string text, int options)
* Searches the string `text` in the QtUiView table view.
* Options:
* - `QtUiDocumemt.FindBackward`: search backward
* - `QtUiDocument.FindForward`: search forward
* Trigger its parent 'QtUiView' search function connected to the emitted search signal.
*/
void QtUiDocument::find(const QString &text, int options)
{
LOG("QtUiDocument::find", LOG_ARG("text", text), options);
emit search(text, options);
}

/*!
* \qmlmethod void QtUiDocument::replace(string before, string after, bool onlyOne)
* Search and replace the string `before` by the string `after`in the QtUiView table view.
* Replace only the current match if `onlyOne` is true, otherwise replace all the matches.
* Trigger its parent 'QtUiView' replace function connected to the emitted findAndReplace signal.
*/
void QtUiDocument::replace(const QString &before, const QString &after, bool onlyOne)
{
if (onlyOne) {
LOG("QtUiDocument::replaceOne", LOG_ARG("text", before), after);
} else {
LOG("QtUiDocument::replaceAll", LOG_ARG("text", before), after);
}
emit findAndReplace(before, after, onlyOne);
}

// clang-format off
/*!
* \qmlmethod QtUiWidget QtUiDocument::addCustomWidget(string className, string baseClassName, string header, bool isContainer)
Expand Down
16 changes: 16 additions & 0 deletions src/core/qtuidocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ class QtUiDocument : public Document
Q_PROPERTY(QList<Core::QtUiWidget *> widgets READ widgets NOTIFY widgetsChanged)

public:
enum FindFlag {
NoFindFlags = 0x0,
FindBackward = 0X2,
FindForward = 0x4,
};
Q_DECLARE_FLAGS(FindFlags, FindFlag)
Q_ENUM(FindFlag)

explicit QtUiDocument(QObject *parent = nullptr);
~QtUiDocument() override;

Expand All @@ -76,11 +84,17 @@ class QtUiDocument : public Document
Q_INVOKABLE void addCustomWidget(const QString &className, const QString &baseClassName, const QString &header,
bool isContainer = false);

Q_INVOKABLE void find(const QString &text, int options);

Q_INVOKABLE void replace(const QString &before, const QString &after, bool onlyOne);

public slots:
void preview() const;

signals:
void widgetsChanged();
void search(const QString &text, int options);
void findAndReplace(const QString &before, const QString &after, bool onlyOne);

protected:
bool doSave(const QString &fileName) override;
Expand All @@ -96,3 +110,5 @@ public slots:
};

} // namespace Core

Q_DECLARE_OPERATORS_FOR_FLAGS(Core::QtUiDocument::FindFlags)
Loading

0 comments on commit 3315cbf

Please sign in to comment.