QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 <QRegularExpression>
16#include <QPlainTextEdit>
17#include <QTextEdit>
18
19#include "qgscodeeditor.h"
20#include "qgsexpressionfinder.h"
21
22
23static const QString EXPRESSION_PATTERN = QStringLiteral( "\\[%\\s*(.*?)\\s*%\\]" );
24
25
26void QgsExpressionFinder::findExpressionAtPos( const QString &text, int startSelectionPos, int endSelectionPos, int &start, int &end, QString &expression, const QString &pattern )
27{
28 start = startSelectionPos;
29 end = endSelectionPos;
30 // html editor replaces newlines with Paragraph Separator characters - see https://github.com/qgis/QGIS/issues/27568
31 expression = text.mid( startSelectionPos, endSelectionPos - startSelectionPos ).replace( QChar( 0x2029 ), QChar( '\n' ) );
32
33 // When the expression is selected including the opening and closing brackets,
34 // we still want it to be matched
35 if ( startSelectionPos != endSelectionPos )
36 {
37 startSelectionPos++;
38 endSelectionPos--;
39 }
40
41 const QRegularExpression regex( pattern.isEmpty() ? EXPRESSION_PATTERN : pattern );
42 QRegularExpressionMatchIterator result = regex.globalMatch( text );
43
44 while ( result.hasNext() )
45 {
46 const QRegularExpressionMatch match = result.next();
47
48 // Check if the selection or cursor is inside the opening and closing brackets
49 if ( match.capturedStart() < startSelectionPos && match.capturedEnd() > endSelectionPos )
50 {
51 start = match.capturedStart();
52 end = match.capturedEnd();
53 // Set the expression builder text to the trimmed expression
54 expression = match.captured( 1 );
55 // html editor replaces newlines with Paragraph Separator characters - see https://github.com/qgis/QGIS/issues/27568
56 expression = expression.replace( QChar( 0x2029 ), QChar( '\n' ) );
57
58 break;
59 }
60 }
61}
62
63QString QgsExpressionFinder::findAndSelectActiveExpression( QgsCodeEditor *editor, const QString &pattern )
64{
65 QString res;
66
67 int startPosition = editor->selectionStart();
68 int endPosition = editor->selectionEnd();
69
70 // Find the expression at the cursor position
71 int newSelectionStart, newSelectionEnd;
72 findExpressionAtPos( editor->text(), startPosition, endPosition, newSelectionStart, newSelectionEnd, res, pattern );
73
74 editor->setLinearSelection( newSelectionStart, newSelectionEnd );
75
76 return res;
77}
78
79QString QgsExpressionFinder::findAndSelectActiveExpression( QTextEdit *editor, const QString &pattern )
80{
81 QString res;
82
83 int startPosition = editor->textCursor().selectionStart();
84 int endPosition = editor->textCursor().selectionEnd();
85
86 // Find the expression at the cursor position
87 int newSelectionStart, newSelectionEnd;
88 findExpressionAtPos( editor->toPlainText(), startPosition, endPosition, newSelectionStart, newSelectionEnd, res, pattern );
89
90 QTextCursor cursor = editor->textCursor();
91 cursor.setPosition( newSelectionStart, QTextCursor::MoveAnchor );
92 cursor.setPosition( newSelectionEnd, QTextCursor::KeepAnchor );
93 editor->setTextCursor( cursor );
94
95 return res;
96}
97
98QString QgsExpressionFinder::findAndSelectActiveExpression( QPlainTextEdit *editor, const QString &pattern )
99{
100 QString res;
101
102 int startPosition = editor->textCursor().selectionStart();
103 int endPosition = editor->textCursor().selectionEnd();
104
105 // Find the expression at the cursor position
106 int newSelectionStart, newSelectionEnd;
107 findExpressionAtPos( editor->toPlainText(), startPosition, endPosition, newSelectionStart, newSelectionEnd, res, pattern );
108
109 QTextCursor cursor = editor->textCursor();
110 cursor.setPosition( newSelectionStart, QTextCursor::MoveAnchor );
111 cursor.setPosition( newSelectionEnd, QTextCursor::KeepAnchor );
112 editor->setTextCursor( cursor );
113
114 return res;
115}
A text editor based on QScintilla2.
Definition: qgscodeeditor.h:93
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.