43 QgsFeatureFilterWidget::QgsFeatureFilterWidget( QWidget *parent )
    49   mFilterColumnsMenu = 
new QMenu( 
this );
    50   mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu );
    51   mStoredFilterExpressionMenu = 
new QMenu( 
this );
    52   mActionStoredFilterExpressions->setMenu( mStoredFilterExpressionMenu );
    56   mActionShowAllFilter->setIcon( filterIcon );
    57   mActionAdvancedFilter->setIcon( filterIcon );
    58   mActionSelectedFilter->setIcon( filterIcon );
    59   mActionVisibleFilter->setIcon( filterIcon );
    60   mActionEditedFilter->setIcon( filterIcon );
    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( mActionVisibleFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterVisible );
    75   connect( mActionEditedFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterEdited );
    76   connect( mFilterQuery, &QLineEdit::returnPressed, 
this, &QgsFeatureFilterWidget::filterQueryAccepted );
    77   connect( mActionApplyFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterQueryAccepted );
    78   connect( mFilterQuery, &QLineEdit::textChanged, 
this, &QgsFeatureFilterWidget::onFilterQueryTextChanged );
    86   mEditorContext = context;
    87   mMessageBar = messageBar;
    88   mMessageBarTimeout = messageBarTimeout;
    94   mFilterQueryTimer.setSingleShot( 
true );
    95   connect( &mFilterQueryTimer, &QTimer::timeout, 
this, &QgsFeatureFilterWidget::updateCurrentStoredFilterExpression );
    98   storedFilterExpressionBoxInit();
    99   storeExpressionButtonInit();
   102 void QgsFeatureFilterWidget::filterShowAll()
   104   mFilterButton->setDefaultAction( mActionShowAllFilter );
   105   mFilterButton->setPopupMode( QToolButton::InstantPopup );
   106   mFilterQuery->setVisible( 
false );
   107   mFilterQuery->setText( QString() );
   108   if ( mCurrentSearchWidgetWrapper )
   110     mCurrentSearchWidgetWrapper->widget()->setVisible( 
false );
   112   mApplyFilterButton->setVisible( 
false );
   113   mStoreFilterExpressionButton->setVisible( 
false );
   117 void QgsFeatureFilterWidget::filterSelected()
   119   mFilterButton->setDefaultAction( mActionSelectedFilter );
   120   mFilterButton->setPopupMode( QToolButton::InstantPopup );
   121   mFilterQuery->setVisible( 
false );
   122   mApplyFilterButton->setVisible( 
false );
   123   mStoreFilterExpressionButton->setVisible( 
false );
   127 void QgsFeatureFilterWidget::filterVisible()
   129   if ( !mLayer->isSpatial() )
   135   mFilterButton->setDefaultAction( mActionVisibleFilter );
   136   mFilterButton->setPopupMode( QToolButton::InstantPopup );
   137   mFilterQuery->setVisible( 
false );
   138   mApplyFilterButton->setVisible( 
false );
   139   mStoreFilterExpressionButton->setVisible( 
false );
   143 void QgsFeatureFilterWidget::filterEdited()
   145   mFilterButton->setDefaultAction( mActionEditedFilter );
   146   mFilterButton->setPopupMode( QToolButton::InstantPopup );
   147   mFilterQuery->setVisible( 
false );
   148   mApplyFilterButton->setVisible( 
false );
   149   mStoreFilterExpressionButton->setVisible( 
false );
   154 void QgsFeatureFilterWidget::filterQueryAccepted()
   156   if ( ( mFilterQuery->isVisible() && mFilterQuery->text().isEmpty() ) ||
   157        ( mCurrentSearchWidgetWrapper && mCurrentSearchWidgetWrapper->widget()->isVisible()
   158          && mCurrentSearchWidgetWrapper->expression().isEmpty() ) )
   163   filterQueryChanged( mFilterQuery->text() );
   166 void QgsFeatureFilterWidget::filterQueryChanged( 
const QString &query )
   169   if ( mFilterButton->defaultAction() == mActionAdvancedFilter )
   173   else if ( mCurrentSearchWidgetWrapper )
   175     str = mCurrentSearchWidgetWrapper->expression();
   178   setFilterExpression( str );
   181 void QgsFeatureFilterWidget::columnBoxInit()
   183   const auto constActions = mFilterColumnsMenu->actions();
   184   for ( QAction *a : constActions )
   186     mFilterColumnsMenu->removeAction( a );
   187     mFilterButton->removeAction( a );
   191   mFilterButton->addAction( mActionShowAllFilter );
   192   mFilterButton->addAction( mActionSelectedFilter );
   193   if ( mLayer->isSpatial() )
   195     mFilterButton->addAction( mActionVisibleFilter );
   197   mFilterButton->addAction( mActionEditedFilter );
   198   mFilterButton->addAction( mActionFilterColumnsMenu );
   199   mFilterButton->addAction( mActionAdvancedFilter );
   200   mFilterButton->addAction( mActionStoredFilterExpressions );
   202   const QList<QgsField> fields = mLayer->fields().toList();
   204   const auto constFields = fields;
   205   for ( 
const QgsField &field : constFields )
   207     int idx = mLayer->fields().lookupField( field.name() );
   213       QIcon icon = mLayer->fields().iconForField( idx );
   214       QString alias = mLayer->attributeDisplayName( idx );
   217       QAction *filterAction = 
new QAction( icon, alias, mFilterButton );
   218       filterAction->setData( field.name() );
   220       connect( filterAction, &QAction::triggered, 
this, [ = ] { filterColumnChanged( filterAction ); } );
   221       mFilterColumnsMenu->addAction( filterAction );
   226 void QgsFeatureFilterWidget::handleStoreFilterExpression()
   228   if ( !mActionHandleStoreFilterExpression->isChecked() )
   230     mLayer->storedExpressionManager()->removeStoredExpression( mActionHandleStoreFilterExpression->data().toString() );
   234     mLayer->storedExpressionManager()->addStoredExpression( mFilterQuery->text(), mFilterQuery->text() );
   237   updateCurrentStoredFilterExpression();
   238   storedFilterExpressionBoxInit();
   241 void QgsFeatureFilterWidget::storedFilterExpressionBoxInit()
   243   const auto constActions = mStoredFilterExpressionMenu->actions();
   244   for ( QAction *a : constActions )
   246     mStoredFilterExpressionMenu->removeAction( a );
   250   const QList< QgsStoredExpression > storedExpressions = mLayer->storedExpressionManager()->storedExpressions();
   253     QAction *storedExpressionAction = 
new QAction( storedExpression.name, mFilterButton );
   254     connect( storedExpressionAction, &QAction::triggered, 
this, [ = ]()
   258     mStoredFilterExpressionMenu->addAction( storedExpressionAction );
   262 void QgsFeatureFilterWidget::storeExpressionButtonInit()
   264   if ( mActionHandleStoreFilterExpression->isChecked() )
   266     mActionHandleStoreFilterExpression->setToolTip( tr( 
"Delete stored expression" ) );
   267     mActionHandleStoreFilterExpression->setText( tr( 
"Delete Stored Expression" ) );
   268     mActionHandleStoreFilterExpression->setIcon( 
QgsApplication::getThemeIcon( QStringLiteral( 
"mActionHandleStoreFilterExpressionChecked.svg" ) ) );
   269     mStoreFilterExpressionButton->removeAction( mActionSaveAsStoredFilterExpression );
   270     mStoreFilterExpressionButton->addAction( mActionEditStoredFilterExpression );
   274     mActionHandleStoreFilterExpression->setToolTip( tr( 
"Save expression with the text as name" ) );
   275     mActionHandleStoreFilterExpression->setText( tr( 
"Save Expression" ) );
   276     mActionHandleStoreFilterExpression->setIcon( 
QgsApplication::getThemeIcon( QStringLiteral( 
"mActionHandleStoreFilterExpressionUnchecked.svg" ) ) );
   277     mStoreFilterExpressionButton->addAction( mActionSaveAsStoredFilterExpression );
   278     mStoreFilterExpressionButton->removeAction( mActionEditStoredFilterExpression );
   283 void QgsFeatureFilterWidget::filterColumnChanged( QAction *filterAction )
   285   mFilterButton->setDefaultAction( filterAction );
   286   mFilterButton->setPopupMode( QToolButton::InstantPopup );
   289   if ( mCurrentSearchWidgetWrapper )
   291     mCurrentSearchWidgetWrapper->widget()->setVisible( 
false );
   292     delete mCurrentSearchWidgetWrapper;
   294   QString fieldName = mFilterButton->defaultAction()->data().toString();
   296   int fldIdx = mLayer->fields().lookupField( fieldName );
   301                                 createSearchWidget( setup.
type(), mLayer, fldIdx, setup.
config(), mFilterContainer, mEditorContext );
   302   if ( mCurrentSearchWidgetWrapper->applyDirectly() )
   305     mApplyFilterButton->setVisible( 
false );
   306     mStoreFilterExpressionButton->setVisible( 
false );
   311     mApplyFilterButton->setVisible( 
true );
   312     mStoreFilterExpressionButton->setVisible( 
true );
   315   replaceSearchWidget( mFilterQuery, mCurrentSearchWidgetWrapper->widget() );
   318 void QgsFeatureFilterWidget::filterExpressionBuilder()
   324   dlg.setWindowTitle( tr( 
"Expression Based Filter" ) );
   329   dlg.setGeomCalculator( myDa );
   331   if ( dlg.exec() == QDialog::Accepted )
   337 void QgsFeatureFilterWidget::saveAsStoredFilterExpression()
   339   QgsDialog *dlg = 
new QgsDialog( 
this, 
nullptr, QDialogButtonBox::Save | QDialogButtonBox::Cancel );
   340   dlg->setWindowTitle( tr( 
"Save Expression As" ) );
   341   QVBoxLayout *layout = dlg->
layout();
   342   dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
   344   QLabel *nameLabel = 
new QLabel( tr( 
"Name" ), dlg );
   345   QLineEdit *nameEdit = 
new QLineEdit( dlg );
   346   layout->addWidget( nameLabel );
   347   layout->addWidget( nameEdit );
   349   if ( dlg->exec() == QDialog::Accepted )
   351     mLayer->storedExpressionManager()->addStoredExpression( nameEdit->text(), mFilterQuery->text() );
   353     updateCurrentStoredFilterExpression();
   354     storedFilterExpressionBoxInit();
   358 void QgsFeatureFilterWidget::editStoredFilterExpression()
   360   QgsDialog *dlg = 
new QgsDialog( 
this, 
nullptr, QDialogButtonBox::Save | QDialogButtonBox::Cancel );
   361   dlg->setWindowTitle( tr( 
"Edit expression" ) );
   362   QVBoxLayout *layout = dlg->
layout();
   363   dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
   365   QLabel *nameLabel = 
new QLabel( tr( 
"Name" ), dlg );
   366   QLineEdit *nameEdit = 
new QLineEdit( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).name, dlg );
   367   QLabel *expressionLabel = 
new QLabel( tr( 
"Expression" ), dlg );
   369   expressionEdit->
setExpression( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).expression );
   371   layout->addWidget( nameLabel );
   372   layout->addWidget( nameEdit );
   373   layout->addWidget( expressionLabel );
   374   layout->addWidget( expressionEdit );
   376   if ( dlg->exec() == QDialog::Accepted )
   379     mLayer->storedExpressionManager()->updateStoredExpression( mActionHandleStoreFilterExpression->data().toString(), nameEdit->text(), expressionEdit->
expression(), QgsStoredExpression::Category::FilterExpression );
   382     mFilterQuery->setValue( expressionEdit->
expression() );
   384     storedFilterExpressionBoxInit();
   388 void QgsFeatureFilterWidget::updateCurrentStoredFilterExpression()
   390   QgsStoredExpression currentStoredExpression = mLayer->storedExpressionManager()->findStoredExpressionByExpression( mFilterQuery->value() );
   393   mActionHandleStoreFilterExpression->setChecked( !currentStoredExpression.
id.isNull() );
   395   mActionHandleStoreFilterExpression->setData( currentStoredExpression.
id );
   396   mActionEditStoredFilterExpression->setData( currentStoredExpression.
id );
   399   storeExpressionButtonInit();
   402 void QgsFeatureFilterWidget::setFilterExpression( 
const QString &filterString, 
QgsAttributeForm::FilterType type, 
bool alwaysShowFilter )
   405   if ( !mFilterQuery->text().isEmpty() && !filterString.isEmpty() )
   410         filter = filterString;
   414         filter = QStringLiteral( 
"(%1) AND (%2)" ).arg( mFilterQuery->text(), filterString );
   418         filter = QStringLiteral( 
"(%1) OR (%2)" ).arg( mFilterQuery->text(), filterString );
   422   else if ( !filterString.isEmpty() )
   424     filter = filterString;
   432   mFilterQuery->setText( filter );
   434   if ( alwaysShowFilter || !mCurrentSearchWidgetWrapper || !mCurrentSearchWidgetWrapper->applyDirectly() )
   437     mFilterButton->setDefaultAction( mActionAdvancedFilter );
   438     mFilterButton->setPopupMode( QToolButton::MenuButtonPopup );
   439     mFilterQuery->setVisible( 
true );
   440     mApplyFilterButton->setVisible( 
true );
   441     mStoreFilterExpressionButton->setVisible( 
true );
   442     if ( mCurrentSearchWidgetWrapper )
   445       replaceSearchWidget( mCurrentSearchWidgetWrapper->widget(), mFilterQuery );
   457   if ( filterExpression.hasParserError() )
   459     mMessageBar->pushMessage( tr( 
"Parsing error" ), filterExpression.parserErrorString(), 
Qgis::Warning, mMessageBarTimeout );
   465   if ( !filterExpression.prepare( &context ) )
   467     mMessageBar->pushMessage( tr( 
"Evaluation error" ), filterExpression.evalErrorString(), 
Qgis::Warning, mMessageBarTimeout );
   470   bool fetchGeom = filterExpression.needsGeometry();
   472   QApplication::setOverrideCursor( Qt::WaitCursor );
   474   filterExpression.setGeomCalculator( &myDa );
   494     context.setFeature( f );
   495     if ( filterExpression.evaluate( &context ).toInt() != 0 )
   496       filteredFeatures << f.
id();
   499     if ( filterExpression.hasEvalError() )
   505   mMainView->setFilteredFeatures( filteredFeatures );
   507   QApplication::restoreOverrideCursor();
   509   if ( filterExpression.hasEvalError() )
   511     mMessageBar->pushMessage( tr( 
"Error filtering" ), filterExpression.evalErrorString(), 
Qgis::Warning, mMessageBarTimeout );
   517 void QgsFeatureFilterWidget::replaceSearchWidget( QWidget *oldw, QWidget *neww )
   519   mFilterLayout->removeWidget( oldw );
   520   oldw->setVisible( 
false );
   521   mFilterLayout->addWidget( neww, 0, 0, 
nullptr );
   522   neww->setVisible( 
true );
   526 void QgsFeatureFilterWidget::onFilterQueryTextChanged( 
const QString &value )
   529   mFilterQueryTimer.start( 300 );
 Class for parsing and evaluation of expressions (formerly called "search strings"). 
 
Wrapper for iterator of features from vector data provider or vector layer. 
 
QSet< QgsFeatureId > QgsFeatureIds
 
This class contains context information for attribute editor widgets. 
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched. 
 
A generic dialog with layout and button box. 
 
A bar for displaying non-blocking messages to the user. 
 
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon. 
 
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
Show only visible features (depends on the map canvas) 
 
Show only selected features. 
 
void setExpression(const QString &expression)
Sets the current expression to show in the widget. 
 
QString expression() const
Returns the current expression shown in the widget. 
 
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories...
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
This class wraps a request for features to a vector layer (or directly its vector data provider)...
 
QString id
generated uuid used for identification 
 
Show only features which have unsaved changes. 
 
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer. 
 
Encapsulate a field in an attribute table or data source. 
 
Show only features whose ids are on the filter list. {. 
 
QgsCoordinateTransformContext transformContext
 
A general purpose distance and area calculator, capable of performing ellipsoid based calculations...
 
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer. 
 
The QgsExpressionLineEdit widget includes a line edit for entering expressions together with a button...
 
static QgsProject * instance()
Returns the QgsProject singleton instance. 
 
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent. 
 
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs. 
 
bool nextFeature(QgsFeature &f)
 
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer. 
 
Geometry is not required. It may still be returned if e.g. required for a filter condition. 
 
Represents a vector layer which manages a vector based data sets. 
 
Stored expression containing name, content (expression text) and a category tag. 
 
A generic dialog for building expression strings. 
 
This widget is used to show the attributes of a set of features of a QgsVectorLayer. 
 
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.