25#include <qclipboard.h>
27#include "moc_qgsexpressionpreviewwidget.cpp"
33 mPreviewLabel->clear();
34 mPreviewLabel->setContextMenuPolicy( Qt::ActionsContextMenu );
35 mCopyPreviewAction =
new QAction(
QgsApplication::getThemeIcon( QStringLiteral(
"/mActionEditCopy.svg" ) ), tr(
"Copy Expression Value" ),
this );
36 mPreviewLabel->addAction( mCopyPreviewAction );
37 mFeaturePickerWidget->setShowBrowserButtons(
true );
39 mStackedWidget->setCurrentWidget( mPageFeaturePicker );
41 mCustomButtonNext->setEnabled(
false );
42 mCustomButtonPrev->setEnabled(
false );
44 connect( mCustomComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsExpressionPreviewWidget::setCustomChoice );
45 connect( mPreviewLabel, &QLabel::linkActivated,
this, &QgsExpressionPreviewWidget::linkActivated );
46 connect( mCopyPreviewAction, &QAction::triggered,
this, &QgsExpressionPreviewWidget::copyFullExpressionValue );
47 connect( mCustomButtonPrev, &QToolButton::clicked,
this, [
this] {
48 mCustomComboBox->setCurrentIndex( std::max( 0, mCustomComboBox->currentIndex() - 1 ) );
50 connect( mCustomButtonNext, &QToolButton::clicked,
this, [
this] {
51 mCustomComboBox->setCurrentIndex( std::min( mCustomComboBox->count() - 1, mCustomComboBox->currentIndex() + 1 ) );
57 if ( layer != mLayer )
60 mFeaturePickerWidget->setLayer( layer );
66 mCustomPreviewGeneratorFunction = previewContextGenerator;
67 mStackedWidget->setCurrentWidget( mPageCustomPicker );
68 mCustomLabel->setText( label );
69 mCustomComboBox->blockSignals(
true );
70 mCustomComboBox->clear();
71 for (
const auto &choice : choices )
73 mCustomComboBox->addItem( choice.first, choice.second );
75 mCustomComboBox->blockSignals(
false );
81 if ( expression != mExpressionText )
83 mExpressionText = expression;
91 if ( feature != mExpressionContext.feature() )
93 mExpressionContext.setFeature( feature );
101 mUseGeomCalculator =
true;
106 mExpressionContext = context;
109void QgsExpressionPreviewWidget::refreshPreview()
113 if ( mExpressionText.isEmpty() )
115 mPreviewLabel->clear();
116 mPreviewLabel->setStyleSheet( QString() );
117 mCopyPreviewAction->setEnabled(
false );
118 setExpressionToolTip( QString() );
124 mExpression = QgsExpression( mExpressionText );
126 if ( mUseGeomCalculator )
130 mExpression.setGeomCalculator( &mDa );
132 const QVariant value = mExpression.evaluate( &mExpressionContext );
134 if ( !mExpression.hasEvalError() )
136 mPreviewLabel->setText( preview );
137 mCopyPreviewAction->setEnabled(
true );
140 if ( mExpression.hasParserError() || mExpression.hasEvalError() )
145 if ( !mExpressionContext.feature().isValid() )
147 if ( !mExpression.referencedColumns().isEmpty() || mExpression.needsGeometry() )
149 mPreviewLabel->setText( tr(
"No feature was found on this layer to evaluate the expression." ) );
150 mPreviewLabel->setStyleSheet( QStringLiteral(
"color: rgba(220, 125, 0, 255);" ) );
152 setParserError(
false );
153 setEvalError(
false );
158 const QString errorString = mExpression.parserErrorString().replace( QLatin1String(
"\n" ), QLatin1String(
"<br>" ) );
160 if ( mExpression.hasParserError() )
161 tooltip = QStringLiteral(
"<b>%1:</b>"
163 .arg( tr(
"Parser Errors" ), errorString );
165 if ( !mExpression.hasParserError() && mExpression.hasEvalError() )
166 tooltip += QStringLiteral(
"<b>%1:</b> %2" ).arg( tr(
"Eval Error" ), mExpression.evalErrorString() );
168 mPreviewLabel->setText( tr(
"Expression is invalid <a href="
170 ">(more info)</a>" ) );
171 mPreviewLabel->setStyleSheet( QStringLiteral(
"color: rgba(255, 6, 10, 255);" ) );
172 setExpressionToolTip( tooltip );
174 setParserError( mExpression.hasParserError() );
175 setEvalError( mExpression.hasEvalError() );
176 mCopyPreviewAction->setEnabled(
false );
180 mPreviewLabel->setStyleSheet( QString() );
182 if ( longerPreview != preview )
183 setExpressionToolTip( longerPreview );
185 setExpressionToolTip( QString() );
187 setParserError(
false );
188 setEvalError(
false );
189 mCopyPreviewAction->setEnabled(
true );
194void QgsExpressionPreviewWidget::linkActivated(
const QString & )
196 QgsMessageViewer mv(
this, QgsGuiUtils::ModalDialogFlags,
false );
197 mv.setWindowTitle( tr(
"More Info on Expression Error" ) );
198 mv.setMessageAsHtml( mToolTip );
202void QgsExpressionPreviewWidget::setExpressionToolTip(
const QString &toolTip )
204 if ( toolTip == mToolTip )
208 if ( toolTip.isEmpty() )
210 mPreviewLabel->setToolTip( tr(
"Right-click to copy" ) );
214 mPreviewLabel->setToolTip( tr(
"%1 (right-click to copy)" ).arg( mToolTip ) );
219void QgsExpressionPreviewWidget::setParserError(
bool parserError )
234 return mPreviewLabel->text();
237void QgsExpressionPreviewWidget::setEvalError(
bool evalError )
251void QgsExpressionPreviewWidget::copyFullExpressionValue()
253 QClipboard *clipboard = QApplication::clipboard();
254 const QVariant value = mExpression.
evaluate( &mExpressionContext );
256 QgsDebugMsgLevel( QStringLiteral(
"set clipboard: %1" ).arg( copiedValue ), 4 );
257 clipboard->setText( copiedValue );
260void QgsExpressionPreviewWidget::setCustomChoice(
int )
262 const QVariant selectedValue = mCustomComboBox->currentData();
264 mCustomButtonPrev->setEnabled( mCustomComboBox->currentIndex() > 0 && mCustomComboBox->count() > 0 );
265 mCustomButtonNext->setEnabled( mCustomComboBox->currentIndex() < ( mCustomComboBox->count() - 1 ) && mCustomComboBox->count() > 0 );
267 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)