QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsexpressionfinder.cpp
Go to the documentation of this file.
1/*********************************************************************************
2 qgsexpressionfinder.cpp - A helper class to locate expression in text editors
3 --------------------------------------
4 begin : September 2023
5 copyright : (C) 2023 by Yoann Quenach de Quivillic
6 email : yoann dot quenach at gmail dot com
7 *********************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 *********************************************************************************/
15#include "qgsexpressionfinder.h"
16
17#include "qgscodeeditor.h"
18
19#include <QPlainTextEdit>
20#include <QRegularExpression>
21#include <QString>
22#include <QTextEdit>
23
24using namespace Qt::StringLiterals;
25
26static const QString EXPRESSION_PATTERN = u"\\[%\\s*(.*?)\\s*%\\]"_s;
27
28
29void QgsExpressionFinder::findExpressionAtPos( const QString &text, int startSelectionPos, int endSelectionPos, int &start, int &end, QString &expression, const QString &pattern )
30{
31 start = startSelectionPos;
32 end = endSelectionPos;
33 // html editor replaces newlines with Paragraph Separator characters - see https://github.com/qgis/QGIS/issues/27568
34 expression = text.mid( startSelectionPos, endSelectionPos - startSelectionPos ).replace( QChar( 0x2029 ), QChar( '\n' ) );
35
36 // When the expression is selected including the opening and closing brackets,
37 // we still want it to be matched
38 if ( startSelectionPos != endSelectionPos )
39 {
40 startSelectionPos++;
41 endSelectionPos--;
42 }
43
44 const QRegularExpression regex( pattern.isEmpty() ? EXPRESSION_PATTERN : pattern );
45 QRegularExpressionMatchIterator result = regex.globalMatch( text );
46
47 while ( result.hasNext() )
48 {
49 const QRegularExpressionMatch match = result.next();
50
51 // Check if the selection or cursor is inside the opening and closing brackets
52 if ( match.capturedStart() < startSelectionPos && match.capturedEnd() > endSelectionPos )
53 {
54 start = match.capturedStart();
55 end = match.capturedEnd();
56 // Set the expression builder text to the trimmed expression
57 expression = match.captured( 1 );
58 // html editor replaces newlines with Paragraph Separator characters - see https://github.com/qgis/QGIS/issues/27568
59 expression = expression.replace( QChar( 0x2029 ), QChar( '\n' ) );
60
61 break;
62 }
63 }
64}
65
66QString QgsExpressionFinder::findAndSelectActiveExpression( QgsCodeEditor *editor, const QString &pattern )
67{
68 QString res;
69
70 int startPosition = editor->selectionStart();
71 int endPosition = editor->selectionEnd();
72
73 // Find the expression at the cursor position
74 int newSelectionStart, newSelectionEnd;
75 findExpressionAtPos( editor->text(), startPosition, endPosition, newSelectionStart, newSelectionEnd, res, pattern );
76
77 editor->setLinearSelection( newSelectionStart, newSelectionEnd );
78
79 return res;
80}
81
82QString QgsExpressionFinder::findAndSelectActiveExpression( QTextEdit *editor, const QString &pattern )
83{
84 QString res;
85
86 int startPosition = editor->textCursor().selectionStart();
87 int endPosition = editor->textCursor().selectionEnd();
88
89 // Find the expression at the cursor position
90 int newSelectionStart, newSelectionEnd;
91 findExpressionAtPos( editor->toPlainText(), startPosition, endPosition, newSelectionStart, newSelectionEnd, res, pattern );
92
93 QTextCursor cursor = editor->textCursor();
94 cursor.setPosition( newSelectionStart, QTextCursor::MoveAnchor );
95 cursor.setPosition( newSelectionEnd, QTextCursor::KeepAnchor );
96 editor->setTextCursor( cursor );
97
98 return res;
99}
100
101QString QgsExpressionFinder::findAndSelectActiveExpression( QPlainTextEdit *editor, const QString &pattern )
102{
103 QString res;
104
105 int startPosition = editor->textCursor().selectionStart();
106 int endPosition = editor->textCursor().selectionEnd();
107
108 // Find the expression at the cursor position
109 int newSelectionStart, newSelectionEnd;
110 findExpressionAtPos( editor->toPlainText(), startPosition, endPosition, newSelectionStart, newSelectionEnd, res, pattern );
111
112 QTextCursor cursor = editor->textCursor();
113 cursor.setPosition( newSelectionStart, QTextCursor::MoveAnchor );
114 cursor.setPosition( newSelectionEnd, QTextCursor::KeepAnchor );
115 editor->setTextCursor( cursor );
116
117 return res;
118}
A text editor based on QScintilla2.
void setLinearSelection(int start, int end)
Convenience function to set the selection using linear indexes.
int selectionEnd() const
Convenience function to return the end of the selection as a linear index Contrary to the getSelectio...
int selectionStart() const
Convenience function to return the start of the selection as a linear index Contrary to the getSelect...
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
static void findExpressionAtPos(const QString &text, int startSelectionPos, int endSelectionPos, int &start, int &end, QString &expression, const QString &pattern=QString())
Find an expression at the given position in the given text.