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] { mCustomComboBox->setCurrentIndex( std::max( 0, mCustomComboBox->currentIndex() - 1 ) ); } );
51 connect( mCustomButtonNext, &QToolButton::clicked,
this, [
this] { mCustomComboBox->setCurrentIndex( std::min( mCustomComboBox->count() - 1, mCustomComboBox->currentIndex() + 1 ) ); } );
56 if ( layer != mLayer )
59 mFeaturePickerWidget->setLayer( layer );
64 const QString &label,
const QList<QPair<QString, QVariant>> &choices,
const std::function<
QgsExpressionContext(
const QVariant & )> &previewContextGenerator
67 mCustomPreviewGeneratorFunction = previewContextGenerator;
68 mStackedWidget->setCurrentWidget( mPageCustomPicker );
69 mCustomLabel->setText( label );
70 mCustomComboBox->blockSignals(
true );
71 mCustomComboBox->clear();
72 for (
const auto &choice : choices )
74 mCustomComboBox->addItem( choice.first, choice.second );
76 mCustomComboBox->blockSignals(
false );
82 if ( expression != mExpressionText )
84 mExpressionText = expression;
92 if ( feature != mExpressionContext.feature() )
94 mExpressionContext.setFeature( feature );
102 mUseGeomCalculator =
true;
107 mExpressionContext = context;
110void QgsExpressionPreviewWidget::refreshPreview()
114 if ( mExpressionText.isEmpty() )
116 mPreviewLabel->clear();
117 mPreviewLabel->setStyleSheet( QString() );
118 mCopyPreviewAction->setEnabled(
false );
119 setExpressionToolTip( QString() );
125 mExpression = QgsExpression( mExpressionText );
127 if ( mUseGeomCalculator )
131 mExpression.setGeomCalculator( &mDa );
133 const QVariant value = mExpression.evaluate( &mExpressionContext );
135 if ( !mExpression.hasEvalError() )
137 mPreviewLabel->setText( preview );
138 mCopyPreviewAction->setEnabled(
true );
141 if ( mExpression.hasParserError() || mExpression.hasEvalError() )
146 if ( !mExpressionContext.feature().isValid() )
148 if ( !mExpression.referencedColumns().isEmpty() || mExpression.needsGeometry() )
150 mPreviewLabel->setText( tr(
"No feature was found on this layer to evaluate the expression." ) );
151 mPreviewLabel->setStyleSheet( u
"color: rgba(220, 125, 0, 255);"_s );
153 setParserError(
false );
154 setEvalError(
false );
159 const QString errorString = mExpression.parserErrorString().replace(
"\n"_L1,
"<br>"_L1 );
161 if ( mExpression.hasParserError() )
162 tooltip = QStringLiteral(
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(
172 "Expression is invalid <a href="
176 mPreviewLabel->setStyleSheet( u
"color: rgba(255, 6, 10, 255);"_s );
177 setExpressionToolTip( tooltip );
179 setParserError( mExpression.hasParserError() );
180 setEvalError( mExpression.hasEvalError() );
181 mCopyPreviewAction->setEnabled(
false );
185 mPreviewLabel->setStyleSheet( QString() );
187 if ( longerPreview != preview )
188 setExpressionToolTip( longerPreview );
190 setExpressionToolTip( QString() );
192 setParserError(
false );
193 setEvalError(
false );
194 mCopyPreviewAction->setEnabled(
true );
199void QgsExpressionPreviewWidget::linkActivated(
const QString & )
201 QgsMessageViewer mv(
this, QgsGuiUtils::ModalDialogFlags,
false );
202 mv.setWindowTitle( tr(
"More Info on Expression Error" ) );
203 mv.setMessageAsHtml( mToolTip );
207void QgsExpressionPreviewWidget::setExpressionToolTip(
const QString &toolTip )
209 if ( toolTip == mToolTip )
213 if ( toolTip.isEmpty() )
215 mPreviewLabel->setToolTip( tr(
"Right-click to copy" ) );
219 mPreviewLabel->setToolTip( tr(
"%1 (right-click to copy)" ).arg( mToolTip ) );
224void QgsExpressionPreviewWidget::setParserError(
bool parserError )
239 return mPreviewLabel->text();
242void QgsExpressionPreviewWidget::setEvalError(
bool evalError )
256void QgsExpressionPreviewWidget::copyFullExpressionValue()
258 QClipboard *clipboard = QApplication::clipboard();
259 const QVariant value = mExpression.
evaluate( &mExpressionContext );
262 clipboard->setText( copiedValue );
265void QgsExpressionPreviewWidget::setCustomChoice(
int )
267 const QVariant selectedValue = mCustomComboBox->currentData();
269 mCustomButtonPrev->setEnabled( mCustomComboBox->currentIndex() > 0 && mCustomComboBox->count() > 0 );
270 mCustomButtonNext->setEnabled( mCustomComboBox->currentIndex() < ( mCustomComboBox->count() - 1 ) && mCustomComboBox->count() > 0 );
272 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)