QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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  setMarginVisible( false );
31  setFoldingVisible( true );
32  setAutoCompletionCaseSensitivity( false );
33  initializeLexer();
34 }
35 
37 {
38  mVariables.clear();
39 
40  const QStringList variableNames = context.filteredVariableNames();
41  for ( const QString &var : variableNames )
42  {
43  mVariables << '@' + var;
44  }
45 
46  mContextFunctions = context.functionNames();
47 
48  mFunctions.clear();
49 
50  const int count = QgsExpression::functionCount();
51  for ( int i = 0; i < count; i++ )
52  {
54  if ( func->isDeprecated() ) // don't show deprecated functions
55  continue;
56  if ( func->isContextual() )
57  {
58  //don't show contextual functions by default - it's up the the QgsExpressionContext
59  //object to provide them if supported
60  continue;
61  }
62 
63  QString signature = func->name();
64  if ( !signature.startsWith( '$' ) )
65  {
66  signature += '(';
67 
68  QStringList paramNames;
69  const QgsExpressionFunction::ParameterList parameters = func->parameters();
70  for ( const QgsExpressionFunction::Parameter &param : parameters )
71  {
72  paramNames << param.name();
73  }
74 
75  // No named parameters but there should be parameteres? Show an ellipsis at least
76  if ( parameters.isEmpty() && func->params() )
77  signature += QChar( 0x2026 );
78 
79  signature += paramNames.join( ", " );
80 
81  signature += ')';
82  }
83  mFunctions << signature;
84  }
85 
86  updateApis();
87 }
88 
90 {
91  mFieldNames.clear();
92 
93  for ( const QgsField &field : fields )
94  {
95  mFieldNames << field.name();
96  }
97 
98  updateApis();
99 }
100 
101 
102 void QgsCodeEditorExpression::initializeLexer()
103 {
104  QHash< QString, QColor > colors;
105  if ( QgsApplication::instance()->themeName() != QStringLiteral( "default" ) )
106  {
107  QSettings ini( QgsApplication::instance()->uiThemes().value( QgsApplication::instance()->themeName() ) + "/qscintilla.ini", QSettings::IniFormat );
108  for ( const auto &key : ini.allKeys() )
109  {
110  colors.insert( key, QgsSymbolLayerUtils::decodeColor( ini.value( key ).toString() ) );
111  }
112  }
113 
114  QFont font = getMonospaceFont();
115  QColor defaultColor = colors.value( QStringLiteral( "sql/defaultFontColor" ), Qt::black );
116 
117  mSqlLexer = new QgsLexerExpression( this );
118  mSqlLexer->setDefaultFont( font );
119  mSqlLexer->setDefaultColor( defaultColor );
120  mSqlLexer->setDefaultPaper( colors.value( QStringLiteral( "sql/paperBackgroundColor" ), Qt::white ) );
121  mSqlLexer->setFont( font, -1 );
122  font.setBold( true );
123  mSqlLexer->setFont( font, QsciLexerSQL::Keyword );
124 
125  mSqlLexer->setColor( Qt::darkYellow, QsciLexerSQL::DoubleQuotedString ); // fields
126 
127  mSqlLexer->setColor( defaultColor, QsciLexerSQL::Default );
128  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/commentFontColor" ), QColor( 142, 144, 140 ) ), QsciLexerSQL::Comment );
129  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/commentLineFontColor" ), QColor( 142, 144, 140 ) ), QsciLexerSQL::CommentLine );
130  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/numberFontColor" ), QColor( 200, 40, 41 ) ), QsciLexerSQL::Number );
131  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/keywordFontColor" ), QColor( 137, 89, 168 ) ), QsciLexerSQL::Keyword );
132  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/singleQuoteFontColor" ), QColor( 113, 140, 0 ) ), QsciLexerSQL::SingleQuotedString );
133  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/doubleQuoteFontColor" ), QColor( 234, 183, 0 ) ), QsciLexerSQL::DoubleQuotedString );
134  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/operatorFontColor" ), QColor( 66, 113, 174 ) ), QsciLexerSQL::Operator );
135  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/identifierFontColor" ), QColor( 62, 153, 159 ) ), QsciLexerSQL::Identifier );
136  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/QuotedIdentifierFontColor" ), Qt::black ), QsciLexerSQL::QuotedIdentifier );
137  mSqlLexer->setColor( colors.value( QStringLiteral( "sql/QuotedOperatorFontColor" ), Qt::black ), QsciLexerSQL::QuotedOperator );
138 
139  setLexer( mSqlLexer );
140 }
141 
142 void QgsCodeEditorExpression::updateApis()
143 {
144  mApis = new QgsSciApisExpression( mSqlLexer );
145 
146  for ( const QString &var : qgis::as_const( mVariables ) )
147  {
148  mApis->add( var );
149  }
150 
151  for ( const QString &function : qgis::as_const( mContextFunctions ) )
152  {
153  mApis->add( function );
154  }
155 
156  for ( const QString &function : qgis::as_const( mFunctions ) )
157  {
158  mApis->add( function );
159  }
160 
161  for ( const QString &fieldName : qgis::as_const( mFieldNames ) )
162  {
163  mApis->add( fieldName );
164  }
165 
166  mApis->prepare();
167  mSqlLexer->setAPIs( mApis );
168 }
169 
171 QgsLexerExpression::QgsLexerExpression( QObject *parent )
172  : QsciLexerSQL( parent )
173 {
174 }
175 
176 const char *QgsLexerExpression::language() const
177 {
178  return "QGIS Expression";
179 }
180 
181 bool QgsLexerExpression::caseSensitive() const
182 {
183  return false;
184 }
185 
186 const char *QgsLexerExpression::wordCharacters() const
187 {
188  return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_@";
189 }
190 
191 QgsSciApisExpression::QgsSciApisExpression( QsciLexer *lexer )
192  : QsciAPIs( lexer )
193 {
194 
195 }
196 
197 QStringList QgsSciApisExpression::callTips( const QStringList &context, int commas, QsciScintilla::CallTipsStyle style, QList<int> &shifts )
198 {
199  const QStringList originalTips = QsciAPIs::callTips( context, commas, style, shifts );
200  QStringList lowercaseTips;
201  for ( const QString &tip : originalTips )
202  lowercaseTips << tip.toLower();
203 
204  return lowercaseTips;
205 }
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:369
qgssymbollayerutils.h
QgsFields
Definition: qgsfields.h:44
QgsCodeEditor::setMarginVisible
void setMarginVisible(bool margin)
Set margin visible state.
Definition: qgscodeeditor.cpp:146
QgsCodeEditor
Definition: qgscodeeditor.h:38
QgsCodeEditorExpression::setFields
void setFields(const QgsFields &fields)
Field names will be added to the API.
Definition: qgscodeeditorexpression.cpp:89
QgsApplication::instance
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
Definition: qgsapplication.cpp:390
QgsExpressionFunction::isContextual
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object.
Definition: qgsexpressionfunction.h:270
QgsSymbolLayerUtils::decodeColor
static QColor decodeColor(const QString &str)
Definition: qgssymbollayerutils.cpp:57
QgsCodeEditor::setTitle
void setTitle(const QString &title)
Set the widget title.
Definition: qgscodeeditor.cpp:141
qgsapplication.h
QgsExpressionFunction::params
int params() const
The number of parameters this function takes.
Definition: qgsexpressionfunction.h:193
QgsExpressionFunction::Parameter
Definition: qgsexpressionfunction.h:54
QgsExpressionFunction::ParameterList
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
Definition: qgsexpressionfunction.h:104
QgsCodeEditorExpression::QgsCodeEditorExpression
QgsCodeEditorExpression(QWidget *parent=nullptr)
Constructor for QgsCodeEditorExpression.
Definition: qgscodeeditorexpression.cpp:23
QgsCodeEditorExpression::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Variables and functions from this expression context will be added to the API.
Definition: qgscodeeditorexpression.cpp:36
QgsExpressionFunction::isDeprecated
virtual bool isDeprecated() const
Returns true if the function is deprecated and should not be presented as a valid option to users in ...
Definition: qgsexpressionfunction.cpp:139
QgsExpression::Functions
static const QList< QgsExpressionFunction * > & Functions()
Definition: qgsexpressionfunction.cpp:5649
qgscodeeditorexpression.h
QgsExpressionContext::functionNames
QStringList functionNames() const
Retrieves a list of function names contained in the context.
Definition: qgsexpressioncontext.cpp:459
QgsExpressionFunction
Definition: qgsexpressionfunction.h:40
QgsExpressionFunction::name
QString name() const
The name of the function.
Definition: qgsexpressionfunction.h:190
QgsExpressionFunction::parameters
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
Definition: qgsexpressionfunction.h:214
QgsCodeEditor::setFoldingVisible
void setFoldingVisible(bool folding)
Set folding visible state.
Definition: qgscodeeditor.cpp:164
QgsCodeEditor::getMonospaceFont
QFont getMonospaceFont()
Definition: qgscodeeditor.cpp:199
QgsExpression::functionCount
static int functionCount()
Returns the number of functions defined in the parser.
Definition: qgsexpression.cpp:140
QgsExpressionContext::filteredVariableNames
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
Definition: qgsexpressioncontext.cpp:414
QgsField
Definition: qgsfield.h:49