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 );
 
   87  mEditorContext = context;
 
   88  mMessageBar = messageBar;
 
   94  mFilterQueryTimer.setSingleShot( 
true );
 
   95  connect( &mFilterQueryTimer, &QTimer::timeout, 
this, &QgsFeatureFilterWidget::updateCurrentStoredFilterExpression );
 
   98  storedFilterExpressionBoxInit();
 
   99  storeExpressionButtonInit();
 
  102void 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 );
 
  117void QgsFeatureFilterWidget::filterSelected()
 
  119  mFilterButton->setDefaultAction( mActionSelectedFilter );
 
  120  mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  121  mFilterQuery->setVisible( 
false );
 
  122  mApplyFilterButton->setVisible( 
false );
 
  123  mStoreFilterExpressionButton->setVisible( 
false );
 
  127void 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 );
 
  143void QgsFeatureFilterWidget::filterInvalid()
 
  145  mFilterButton->setDefaultAction( mActionInvalidFilter );
 
  146  mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  147  mFilterQuery->setVisible( 
false );
 
  148  mApplyFilterButton->setVisible( 
false );
 
  149  mStoreFilterExpressionButton->setVisible( 
false );
 
  151  mMainView->filterFeatures( QStringLiteral( 
"is_feature_valid() = false" ), context );
 
  155void QgsFeatureFilterWidget::filterEdited()
 
  157  mFilterButton->setDefaultAction( mActionEditedFilter );
 
  158  mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  159  mFilterQuery->setVisible( 
false );
 
  160  mApplyFilterButton->setVisible( 
false );
 
  161  mStoreFilterExpressionButton->setVisible( 
false );
 
  166void QgsFeatureFilterWidget::filterQueryAccepted()
 
  168  if ( ( mFilterQuery->isVisible() && mFilterQuery->text().isEmpty() ) ||
 
  169       ( mCurrentSearchWidgetWrapper && mCurrentSearchWidgetWrapper->widget()->isVisible()
 
  170         && mCurrentSearchWidgetWrapper->expression().isEmpty() ) )
 
  175  filterQueryChanged( mFilterQuery->text() );
 
  178void QgsFeatureFilterWidget::filterQueryChanged( 
const QString &query )
 
  181  if ( mFilterButton->defaultAction() == mActionAdvancedFilter )
 
  185  else if ( mCurrentSearchWidgetWrapper )
 
  187    str = mCurrentSearchWidgetWrapper->expression();
 
  190  setFilterExpression( 
str );
 
  193void QgsFeatureFilterWidget::columnBoxInit()
 
  195  const auto constActions = mFilterColumnsMenu->actions();
 
  196  for ( QAction *a : constActions )
 
  198    mFilterColumnsMenu->removeAction( a );
 
  199    mFilterButton->removeAction( a );
 
  203  mFilterButton->addAction( mActionShowAllFilter );
 
  204  mFilterButton->addAction( mActionSelectedFilter );
 
  205  if ( mLayer->isSpatial() )
 
  207    mFilterButton->addAction( mActionVisibleFilter );
 
  209  mFilterButton->addAction( mActionInvalidFilter );
 
  210  mFilterButton->addAction( mActionEditedFilter );
 
  211  mFilterButton->addAction( mActionFilterColumnsMenu );
 
  212  mFilterButton->addAction( mActionAdvancedFilter );
 
  213  mFilterButton->addAction( mActionStoredFilterExpressions );
 
  215  const QList<QgsField> fields = mLayer->fields().toList();
 
  217  const auto constFields = fields;
 
  218  for ( 
const QgsField &field : constFields )
 
  220    const int idx = mLayer->fields().lookupField( field.name() );
 
  226      const QIcon icon = mLayer->fields().iconForField( idx );
 
  227      const QString alias = mLayer->attributeDisplayName( idx );
 
  230      QAction *filterAction = 
new QAction( icon, alias, mFilterButton );
 
  231      filterAction->setData( field.name() );
 
  233      connect( filterAction, &QAction::triggered, 
this, [ = ] { filterColumnChanged( filterAction ); } );
 
  234      mFilterColumnsMenu->addAction( filterAction );
 
  239void QgsFeatureFilterWidget::handleStoreFilterExpression()
 
  241  if ( !mActionHandleStoreFilterExpression->isChecked() )
 
  243    mLayer->storedExpressionManager()->removeStoredExpression( mActionHandleStoreFilterExpression->data().toString() );
 
  247    mLayer->storedExpressionManager()->addStoredExpression( mFilterQuery->text(), mFilterQuery->text() );
 
  250  updateCurrentStoredFilterExpression();
 
  251  storedFilterExpressionBoxInit();
 
  254void QgsFeatureFilterWidget::storedFilterExpressionBoxInit()
 
  256  const auto constActions = mStoredFilterExpressionMenu->actions();
 
  257  for ( QAction *a : constActions )
 
  259    mStoredFilterExpressionMenu->removeAction( a );
 
  263  const QList< QgsStoredExpression > storedExpressions = mLayer->storedExpressionManager()->storedExpressions();
 
  266    QAction *storedExpressionAction = 
new QAction( storedExpression.name, mFilterButton );
 
  267    connect( storedExpressionAction, &QAction::triggered, 
this, [ = ]()
 
  271    mStoredFilterExpressionMenu->addAction( storedExpressionAction );
 
  275void QgsFeatureFilterWidget::storeExpressionButtonInit()
 
  277  if ( mActionHandleStoreFilterExpression->isChecked() )
 
  279    mActionHandleStoreFilterExpression->setToolTip( tr( 
"Delete stored expression" ) );
 
  280    mActionHandleStoreFilterExpression->setText( tr( 
"Delete Stored Expression" ) );
 
  281    mActionHandleStoreFilterExpression->setIcon( 
QgsApplication::getThemeIcon( QStringLiteral( 
"mActionHandleStoreFilterExpressionChecked.svg" ) ) );
 
  282    mStoreFilterExpressionButton->removeAction( mActionSaveAsStoredFilterExpression );
 
  283    mStoreFilterExpressionButton->addAction( mActionEditStoredFilterExpression );
 
  287    mActionHandleStoreFilterExpression->setToolTip( tr( 
"Save expression with the text as name" ) );
 
  288    mActionHandleStoreFilterExpression->setText( tr( 
"Save Expression" ) );
 
  289    mActionHandleStoreFilterExpression->setIcon( 
QgsApplication::getThemeIcon( QStringLiteral( 
"mActionHandleStoreFilterExpressionUnchecked.svg" ) ) );
 
  290    mStoreFilterExpressionButton->addAction( mActionSaveAsStoredFilterExpression );
 
  291    mStoreFilterExpressionButton->removeAction( mActionEditStoredFilterExpression );
 
  296void QgsFeatureFilterWidget::filterColumnChanged( QAction *filterAction )
 
  298  mFilterButton->setDefaultAction( filterAction );
 
  299  mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  302  if ( mCurrentSearchWidgetWrapper )
 
  304    mCurrentSearchWidgetWrapper->widget()->setVisible( 
false );
 
  305    delete mCurrentSearchWidgetWrapper;
 
  307  const QString fieldName = mFilterButton->defaultAction()->data().toString();
 
  309  const int fldIdx = mLayer->fields().lookupField( fieldName );
 
  314                                createSearchWidget( setup.
type(), mLayer, fldIdx, setup.
config(), mFilterContainer, mEditorContext );
 
  315  if ( mCurrentSearchWidgetWrapper->applyDirectly() )
 
  318    mApplyFilterButton->setVisible( 
false );
 
  319    mStoreFilterExpressionButton->setVisible( 
false );
 
  324    mApplyFilterButton->setVisible( 
true );
 
  325    mStoreFilterExpressionButton->setVisible( 
true );
 
  328  replaceSearchWidget( mFilterQuery, mCurrentSearchWidgetWrapper->widget() );
 
  331void QgsFeatureFilterWidget::filterExpressionBuilder()
 
  337  dlg.setWindowTitle( tr( 
"Expression Based Filter" ) );
 
  342  dlg.setGeomCalculator( myDa );
 
  344  if ( dlg.exec() == QDialog::Accepted )
 
  350void QgsFeatureFilterWidget::saveAsStoredFilterExpression()
 
  352  QgsDialog *dlg = 
new QgsDialog( 
this, Qt::WindowFlags(), QDialogButtonBox::Save | QDialogButtonBox::Cancel );
 
  353  dlg->setWindowTitle( tr( 
"Save Expression As" ) );
 
  354  QVBoxLayout *layout = dlg->
layout();
 
  355  dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
 
  357  QLabel *nameLabel = 
new QLabel( tr( 
"Name" ), dlg );
 
  358  QLineEdit *nameEdit = 
new QLineEdit( dlg );
 
  359  layout->addWidget( nameLabel );
 
  360  layout->addWidget( nameEdit );
 
  361  nameEdit->setFocus();
 
  363  if ( dlg->exec() == QDialog::Accepted )
 
  365    mLayer->storedExpressionManager()->addStoredExpression( nameEdit->text(), mFilterQuery->text() );
 
  367    updateCurrentStoredFilterExpression();
 
  368    storedFilterExpressionBoxInit();
 
  372void QgsFeatureFilterWidget::editStoredFilterExpression()
 
  374  QgsDialog *dlg = 
new QgsDialog( 
this, Qt::WindowFlags(), QDialogButtonBox::Save | QDialogButtonBox::Cancel );
 
  375  dlg->setWindowTitle( tr( 
"Edit expression" ) );
 
  376  QVBoxLayout *layout = dlg->
layout();
 
  377  dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
 
  379  QLabel *nameLabel = 
new QLabel( tr( 
"Name" ), dlg );
 
  380  QLineEdit *nameEdit = 
new QLineEdit( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).name, dlg );
 
  381  QLabel *expressionLabel = 
new QLabel( tr( 
"Expression" ), dlg );
 
  383  expressionEdit->
setExpression( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).expression );
 
  385  layout->addWidget( nameLabel );
 
  386  layout->addWidget( nameEdit );
 
  387  layout->addWidget( expressionLabel );
 
  388  layout->addWidget( expressionEdit );
 
  389  nameEdit->setFocus();
 
  391  if ( dlg->exec() == QDialog::Accepted )
 
  397    mFilterQuery->setValue( expressionEdit->
expression() );
 
  399    storedFilterExpressionBoxInit();
 
  403void QgsFeatureFilterWidget::updateCurrentStoredFilterExpression()
 
  405  const QgsStoredExpression currentStoredExpression = mLayer->storedExpressionManager()->findStoredExpressionByExpression( mFilterQuery->value() );
 
  408  mActionHandleStoreFilterExpression->setChecked( !currentStoredExpression.
id.isNull() );
 
  410  mActionHandleStoreFilterExpression->setData( currentStoredExpression.
id );
 
  411  mActionEditStoredFilterExpression->setData( currentStoredExpression.
id );
 
  414  storeExpressionButtonInit();
 
  417void QgsFeatureFilterWidget::setFilterExpression( 
const QString &filterString, 
QgsAttributeForm::FilterType type, 
bool alwaysShowFilter )
 
  420  if ( !mFilterQuery->text().isEmpty() && !filterString.isEmpty() )
 
  425        filter = filterString;
 
  429        filter = QStringLiteral( 
"(%1) AND (%2)" ).arg( mFilterQuery->text(), filterString );
 
  433        filter = QStringLiteral( 
"(%1) OR (%2)" ).arg( mFilterQuery->text(), filterString );
 
  437  else if ( !filterString.isEmpty() )
 
  439    filter = filterString;
 
  447  mFilterQuery->setText( filter );
 
  449  if ( alwaysShowFilter || !mCurrentSearchWidgetWrapper || !mCurrentSearchWidgetWrapper->applyDirectly() )
 
  452    mFilterButton->setDefaultAction( mActionAdvancedFilter );
 
  453    mFilterButton->setPopupMode( QToolButton::MenuButtonPopup );
 
  454    mFilterQuery->setVisible( 
true );
 
  455    mApplyFilterButton->setVisible( 
true );
 
  456    mStoreFilterExpressionButton->setVisible( 
true );
 
  457    if ( mCurrentSearchWidgetWrapper )
 
  460      replaceSearchWidget( mCurrentSearchWidgetWrapper->widget(), mFilterQuery );
 
  466  if ( filterExpression.hasParserError() )
 
  474  if ( !filterExpression.prepare( &context ) )
 
  479  mMainView->filterFeatures( filterExpression, context );
 
  483void QgsFeatureFilterWidget::replaceSearchWidget( QWidget *oldw, QWidget *neww )
 
  485  mFilterLayout->removeWidget( oldw );
 
  486  oldw->setVisible( 
false );
 
  487  mFilterLayout->addWidget( neww, 0, 0 );
 
  488  neww->setVisible( 
true );
 
  492void QgsFeatureFilterWidget::onFilterQueryTextChanged( 
const QString &value )
 
  495  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 (since QGIS 3.30)
 
@ 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.