43QgsFeatureFilterWidget::QgsFeatureFilterWidget( QWidget *parent )
49 mFilterColumnsMenu =
new QMenu(
this );
50 mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu );
51 mStoredFilterExpressionMenu =
new QMenu(
this );
52 mActionStoredFilterExpressions->setMenu( mStoredFilterExpressionMenu );
64 mStoreFilterExpressionButton->setDefaultAction( mActionHandleStoreFilterExpression );
65 connect( mActionSaveAsStoredFilterExpression, &QAction::triggered,
this, &QgsFeatureFilterWidget::saveAsStoredFilterExpression );
66 connect( mActionEditStoredFilterExpression, &QAction::triggered,
this, &QgsFeatureFilterWidget::editStoredFilterExpression );
67 connect( mActionHandleStoreFilterExpression, &QAction::triggered,
this, &QgsFeatureFilterWidget::handleStoreFilterExpression );
68 mApplyFilterButton->setDefaultAction( mActionApplyFilter );
71 connect( mActionAdvancedFilter, &QAction::triggered,
this, &QgsFeatureFilterWidget::filterExpressionBuilder );
72 connect( mActionShowAllFilter, &QAction::triggered,
this, &QgsFeatureFilterWidget::filterShowAll );
73 connect( mActionSelectedFilter, &QAction::triggered,
this, &QgsFeatureFilterWidget::filterSelected );
74 connect( mActionInvalidFilter, &QAction::triggered,
this, &QgsFeatureFilterWidget::filterInvalid );
75 connect( mActionVisibleFilter, &QAction::triggered,
this, &QgsFeatureFilterWidget::filterVisible );
76 connect( mActionEditedFilter, &QAction::triggered,
this, &QgsFeatureFilterWidget::filterEdited );
77 connect( mFilterQuery, &QLineEdit::returnPressed,
this, &QgsFeatureFilterWidget::filterQueryAccepted );
78 connect( mActionApplyFilter, &QAction::triggered,
this, &QgsFeatureFilterWidget::filterQueryAccepted );
79 connect( mFilterQuery, &QLineEdit::textChanged,
this, &QgsFeatureFilterWidget::onFilterQueryTextChanged );
86 mEditorContext = context;
87 mMessageBar = messageBar;
93 mFilterQueryTimer.setSingleShot(
true );
94 connect( &mFilterQueryTimer, &QTimer::timeout,
this, &QgsFeatureFilterWidget::updateCurrentStoredFilterExpression );
97 storedFilterExpressionBoxInit();
98 storeExpressionButtonInit();
101void QgsFeatureFilterWidget::filterShowAll()
103 mFilterButton->setDefaultAction( mActionShowAllFilter );
104 mFilterButton->setPopupMode( QToolButton::InstantPopup );
105 mFilterQuery->setVisible(
false );
106 mFilterQuery->setText( QString() );
107 if ( mCurrentSearchWidgetWrapper )
109 mCurrentSearchWidgetWrapper->widget()->setVisible(
false );
111 mApplyFilterButton->setVisible(
false );
112 mStoreFilterExpressionButton->setVisible(
false );
116void QgsFeatureFilterWidget::filterSelected()
118 mFilterButton->setDefaultAction( mActionSelectedFilter );
119 mFilterButton->setPopupMode( QToolButton::InstantPopup );
120 mFilterQuery->setVisible(
false );
121 mApplyFilterButton->setVisible(
false );
122 mStoreFilterExpressionButton->setVisible(
false );
126void QgsFeatureFilterWidget::filterVisible()
128 if ( !mLayer->isSpatial() )
134 mFilterButton->setDefaultAction( mActionVisibleFilter );
135 mFilterButton->setPopupMode( QToolButton::InstantPopup );
136 mFilterQuery->setVisible(
false );
137 mApplyFilterButton->setVisible(
false );
138 mStoreFilterExpressionButton->setVisible(
false );
142void QgsFeatureFilterWidget::filterInvalid()
144 mFilterButton->setDefaultAction( mActionInvalidFilter );
145 mFilterButton->setPopupMode( QToolButton::InstantPopup );
146 mFilterQuery->setVisible(
false );
147 mApplyFilterButton->setVisible(
false );
148 mStoreFilterExpressionButton->setVisible(
false );
150 mMainView->filterFeatures( QStringLiteral(
"is_feature_valid() = false" ), context );
154void QgsFeatureFilterWidget::filterEdited()
156 mFilterButton->setDefaultAction( mActionEditedFilter );
157 mFilterButton->setPopupMode( QToolButton::InstantPopup );
158 mFilterQuery->setVisible(
false );
159 mApplyFilterButton->setVisible(
false );
160 mStoreFilterExpressionButton->setVisible(
false );
165void QgsFeatureFilterWidget::filterQueryAccepted()
167 if ( ( mFilterQuery->isVisible() && mFilterQuery->text().isEmpty() ) || ( mCurrentSearchWidgetWrapper && mCurrentSearchWidgetWrapper->widget()->isVisible() && mCurrentSearchWidgetWrapper->expression().isEmpty() ) )
172 filterQueryChanged( mFilterQuery->text() );
175void QgsFeatureFilterWidget::filterQueryChanged(
const QString &query )
178 if ( mFilterButton->defaultAction() == mActionAdvancedFilter )
182 else if ( mCurrentSearchWidgetWrapper )
184 str = mCurrentSearchWidgetWrapper->expression();
187 setFilterExpression( str );
190void QgsFeatureFilterWidget::columnBoxInit()
192 const auto constActions = mFilterColumnsMenu->actions();
193 for ( QAction *a : constActions )
195 mFilterColumnsMenu->removeAction( a );
196 mFilterButton->removeAction( a );
200 mFilterButton->addAction( mActionShowAllFilter );
201 mFilterButton->addAction( mActionSelectedFilter );
202 if ( mLayer->isSpatial() )
204 mFilterButton->addAction( mActionVisibleFilter );
206 mFilterButton->addAction( mActionInvalidFilter );
207 mFilterButton->addAction( mActionEditedFilter );
208 mFilterButton->addAction( mActionFilterColumnsMenu );
209 mFilterButton->addAction( mActionAdvancedFilter );
210 mFilterButton->addAction( mActionStoredFilterExpressions );
212 const QList<QgsField> fields = mLayer->fields().toList();
214 const auto constFields = fields;
215 for (
const QgsField &field : constFields )
217 const int idx = mLayer->fields().lookupField( field.name() );
223 const QIcon icon = mLayer->fields().iconForField( idx );
224 const QString alias = mLayer->attributeDisplayName( idx );
227 QAction *filterAction =
new QAction( icon, alias, mFilterButton );
228 filterAction->setData( field.name() );
230 connect( filterAction, &QAction::triggered,
this, [=] { filterColumnChanged( filterAction ); } );
231 mFilterColumnsMenu->addAction( filterAction );
236void QgsFeatureFilterWidget::handleStoreFilterExpression()
238 if ( !mActionHandleStoreFilterExpression->isChecked() )
240 mLayer->storedExpressionManager()->removeStoredExpression( mActionHandleStoreFilterExpression->data().toString() );
244 mLayer->storedExpressionManager()->addStoredExpression( mFilterQuery->text(), mFilterQuery->text() );
247 updateCurrentStoredFilterExpression();
248 storedFilterExpressionBoxInit();
251void QgsFeatureFilterWidget::storedFilterExpressionBoxInit()
253 const auto constActions = mStoredFilterExpressionMenu->actions();
254 for ( QAction *a : constActions )
256 mStoredFilterExpressionMenu->removeAction( a );
260 const QList<QgsStoredExpression> storedExpressions = mLayer->storedExpressionManager()->storedExpressions();
263 QAction *storedExpressionAction =
new QAction( storedExpression.name, mFilterButton );
264 connect( storedExpressionAction, &QAction::triggered,
this, [=]() {
267 mStoredFilterExpressionMenu->addAction( storedExpressionAction );
271void QgsFeatureFilterWidget::storeExpressionButtonInit()
273 if ( mActionHandleStoreFilterExpression->isChecked() )
275 mActionHandleStoreFilterExpression->setToolTip( tr(
"Delete stored expression" ) );
276 mActionHandleStoreFilterExpression->setText( tr(
"Delete Stored Expression" ) );
277 mActionHandleStoreFilterExpression->setIcon(
QgsApplication::getThemeIcon( QStringLiteral(
"mActionHandleStoreFilterExpressionChecked.svg" ) ) );
278 mStoreFilterExpressionButton->removeAction( mActionSaveAsStoredFilterExpression );
279 mStoreFilterExpressionButton->addAction( mActionEditStoredFilterExpression );
283 mActionHandleStoreFilterExpression->setToolTip( tr(
"Save expression with the text as name" ) );
284 mActionHandleStoreFilterExpression->setText( tr(
"Save Expression" ) );
285 mActionHandleStoreFilterExpression->setIcon(
QgsApplication::getThemeIcon( QStringLiteral(
"mActionHandleStoreFilterExpressionUnchecked.svg" ) ) );
286 mStoreFilterExpressionButton->addAction( mActionSaveAsStoredFilterExpression );
287 mStoreFilterExpressionButton->removeAction( mActionEditStoredFilterExpression );
292void QgsFeatureFilterWidget::filterColumnChanged( QAction *filterAction )
294 mFilterButton->setDefaultAction( filterAction );
295 mFilterButton->setPopupMode( QToolButton::InstantPopup );
298 if ( mCurrentSearchWidgetWrapper )
300 mCurrentSearchWidgetWrapper->widget()->setVisible(
false );
301 delete mCurrentSearchWidgetWrapper;
303 const QString fieldName = mFilterButton->defaultAction()->data().toString();
305 const int fldIdx = mLayer->fields().lookupField( fieldName );
310 if ( mCurrentSearchWidgetWrapper->applyDirectly() )
313 mApplyFilterButton->setVisible(
false );
314 mStoreFilterExpressionButton->setVisible(
false );
319 mApplyFilterButton->setVisible(
true );
320 mStoreFilterExpressionButton->setVisible(
true );
323 replaceSearchWidget( mFilterQuery, mCurrentSearchWidgetWrapper->widget() );
326void QgsFeatureFilterWidget::filterExpressionBuilder()
332 dlg.setWindowTitle( tr(
"Expression Based Filter" ) );
337 dlg.setGeomCalculator( myDa );
339 if ( dlg.exec() == QDialog::Accepted )
345void QgsFeatureFilterWidget::saveAsStoredFilterExpression()
347 QgsDialog *dlg =
new QgsDialog(
this, Qt::WindowFlags(), QDialogButtonBox::Save | QDialogButtonBox::Cancel );
348 dlg->setWindowTitle( tr(
"Save Expression As" ) );
349 QVBoxLayout *layout = dlg->
layout();
350 dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
352 QLabel *nameLabel =
new QLabel( tr(
"Name" ), dlg );
353 QLineEdit *nameEdit =
new QLineEdit( dlg );
354 layout->addWidget( nameLabel );
355 layout->addWidget( nameEdit );
356 nameEdit->setFocus();
358 if ( dlg->exec() == QDialog::Accepted )
360 mLayer->storedExpressionManager()->addStoredExpression( nameEdit->text(), mFilterQuery->text() );
362 updateCurrentStoredFilterExpression();
363 storedFilterExpressionBoxInit();
367void QgsFeatureFilterWidget::editStoredFilterExpression()
369 QgsDialog *dlg =
new QgsDialog(
this, Qt::WindowFlags(), QDialogButtonBox::Save | QDialogButtonBox::Cancel );
370 dlg->setWindowTitle( tr(
"Edit expression" ) );
371 QVBoxLayout *layout = dlg->
layout();
372 dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
374 QLabel *nameLabel =
new QLabel( tr(
"Name" ), dlg );
375 QLineEdit *nameEdit =
new QLineEdit( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).name, dlg );
376 QLabel *expressionLabel =
new QLabel( tr(
"Expression" ), dlg );
378 expressionEdit->
setExpression( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).expression );
380 layout->addWidget( nameLabel );
381 layout->addWidget( nameEdit );
382 layout->addWidget( expressionLabel );
383 layout->addWidget( expressionEdit );
384 nameEdit->setFocus();
386 if ( dlg->exec() == QDialog::Accepted )
392 mFilterQuery->setValue( expressionEdit->
expression() );
394 storedFilterExpressionBoxInit();
398void QgsFeatureFilterWidget::updateCurrentStoredFilterExpression()
400 const QgsStoredExpression currentStoredExpression = mLayer->storedExpressionManager()->findStoredExpressionByExpression( mFilterQuery->value() );
403 mActionHandleStoreFilterExpression->setChecked( !currentStoredExpression.
id.isNull() );
405 mActionHandleStoreFilterExpression->setData( currentStoredExpression.
id );
406 mActionEditStoredFilterExpression->setData( currentStoredExpression.
id );
409 storeExpressionButtonInit();
412void QgsFeatureFilterWidget::setFilterExpression(
const QString &filterString,
QgsAttributeForm::FilterType type,
bool alwaysShowFilter )
415 if ( !mFilterQuery->text().isEmpty() && !filterString.isEmpty() )
420 filter = filterString;
424 filter = QStringLiteral(
"(%1) AND (%2)" ).arg( mFilterQuery->text(), filterString );
428 filter = QStringLiteral(
"(%1) OR (%2)" ).arg( mFilterQuery->text(), filterString );
432 else if ( !filterString.isEmpty() )
434 filter = filterString;
442 mFilterQuery->setText( filter );
444 if ( alwaysShowFilter || !mCurrentSearchWidgetWrapper || !mCurrentSearchWidgetWrapper->applyDirectly() )
446 mFilterButton->setDefaultAction( mActionAdvancedFilter );
447 mFilterButton->setPopupMode( QToolButton::MenuButtonPopup );
448 mFilterQuery->setVisible(
true );
449 mApplyFilterButton->setVisible(
true );
450 mStoreFilterExpressionButton->setVisible(
true );
451 if ( mCurrentSearchWidgetWrapper )
454 replaceSearchWidget( mCurrentSearchWidgetWrapper->widget(), mFilterQuery );
460 if ( filterExpression.hasParserError() )
468 if ( !filterExpression.prepare( &context ) )
473 mMainView->filterFeatures( filterExpression, context );
477void QgsFeatureFilterWidget::replaceSearchWidget( QWidget *oldw, QWidget *neww )
479 mFilterLayout->removeWidget( oldw );
480 oldw->setVisible(
false );
481 mFilterLayout->addWidget( neww, 0, 0 );
482 neww->setVisible(
true );
486void QgsFeatureFilterWidget::onFilterQueryTextChanged(
const QString &value )
489 mFilterQueryTimer.start( 300 );
@ Warning
Warning message.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
This class contains context information for attribute editor widgets.
@ ShowFilteredList
Show only features whose ids are on the filter list. {.
@ ShowVisible
Show only visible features (depends on the map canvas)
@ ShowSelected
Show only selected features.
@ ShowInvalid
Show only features not respecting constraints.
@ ShowEdited
Show only features which have unsaved changes.
@ ShowAll
Show all features.
A generic dialog with layout and button box.
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
This widget is used to show the attributes of a set of features of a QgsVectorLayer.
A generic dialog for building expression strings.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
The QgsExpressionLineEdit widget includes a line edit for entering expressions together with a button...
QString expression() const
Returns the current expression shown in the widget.
void setExpression(const QString &expression)
Sets the current expression to show in the widget.
Class for parsing and evaluation of expressions (formerly called "search strings").
Encapsulate a field in an attribute table or data source.
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
A bar for displaying non-blocking messages to the user.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsCoordinateTransformContext transformContext
Stored expression containing name, content (expression text) and a category tag.
@ FilterExpression
Expressions to filter features.
QString id
generated uuid used for identification
Represents a vector layer which manages a vector based data sets.
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer.
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.