QGIS API Documentation 3.41.0-Master (45a0abf3bec)
Loading...
Searching...
No Matches
qgsexpressionlineedit.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsexpressionlineedit.cpp
3 ------------------------
4 Date : 18.08.2016
5 Copyright : (C) 2016 Nyall Dawson
6 Email : nyall dot dawson 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
17#include "moc_qgsexpressionlineedit.cpp"
18#include "qgsfilterlineedit.h"
20#include "qgsapplication.h"
23#include "qgsproject.h"
24#include "qgsvectorlayer.h"
27
28#include <QHBoxLayout>
29#include <QVBoxLayout>
30#include <QToolButton>
31
32
34 : QWidget( parent )
35 , mExpressionDialogTitle( tr( "Expression Builder" ) )
36{
37 mButton = new QToolButton();
38 mButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
39 mButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconExpression.svg" ) ) );
40 connect( mButton, &QAbstractButton::clicked, this, &QgsExpressionLineEdit::editExpression );
41
42 //sets up layout
43 setMultiLine( false );
44
45 mExpressionContext = QgsExpressionContext();
46 mExpressionContext << QgsExpressionContextUtils::globalScope()
48}
49
51
53{
54 mExpressionDialogTitle = title;
55}
56
58{
59 const QString exp = expression();
60
61 if ( multiLine && !mCodeEditor )
62 {
63 mCodeEditor = new QgsCodeEditorExpression();
64 mCodeEditor->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
65 delete mLineEdit;
66 mLineEdit = nullptr;
67
68 QHBoxLayout *newLayout = new QHBoxLayout();
69 newLayout->setContentsMargins( 0, 0, 0, 0 );
70 newLayout->addWidget( mCodeEditor );
71
72 QVBoxLayout *vLayout = new QVBoxLayout();
73 vLayout->addWidget( mButton );
74 vLayout->addStretch();
75 newLayout->addLayout( vLayout );
76
77 delete layout();
78 setLayout( newLayout );
79
80 setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
81
82 setFocusProxy( mCodeEditor );
83 connect( mCodeEditor, &QsciScintilla::textChanged, this, static_cast < void ( QgsExpressionLineEdit::* )() > ( &QgsExpressionLineEdit::expressionEdited ) );
84
85 setExpression( exp );
86 }
87 else if ( !multiLine && !mLineEdit )
88 {
89 delete mCodeEditor;
90 mCodeEditor = nullptr;
91 mLineEdit = new QgsFilterLineEdit();
92 mLineEdit->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
93
94 QHBoxLayout *newLayout = new QHBoxLayout();
95 newLayout->setContentsMargins( 0, 0, 0, 0 );
96 newLayout->addWidget( mLineEdit );
97 newLayout->addWidget( mButton );
98
99 delete layout();
100 setLayout( newLayout );
101
102 setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
103
104 setFocusProxy( mLineEdit );
105 connect( mLineEdit, &QLineEdit::textChanged, this, static_cast < void ( QgsExpressionLineEdit::* )( const QString & ) > ( &QgsExpressionLineEdit::expressionEdited ) );
106
107 setExpression( exp );
108 }
109}
110
112{
113 return mExpectedOutputFormat;
114}
115
117{
118 mExpectedOutputFormat = expected;
119}
120
122{
123 mDa.reset( new QgsDistanceArea( da ) );
124}
125
127{
128 if ( !mExpressionContextGenerator || mExpressionContextGenerator == mLayer )
129 mExpressionContextGenerator = layer;
130 mLayer = layer;
131}
132
134{
135 if ( mLineEdit )
136 return mLineEdit->text();
137 else if ( mCodeEditor )
138 return mCodeEditor->text();
139
140 return QString();
141}
142
143bool QgsExpressionLineEdit::isValidExpression( QString *expressionError ) const
144{
145 QString temp;
146 const QgsExpressionContext context = mExpressionContextGenerator ? mExpressionContextGenerator->createExpressionContext() : mExpressionContext;
147 return QgsExpression::checkExpression( expression(), &context, expressionError ? *expressionError : temp );
148}
149
151{
152 mExpressionContextGenerator = generator;
153}
154
155void QgsExpressionLineEdit::setExpression( const QString &newExpression )
156{
157 if ( mLineEdit )
158 mLineEdit->setText( newExpression );
159 else if ( mCodeEditor )
160 mCodeEditor->setText( newExpression );
161}
162
163void QgsExpressionLineEdit::editExpression()
164{
165 const QString currentExpression = expression();
166
167 const QgsExpressionContext context = mExpressionContextGenerator ? mExpressionContextGenerator->createExpressionContext() : mExpressionContext;
168
169 QgsExpressionBuilderDialog dlg( mLayer, currentExpression, this, QStringLiteral( "generic" ), context );
170 dlg.setExpectedOutputFormat( mExpectedOutputFormat );
171 if ( mDa )
172 {
173 dlg.setGeomCalculator( *mDa );
174 }
175 dlg.setWindowTitle( mExpressionDialogTitle );
176
177 if ( dlg.exec() )
178 {
179 const QString newExpression = dlg.expressionText();
180 setExpression( newExpression );
181 }
182}
183
184void QgsExpressionLineEdit::expressionEdited()
185{
187}
188
189void QgsExpressionLineEdit::expressionEdited( const QString &expression )
190{
191 updateLineEditStyle( expression );
193}
194
196{
197 if ( event->type() == QEvent::EnabledChange )
198 {
199 updateLineEditStyle( expression() );
200 }
201}
202
203void QgsExpressionLineEdit::updateLineEditStyle( const QString &expression )
204{
205 if ( !mLineEdit )
206 return;
207
208 QPalette appPalette = qApp->palette();
209 QPalette palette = mLineEdit->palette();
210 if ( !isEnabled() )
211 {
212 palette.setColor( QPalette::Text, appPalette.color( QPalette::Disabled, QPalette::Text ) );
213 }
214 else
215 {
216 bool isValid = true;
217 if ( !expression.isEmpty() )
218 {
219 isValid = isExpressionValid( expression );
220 }
221 if ( !isValid )
222 {
223 palette.setColor( QPalette::Text, Qt::red );
224 }
225 else
226 {
227 palette.setColor( QPalette::Text, appPalette.color( QPalette::Text ) );
228 }
229 }
230 mLineEdit->setPalette( palette );
231}
232
233bool QgsExpressionLineEdit::isExpressionValid( const QString &expressionStr )
234{
235 QgsExpression expression( expressionStr );
236
237 const QgsExpressionContext context = mExpressionContextGenerator ? mExpressionContextGenerator->createExpressionContext() : mExpressionContext;
238 expression.prepare( &mExpressionContext );
239 return !expression.hasParserError();
240}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A QGIS expression editor based on QScintilla2.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
A generic dialog for building expression strings.
Abstract interface for generating an expression context.
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
The QgsExpressionLineEdit widget includes a line edit for entering expressions together with a button...
QString expression() const
Returns the current expression shown in the widget.
void setMultiLine(bool multiLine)
Sets whether the widget should show a multiline text editor.
void changeEvent(QEvent *event) override
bool isValidExpression(QString *expressionError=nullptr) const
Determines if the current expression is valid.
~QgsExpressionLineEdit() override
void expressionChanged(const QString &expression)
Emitted when the expression is changed.
void registerExpressionContextGenerator(const QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
void setExpectedOutputFormat(const QString &expected)
Set the expected format string, which is shown in the expression builder dialog for the widget.
void setGeomCalculator(const QgsDistanceArea &distanceArea)
Set the geometry calculator used in the expression dialog.
void setExpressionDialogTitle(const QString &title)
Sets the title used in the expression builder dialog.
void setExpression(const QString &expression)
Sets the current expression to show in the widget.
QString expectedOutputFormat() const
Returns the expected format string, which is shown in the expression builder dialog for the widget.
QgsExpressionLineEdit(QWidget *parent=nullptr)
Constructor for QgsExpressionLineEdit.
void setLayer(QgsVectorLayer *layer)
Sets a layer associated with the widget.
Class for parsing and evaluation of expressions (formerly called "search strings").
static bool checkExpression(const QString &text, const QgsExpressionContext *context, QString &errorMessage)
Tests whether a string is a valid expression.
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
static QgsProject * instance()
Returns the QgsProject singleton instance.
Represents a vector layer which manages a vector based data sets.