QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsexpressionpreviewwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressionpreviewwidget.cpp
3  --------------------------------------
4  Date : march 2020 - quarantine day 12
5  Copyright : (C) 2020 by Denis Rouzaud
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 
17 #include "qgsmessageviewer.h"
18 #include "qgsvectorlayer.h"
19 #include "qgsfeaturepickerwidget.h"
20 
21 
22 
23 
24 
26  : QWidget( parent )
27 {
28  setupUi( this );
29  mPreviewLabel->clear();
30  mFeaturePickerWidget->setShowBrowserButtons( true );
31 
33  connect( mPreviewLabel, &QLabel::linkActivated, this, &QgsExpressionPreviewWidget::linkActivated );
34 }
35 
37 {
38  mLayer = layer;
39  mFeaturePickerWidget->setLayer( layer );
40 }
41 
42 void QgsExpressionPreviewWidget::setExpressionText( const QString &expression )
43 {
44  mExpressionText = expression;
45  refreshPreview();
46 }
47 
49 {
50  // todo: update the combo box if it has been set externaly?
51 
52  mExpressionContext.setFeature( feature );
53  refreshPreview();
54 }
55 
57 {
58  mDa = da;
59  mUseGeomCalculator = true;
60 }
61 
63 {
64  mExpressionContext = context;
65 }
66 
67 void QgsExpressionPreviewWidget::refreshPreview()
68 {
69  // If the string is empty the expression will still "fail" although
70  // we don't show the user an error as it will be confusing.
71  if ( mExpressionText.isEmpty() )
72  {
73  mPreviewLabel->clear();
74  mPreviewLabel->setStyleSheet( QString() );
75  setExpressionToolTip( QString() );
76  emit expressionParsed( false );
77  mExpression = QgsExpression();
78  }
79  else
80  {
81  mExpression = QgsExpression( mExpressionText );
82 
83  if ( !mExpressionContext.feature().isValid() )
84  {
85  if ( !mExpression.referencedColumns().isEmpty() || mExpression.needsGeometry() )
86  {
87  mPreviewLabel->setText( tr( "No feature was found on this layer to evaluate the expression." ) );
88  mPreviewLabel->setStyleSheet( QStringLiteral( "color: rgba(255, 6, 10, 255);" ) );
89  return;
90  }
91  }
92 
93  if ( mUseGeomCalculator )
94  {
95  // only set an explicit geometry calculator if a call to setGeomCalculator was made. If not,
96  // let the expression context handle this correctly
97  mExpression.setGeomCalculator( &mDa );
98  }
99 
100  QVariant value = mExpression.evaluate( &mExpressionContext );
101  if ( !mExpression.hasEvalError() )
102  {
103  mPreviewLabel->setText( QgsExpression::formatPreviewString( value ) );
104  }
105 
106  if ( mExpression.hasParserError() || mExpression.hasEvalError() )
107  {
108  QString errorString = mExpression.parserErrorString().replace( "\n", "<br>" );
109  QString tooltip;
110  if ( mExpression.hasParserError() )
111  tooltip = QStringLiteral( "<b>%1:</b>"
112  "%2" ).arg( tr( "Parser Errors" ), errorString );
113  // Only show the eval error if there is no parser error.
114  if ( !mExpression.hasParserError() && mExpression.hasEvalError() )
115  tooltip += QStringLiteral( "<b>%1:</b> %2" ).arg( tr( "Eval Error" ), mExpression.evalErrorString() );
116 
117  mPreviewLabel->setText( tr( "Expression is invalid <a href=""more"">(more info)</a>" ) );
118  mPreviewLabel->setStyleSheet( QStringLiteral( "color: rgba(255, 6, 10, 255);" ) );
119  setExpressionToolTip( tooltip );
120  emit expressionParsed( false );
121  setParserError( mExpression.hasParserError() );
122  setEvalError( mExpression.hasEvalError() );
123  }
124  else
125  {
126  mPreviewLabel->setStyleSheet( QString() );
127  setExpressionToolTip( QString() );
128  emit expressionParsed( true );
129  setParserError( false );
130  setEvalError( false );
131  }
132  }
133 }
134 
135 void QgsExpressionPreviewWidget::linkActivated( const QString & )
136 {
137  QgsMessageViewer mv( this, QgsGuiUtils::ModalDialogFlags, false );
138  mv.setWindowTitle( tr( "More Info on Expression Error" ) );
139  mv.setMessageAsHtml( mToolTip );
140  mv.exec();
141 }
142 
143 void QgsExpressionPreviewWidget::setExpressionToolTip( const QString &toolTip )
144 {
145  if ( toolTip == mToolTip )
146  return;
147 
148  mToolTip = toolTip;
149  mPreviewLabel->setToolTip( mToolTip );
150  emit toolTipChanged( mToolTip );
151 }
152 
153 void QgsExpressionPreviewWidget::setParserError( bool parserError )
154 {
155  if ( parserError != mParserError )
156  {
157  mParserError = parserError;
158  emit parserErrorChanged();
159  }
160 }
162 {
163  return mParserError;
164 }
165 
166 void QgsExpressionPreviewWidget::setEvalError( bool evalError )
167 {
168  if ( evalError == mEvalError )
169  return;
170 
171  mEvalError = evalError;
172  emit evalErrorChanged();
173 }
174 
176 {
177  return mEvalError;
178 }
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
QgsExpression::evalErrorString
QString evalErrorString() const
Returns evaluation error.
Definition: qgsexpression.cpp:379
QgsExpressionPreviewWidget::parserError
bool parserError() const
Will be set to true if the current expression text reports a parser error with the context.
Definition: qgsexpressionpreviewwidget.cpp:161
QgsExpression::referencedColumns
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
Definition: qgsexpression.cpp:217
QgsExpressionPreviewWidget::setGeomCalculator
void setGeomCalculator(const QgsDistanceArea &da)
Sets geometry calculator used in distance/area calculations.
Definition: qgsexpressionpreviewwidget.cpp:56
QgsExpressionPreviewWidget::QgsExpressionPreviewWidget
QgsExpressionPreviewWidget(QWidget *parent=nullptr)
Constructor.
Definition: qgsexpressionpreviewwidget.cpp:25
QgsFeaturePickerWidget::featureChanged
void featureChanged(const QgsFeature &feature)
Sends the feature as soon as it is chosen.
QgsExpressionPreviewWidget::setCurrentFeature
void setCurrentFeature(const QgsFeature &feature)
sets the current feature used
Definition: qgsexpressionpreviewwidget.cpp:48
qgsfeaturepickerwidget.h
QgsExpression::setGeomCalculator
void setGeomCalculator(const QgsDistanceArea *calc)
Sets the geometry calculator used for distance and area calculations in expressions.
Definition: qgsexpression.cpp:314
QgsExpression::formatPreviewString
static QString formatPreviewString(const QVariant &value, bool htmlOutput=true)
Formats an expression result for friendly display to the user.
Definition: qgsexpression.cpp:944
QgsExpressionPreviewWidget::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context for the widget.
Definition: qgsexpressionpreviewwidget.cpp:62
QgsExpression::hasEvalError
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
Definition: qgsexpression.cpp:374
QgsExpression::parserErrorString
QString parserErrorString() const
Returns parser error.
Definition: qgsexpression.cpp:207
QgsFeature::isValid
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:185
QgsExpressionPreviewWidget::expressionParsed
void expressionParsed(bool isValid)
Emitted when the user changes the expression in the widget.
QgsExpressionPreviewWidget::evalErrorChanged
void evalErrorChanged()
Will be set to true if the current expression text reported an eval error with the context.
qgsexpressionpreviewwidget.h
qgsmessageviewer.h
QgsExpressionPreviewWidget::toolTipChanged
void toolTipChanged(const QString &toolTip)
Emitted whenever the tool tip changed.
QgsExpressionPreviewWidget::evalError
bool evalError() const
Will be set to true if the current expression text reported an eval error with the context.
Definition: qgsexpressionpreviewwidget.cpp:175
QgsExpression::evaluate
QVariant evaluate()
Evaluate the feature and return the result.
Definition: qgsexpression.cpp:346
qgsvectorlayer.h
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsExpressionContext::feature
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
Definition: qgsexpressioncontext.cpp:540
QgsExpressionPreviewWidget::setLayer
void setLayer(QgsVectorLayer *layer)
Sets the layer used in the preview.
Definition: qgsexpressionpreviewwidget.cpp:36
QgsExpression::needsGeometry
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
Definition: qgsexpression.cpp:266
QgsDistanceArea
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Definition: qgsdistancearea.h:50
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsExpressionPreviewWidget::setExpressionText
void setExpressionText(const QString &expression)
Sets the expression.
Definition: qgsexpressionpreviewwidget.cpp:42
QgsExpression::hasParserError
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.cpp:202
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:105
QgsExpressionPreviewWidget::parserErrorChanged
void parserErrorChanged()
Will be set to true if the current expression text reported a parser error with the context.
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:521