QGIS API Documentation  3.27.0-Master (597e8eebd4)
qgscodeeditorexpression.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscodeeditorexpressoin.cpp - An expression editor based on QScintilla
3  --------------------------------------
4  Date : 8.9.2018
5  Copyright : (C) 2018 by Matthias Kuhn
6  Email : [email protected]
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 
16 #include "qgsapplication.h"
18 #include "qgssymbollayerutils.h"
19 
20 #include <QString>
21 #include <QFont>
22 
24  : QgsCodeEditor( parent )
25 {
26  if ( !parent )
27  {
28  setTitle( tr( "Expression Editor" ) );
29  }
30  setFoldingVisible( false );
31  setAutoCompletionCaseSensitivity( false );
32  QgsCodeEditorExpression::initializeLexer(); // avoid cppcheck warning by explicitly specifying namespace
33 }
34 
36 {
37  mVariables.clear();
38 
39  const QStringList variableNames = context.filteredVariableNames();
40  for ( const QString &var : variableNames )
41  {
42  mVariables << '@' + var;
43  }
44 
45  mContextFunctions = context.functionNames();
46 
47  mFunctions.clear();
48 
49  const int count = QgsExpression::functionCount();
50  for ( int i = 0; i < count; i++ )
51  {
53  if ( func->isDeprecated() ) // don't show deprecated functions
54  continue;
55  if ( func->isContextual() )
56  {
57  //don't show contextual functions by default - it's up the the QgsExpressionContext
58  //object to provide them if supported
59  continue;
60  }
61 
62  QString signature = func->name();
63  if ( !signature.startsWith( '$' ) )
64  {
65  signature += '(';
66 
67  QStringList paramNames;
68  const QgsExpressionFunction::ParameterList parameters = func->parameters();
69  for ( const QgsExpressionFunction::Parameter &param : parameters )
70  {
71  paramNames << param.name();
72  }
73 
74  // No named parameters but there should be parameteres? Show an ellipsis at least
75  if ( parameters.isEmpty() && func->params() )
76  signature += QChar( 0x2026 );
77 
78  signature += paramNames.join( ", " );
79 
80  signature += ')';
81  }
82  mFunctions << signature;
83  }
84 
85  updateApis();
86 }
87 
89 {
90  mFieldNames.clear();
91 
92  for ( const QgsField &field : fields )
93  {
94  mFieldNames << field.name();
95  }
96 
97  updateApis();
98 }
99 
101 {
102  QFont font = lexerFont();
104 
105  mSqlLexer = new QgsLexerExpression( this );
106  mSqlLexer->setDefaultFont( font );
107  mSqlLexer->setDefaultColor( defaultColor );
108  mSqlLexer->setDefaultPaper( lexerColor( QgsCodeEditorColorScheme::ColorRole::Background ) );
109  mSqlLexer->setFont( font, -1 );
110  font.setBold( true );
111  mSqlLexer->setFont( font, QsciLexerSQL::Keyword );
112 
113  font.setBold( false );
114  font.setItalic( true );
115  mSqlLexer->setFont( font, QsciLexerSQL::Comment );
116  mSqlLexer->setFont( font, QsciLexerSQL::CommentLine );
117 
118  mSqlLexer->setColor( Qt::darkYellow, QsciLexerSQL::DoubleQuotedString ); // fields
119 
120  mSqlLexer->setColor( defaultColor, QsciLexerSQL::Default );
121  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Comment ), QsciLexerSQL::Comment );
122  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::CommentLine ), QsciLexerSQL::CommentLine );
123  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Number ), QsciLexerSQL::Number );
124  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Keyword ), QsciLexerSQL::Keyword );
125  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::SingleQuote ), QsciLexerSQL::SingleQuotedString );
126  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::DoubleQuote ), QsciLexerSQL::DoubleQuotedString );
127  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Operator ), QsciLexerSQL::Operator );
128  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::Identifier ), QsciLexerSQL::Identifier );
129  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::QuotedIdentifier ), QsciLexerSQL::QuotedIdentifier );
130  mSqlLexer->setColor( lexerColor( QgsCodeEditorColorScheme::ColorRole::QuotedOperator ), QsciLexerSQL::QuotedOperator );
131 
132  setLexer( mSqlLexer );
134 }
135 
136 void QgsCodeEditorExpression::updateApis()
137 {
138  mApis = new QgsSciApisExpression( mSqlLexer );
139 
140  for ( const QString &var : std::as_const( mVariables ) )
141  {
142  mApis->add( var );
143  }
144 
145  for ( const QString &function : std::as_const( mContextFunctions ) )
146  {
147  mApis->add( function );
148  }
149 
150  for ( const QString &function : std::as_const( mFunctions ) )
151  {
152  mApis->add( function );
153  }
154 
155  for ( const QString &fieldName : std::as_const( mFieldNames ) )
156  {
157  mApis->add( fieldName );
158  }
159 
160  mApis->add( QString( "NULL" ) );
161  mApis->prepare();
162  mSqlLexer->setAPIs( mApis );
163 }
164 
166 QgsLexerExpression::QgsLexerExpression( QObject *parent )
167  : QsciLexerSQL( parent )
168 {
169  setBackslashEscapes( true );
170 }
171 
172 const char *QgsLexerExpression::language() const
173 {
174  return "QGIS Expression";
175 }
176 
177 bool QgsLexerExpression::caseSensitive() const
178 {
179  return false;
180 }
181 
182 const char *QgsLexerExpression::wordCharacters() const
183 {
184  return "[email protected]";
185 }
186 
187 QgsSciApisExpression::QgsSciApisExpression( QsciLexer *lexer )
188  : QsciAPIs( lexer )
189 {
190 
191 }
192 
193 QStringList QgsSciApisExpression::callTips( const QStringList &context, int commas, QsciScintilla::CallTipsStyle style, QList<int> &shifts )
194 {
195  const QStringList originalTips = QsciAPIs::callTips( context, commas, style, shifts );
196  QStringList lowercaseTips;
197  for ( const QString &tip : originalTips )
198  lowercaseTips << tip.toLower();
199 
200  return lowercaseTips;
201 }
@ QuotedOperator
Quoted operator color.
@ DoubleQuote
Double quote color.
@ QuotedIdentifier
Quoted identifier color.
@ CommentLine
Line comment color.
@ SingleQuote
Single quote color.
void initializeLexer() override
Called when the dialect specific code lexer needs to be initialized (or reinitialized).
QgsCodeEditorExpression(QWidget *parent=nullptr)
Constructor for QgsCodeEditorExpression.
void setExpressionContext(const QgsExpressionContext &context)
Variables and functions from this expression context will be added to the API.
void setFields(const QgsFields &fields)
Field names will be added to the API.
A text editor based on QScintilla2.
Definition: qgscodeeditor.h:42
void setFoldingVisible(bool folding)
Set whether the folding controls are visible in the editor.
void runPostLexerConfigurationTasks()
Performs tasks which must be run after a lexer has been set for the widget.
void setTitle(const QString &title)
Set the widget title.
QFont lexerFont() const
Returns the font to use in the lexer.
QColor lexerColor(QgsCodeEditorColorScheme::ColorRole role) const
Returns the color to use in the lexer for the specified role.
static QColor defaultColor(QgsCodeEditorColorScheme::ColorRole role, const QString &theme=QString())
Returns the default color for the specified role.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QStringList functionNames() const
Retrieves a list of function names contained in the context.
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
Represents a single parameter passed to a function.
A abstract base class for defining QgsExpression functions.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object.
int params() const
The number of parameters this function takes.
virtual bool isDeprecated() const
Returns true if the function is deprecated and should not be presented as a valid option to users in ...
QString name() const
The name of the function.
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
static const QList< QgsExpressionFunction * > & Functions()
static int functionCount()
Returns the number of functions defined in the parser.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
QString name
Definition: qgsfield.h:60
Container of fields for a vector layer.
Definition: qgsfields.h:45
const QgsField & field
Definition: qgsfield.h:463