26#include <qclipboard.h>
28#include "moc_qgsexpressionpreviewwidget.cpp"
30using namespace Qt::StringLiterals;
36 mPreviewLabel->clear();
37 mPreviewLabel->setContextMenuPolicy( Qt::ActionsContextMenu );
39 mPreviewLabel->addAction( mCopyPreviewAction );
40 mFeaturePickerWidget->setShowBrowserButtons(
true );
42 mStackedWidget->setCurrentWidget( mPageFeaturePicker );
44 mCustomButtonNext->setEnabled(
false );
45 mCustomButtonPrev->setEnabled(
false );
47 connect( mCustomComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsExpressionPreviewWidget::setCustomChoice );
48 connect( mPreviewLabel, &QLabel::linkActivated,
this, &QgsExpressionPreviewWidget::linkActivated );
49 connect( mCopyPreviewAction, &QAction::triggered,
this, &QgsExpressionPreviewWidget::copyFullExpressionValue );
50 connect( mCustomButtonPrev, &QToolButton::clicked,
this, [
this] {
51 mCustomComboBox->setCurrentIndex( std::max( 0, mCustomComboBox->currentIndex() - 1 ) );
53 connect( mCustomButtonNext, &QToolButton::clicked,
this, [
this] {
54 mCustomComboBox->setCurrentIndex( std::min( mCustomComboBox->count() - 1, mCustomComboBox->currentIndex() + 1 ) );
60 if ( layer != mLayer )
63 mFeaturePickerWidget->setLayer( layer );
69 mCustomPreviewGeneratorFunction = previewContextGenerator;
70 mStackedWidget->setCurrentWidget( mPageCustomPicker );
71 mCustomLabel->setText( label );
72 mCustomComboBox->blockSignals(
true );
73 mCustomComboBox->clear();
74 for (
const auto &choice : choices )
76 mCustomComboBox->addItem( choice.first, choice.second );
78 mCustomComboBox->blockSignals(
false );
84 if ( expression != mExpressionText )
86 mExpressionText = expression;
94 if ( feature != mExpressionContext.feature() )
96 mExpressionContext.setFeature( feature );
104 mUseGeomCalculator =
true;
109 mExpressionContext = context;
112void QgsExpressionPreviewWidget::refreshPreview()
116 if ( mExpressionText.isEmpty() )
118 mPreviewLabel->clear();
119 mPreviewLabel->setStyleSheet( QString() );
120 mCopyPreviewAction->setEnabled(
false );
121 setExpressionToolTip( QString() );
127 mExpression = QgsExpression( mExpressionText );
129 if ( mUseGeomCalculator )
133 mExpression.setGeomCalculator( &mDa );
135 const QVariant value = mExpression.evaluate( &mExpressionContext );
137 if ( !mExpression.hasEvalError() )
139 mPreviewLabel->setText( preview );
140 mCopyPreviewAction->setEnabled(
true );
143 if ( mExpression.hasParserError() || mExpression.hasEvalError() )
148 if ( !mExpressionContext.feature().isValid() )
150 if ( !mExpression.referencedColumns().isEmpty() || mExpression.needsGeometry() )
152 mPreviewLabel->setText( tr(
"No feature was found on this layer to evaluate the expression." ) );
153 mPreviewLabel->setStyleSheet( u
"color: rgba(220, 125, 0, 255);"_s );
155 setParserError(
false );
156 setEvalError(
false );
161 const QString errorString = mExpression.parserErrorString().replace(
"\n"_L1,
"<br>"_L1 );
163 if ( mExpression.hasParserError() )
164 tooltip = QStringLiteral(
"<b>%1:</b>"
166 .arg( tr(
"Parser Errors" ), errorString );
168 if ( !mExpression.hasParserError() && mExpression.hasEvalError() )
169 tooltip += u
"<b>%1:</b> %2"_s.arg( tr(
"Eval Error" ), mExpression.evalErrorString() );
171 mPreviewLabel->setText( tr(
"Expression is invalid <a href="
173 ">(more info)</a>" ) );
174 mPreviewLabel->setStyleSheet( u
"color: rgba(255, 6, 10, 255);"_s );
175 setExpressionToolTip( tooltip );
177 setParserError( mExpression.hasParserError() );
178 setEvalError( mExpression.hasEvalError() );
179 mCopyPreviewAction->setEnabled(
false );
183 mPreviewLabel->setStyleSheet( QString() );
185 if ( longerPreview != preview )
186 setExpressionToolTip( longerPreview );
188 setExpressionToolTip( QString() );
190 setParserError(
false );
191 setEvalError(
false );
192 mCopyPreviewAction->setEnabled(
true );
197void QgsExpressionPreviewWidget::linkActivated(
const QString & )
199 QgsMessageViewer mv(
this, QgsGuiUtils::ModalDialogFlags,
false );
200 mv.setWindowTitle( tr(
"More Info on Expression Error" ) );
201 mv.setMessageAsHtml( mToolTip );
205void QgsExpressionPreviewWidget::setExpressionToolTip(
const QString &toolTip )
207 if ( toolTip == mToolTip )
211 if ( toolTip.isEmpty() )
213 mPreviewLabel->setToolTip( tr(
"Right-click to copy" ) );
217 mPreviewLabel->setToolTip( tr(
"%1 (right-click to copy)" ).arg( mToolTip ) );
222void QgsExpressionPreviewWidget::setParserError(
bool parserError )
237 return mPreviewLabel->text();
240void QgsExpressionPreviewWidget::setEvalError(
bool evalError )
254void QgsExpressionPreviewWidget::copyFullExpressionValue()
256 QClipboard *clipboard = QApplication::clipboard();
257 const QVariant value = mExpression.
evaluate( &mExpressionContext );
260 clipboard->setText( copiedValue );
263void QgsExpressionPreviewWidget::setCustomChoice(
int )
265 const QVariant selectedValue = mCustomComboBox->currentData();
267 mCustomButtonPrev->setEnabled( mCustomComboBox->currentIndex() > 0 && mCustomComboBox->count() > 0 );
268 mCustomButtonNext->setEnabled( mCustomComboBox->currentIndex() < ( mCustomComboBox->count() - 1 ) && mCustomComboBox->count() > 0 );
270 mExpressionContext = mCustomPreviewGeneratorFunction( selectedValue );
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Handles parsing and evaluation of expressions (formerly called "search strings").
static QString formatPreviewString(const QVariant &value, bool htmlOutput=true, int maximumPreviewLength=60)
Formats an expression result for friendly display to the user.
QVariant evaluate()
Evaluate the feature and return the result.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Represents a vector layer which manages a vector based dataset.
#define QgsDebugMsgLevel(str, level)