QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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 <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.
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.