QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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  // force the feature to be valid, so it can evaluate an invalid feature but having its fields set
53  if ( !feature.isValid() )
54  {
55  QgsFeature validFeature( feature );
56  validFeature.setValid( true );
57  mExpressionContext.setFeature( validFeature );
58  }
59  else
60  {
61  mExpressionContext.setFeature( feature );
62  }
63  refreshPreview();
64 }
65 
67 {
68  mDa = da;
69  mUseGeomCalculator = true;
70 }
71 
73 {
74  mExpressionContext = context;
75 }
76 
77 void QgsExpressionPreviewWidget::refreshPreview()
78 {
79  // If the string is empty the expression will still "fail" although
80  // we don't show the user an error as it will be confusing.
81  if ( mExpressionText.isEmpty() )
82  {
83  mPreviewLabel->clear();
84  mPreviewLabel->setStyleSheet( QString() );
85  setExpressionToolTip( QString() );
86  emit expressionParsed( false );
87  mExpression = QgsExpression();
88  }
89  else
90  {
91  mExpression = QgsExpression( mExpressionText );
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:369
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
QgsExpressionPreviewWidget::setGeomCalculator
void setGeomCalculator(const QgsDistanceArea &da)
Sets geometry calculator used in distance/area calculations.
Definition: qgsexpressionpreviewwidget.cpp:66
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.
QgsFeature::setValid
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:188
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:941
QgsExpressionPreviewWidget::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context for the widget.
Definition: qgsexpressionpreviewwidget.cpp:72
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:183
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
Definition: qgsvectorlayer.h:385
QgsExpressionPreviewWidget::setLayer
void setLayer(QgsVectorLayer *layer)
Sets the layer used in the preview.
Definition: qgsexpressionpreviewwidget.cpp:36
QgsDistanceArea
Definition: qgsdistancearea.h:49
QgsFeature
Definition: qgsfeature.h:55
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
Definition: qgsexpression.h:113
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