43 QgsFeatureFilterWidget::QgsFeatureFilterWidget( QWidget *parent )
 
   49   mFilterColumnsMenu = 
new QMenu( 
this );
 
   50   mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu );
 
   51   mStoredFilterExpressionMenu = 
new QMenu( 
this );
 
   52   mActionStoredFilterExpressions->setMenu( mStoredFilterExpressionMenu );
 
   63   mStoreFilterExpressionButton->setDefaultAction( mActionHandleStoreFilterExpression );
 
   64   connect( mActionSaveAsStoredFilterExpression, &QAction::triggered, 
this, &QgsFeatureFilterWidget::saveAsStoredFilterExpression );
 
   65   connect( mActionEditStoredFilterExpression, &QAction::triggered, 
this, &QgsFeatureFilterWidget::editStoredFilterExpression );
 
   66   connect( mActionHandleStoreFilterExpression, &QAction::triggered, 
this, &QgsFeatureFilterWidget::handleStoreFilterExpression );
 
   67   mApplyFilterButton->setDefaultAction( mActionApplyFilter );
 
   70   connect( mActionAdvancedFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterExpressionBuilder );
 
   71   connect( mActionShowAllFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterShowAll );
 
   72   connect( mActionSelectedFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterSelected );
 
   73   connect( mActionVisibleFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterVisible );
 
   74   connect( mActionEditedFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterEdited );
 
   75   connect( mFilterQuery, &QLineEdit::returnPressed, 
this, &QgsFeatureFilterWidget::filterQueryAccepted );
 
   76   connect( mActionApplyFilter, &QAction::triggered, 
this, &QgsFeatureFilterWidget::filterQueryAccepted );
 
   77   connect( mFilterQuery, &QLineEdit::textChanged, 
this, &QgsFeatureFilterWidget::onFilterQueryTextChanged );
 
   85   mEditorContext = context;
 
   86   mMessageBar = messageBar;
 
   92   mFilterQueryTimer.setSingleShot( 
true );
 
   93   connect( &mFilterQueryTimer, &QTimer::timeout, 
this, &QgsFeatureFilterWidget::updateCurrentStoredFilterExpression );
 
   96   storedFilterExpressionBoxInit();
 
   97   storeExpressionButtonInit();
 
  100 void QgsFeatureFilterWidget::filterShowAll()
 
  102   mFilterButton->setDefaultAction( mActionShowAllFilter );
 
  103   mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  104   mFilterQuery->setVisible( 
false );
 
  105   mFilterQuery->setText( QString() );
 
  106   if ( mCurrentSearchWidgetWrapper )
 
  108     mCurrentSearchWidgetWrapper->widget()->setVisible( 
false );
 
  110   mApplyFilterButton->setVisible( 
false );
 
  111   mStoreFilterExpressionButton->setVisible( 
false );
 
  115 void QgsFeatureFilterWidget::filterSelected()
 
  117   mFilterButton->setDefaultAction( mActionSelectedFilter );
 
  118   mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  119   mFilterQuery->setVisible( 
false );
 
  120   mApplyFilterButton->setVisible( 
false );
 
  121   mStoreFilterExpressionButton->setVisible( 
false );
 
  125 void QgsFeatureFilterWidget::filterVisible()
 
  127   if ( !mLayer->isSpatial() )
 
  133   mFilterButton->setDefaultAction( mActionVisibleFilter );
 
  134   mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  135   mFilterQuery->setVisible( 
false );
 
  136   mApplyFilterButton->setVisible( 
false );
 
  137   mStoreFilterExpressionButton->setVisible( 
false );
 
  141 void QgsFeatureFilterWidget::filterEdited()
 
  143   mFilterButton->setDefaultAction( mActionEditedFilter );
 
  144   mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  145   mFilterQuery->setVisible( 
false );
 
  146   mApplyFilterButton->setVisible( 
false );
 
  147   mStoreFilterExpressionButton->setVisible( 
false );
 
  152 void QgsFeatureFilterWidget::filterQueryAccepted()
 
  154   if ( ( mFilterQuery->isVisible() && mFilterQuery->text().isEmpty() ) ||
 
  155        ( mCurrentSearchWidgetWrapper && mCurrentSearchWidgetWrapper->widget()->isVisible()
 
  156          && mCurrentSearchWidgetWrapper->expression().isEmpty() ) )
 
  161   filterQueryChanged( mFilterQuery->text() );
 
  164 void QgsFeatureFilterWidget::filterQueryChanged( 
const QString &query )
 
  167   if ( mFilterButton->defaultAction() == mActionAdvancedFilter )
 
  171   else if ( mCurrentSearchWidgetWrapper )
 
  173     str = mCurrentSearchWidgetWrapper->expression();
 
  176   setFilterExpression( 
str );
 
  179 void QgsFeatureFilterWidget::columnBoxInit()
 
  181   const auto constActions = mFilterColumnsMenu->actions();
 
  182   for ( QAction *a : constActions )
 
  184     mFilterColumnsMenu->removeAction( a );
 
  185     mFilterButton->removeAction( a );
 
  189   mFilterButton->addAction( mActionShowAllFilter );
 
  190   mFilterButton->addAction( mActionSelectedFilter );
 
  191   if ( mLayer->isSpatial() )
 
  193     mFilterButton->addAction( mActionVisibleFilter );
 
  195   mFilterButton->addAction( mActionEditedFilter );
 
  196   mFilterButton->addAction( mActionFilterColumnsMenu );
 
  197   mFilterButton->addAction( mActionAdvancedFilter );
 
  198   mFilterButton->addAction( mActionStoredFilterExpressions );
 
  200   const QList<QgsField> fields = mLayer->fields().toList();
 
  202   const auto constFields = fields;
 
  205     int idx = mLayer->fields().lookupField( 
field.
name() );
 
  211       QIcon icon = mLayer->fields().iconForField( idx );
 
  212       QString alias = mLayer->attributeDisplayName( idx );
 
  215       QAction *filterAction = 
new QAction( icon, alias, mFilterButton );
 
  218       connect( filterAction, &QAction::triggered, 
this, [ = ] { filterColumnChanged( filterAction ); } );
 
  219       mFilterColumnsMenu->addAction( filterAction );
 
  224 void QgsFeatureFilterWidget::handleStoreFilterExpression()
 
  226   if ( !mActionHandleStoreFilterExpression->isChecked() )
 
  228     mLayer->storedExpressionManager()->removeStoredExpression( mActionHandleStoreFilterExpression->data().toString() );
 
  232     mLayer->storedExpressionManager()->addStoredExpression( mFilterQuery->text(), mFilterQuery->text() );
 
  235   updateCurrentStoredFilterExpression();
 
  236   storedFilterExpressionBoxInit();
 
  239 void QgsFeatureFilterWidget::storedFilterExpressionBoxInit()
 
  241   const auto constActions = mStoredFilterExpressionMenu->actions();
 
  242   for ( QAction *a : constActions )
 
  244     mStoredFilterExpressionMenu->removeAction( a );
 
  248   const QList< QgsStoredExpression > storedExpressions = mLayer->storedExpressionManager()->storedExpressions();
 
  251     QAction *storedExpressionAction = 
new QAction( storedExpression.name, mFilterButton );
 
  252     connect( storedExpressionAction, &QAction::triggered, 
this, [ = ]()
 
  256     mStoredFilterExpressionMenu->addAction( storedExpressionAction );
 
  260 void QgsFeatureFilterWidget::storeExpressionButtonInit()
 
  262   if ( mActionHandleStoreFilterExpression->isChecked() )
 
  264     mActionHandleStoreFilterExpression->setToolTip( tr( 
"Delete stored expression" ) );
 
  265     mActionHandleStoreFilterExpression->setText( tr( 
"Delete Stored Expression" ) );
 
  266     mActionHandleStoreFilterExpression->setIcon( 
QgsApplication::getThemeIcon( QStringLiteral( 
"mActionHandleStoreFilterExpressionChecked.svg" ) ) );
 
  267     mStoreFilterExpressionButton->removeAction( mActionSaveAsStoredFilterExpression );
 
  268     mStoreFilterExpressionButton->addAction( mActionEditStoredFilterExpression );
 
  272     mActionHandleStoreFilterExpression->setToolTip( tr( 
"Save expression with the text as name" ) );
 
  273     mActionHandleStoreFilterExpression->setText( tr( 
"Save Expression" ) );
 
  274     mActionHandleStoreFilterExpression->setIcon( 
QgsApplication::getThemeIcon( QStringLiteral( 
"mActionHandleStoreFilterExpressionUnchecked.svg" ) ) );
 
  275     mStoreFilterExpressionButton->addAction( mActionSaveAsStoredFilterExpression );
 
  276     mStoreFilterExpressionButton->removeAction( mActionEditStoredFilterExpression );
 
  281 void QgsFeatureFilterWidget::filterColumnChanged( QAction *filterAction )
 
  283   mFilterButton->setDefaultAction( filterAction );
 
  284   mFilterButton->setPopupMode( QToolButton::InstantPopup );
 
  287   if ( mCurrentSearchWidgetWrapper )
 
  289     mCurrentSearchWidgetWrapper->widget()->setVisible( 
false );
 
  290     delete mCurrentSearchWidgetWrapper;
 
  292   QString fieldName = mFilterButton->defaultAction()->data().toString();
 
  294   int fldIdx = mLayer->fields().lookupField( fieldName );
 
  299                                 createSearchWidget( setup.
type(), mLayer, fldIdx, setup.
config(), mFilterContainer, mEditorContext );
 
  300   if ( mCurrentSearchWidgetWrapper->applyDirectly() )
 
  303     mApplyFilterButton->setVisible( 
false );
 
  304     mStoreFilterExpressionButton->setVisible( 
false );
 
  309     mApplyFilterButton->setVisible( 
true );
 
  310     mStoreFilterExpressionButton->setVisible( 
true );
 
  313   replaceSearchWidget( mFilterQuery, mCurrentSearchWidgetWrapper->widget() );
 
  316 void QgsFeatureFilterWidget::filterExpressionBuilder()
 
  322   dlg.setWindowTitle( tr( 
"Expression Based Filter" ) );
 
  327   dlg.setGeomCalculator( myDa );
 
  329   if ( dlg.exec() == QDialog::Accepted )
 
  335 void QgsFeatureFilterWidget::saveAsStoredFilterExpression()
 
  337   QgsDialog *dlg = 
new QgsDialog( 
this, Qt::WindowFlags(), QDialogButtonBox::Save | QDialogButtonBox::Cancel );
 
  338   dlg->setWindowTitle( tr( 
"Save Expression As" ) );
 
  339   QVBoxLayout *layout = dlg->
layout();
 
  340   dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
 
  342   QLabel *nameLabel = 
new QLabel( tr( 
"Name" ), dlg );
 
  343   QLineEdit *nameEdit = 
new QLineEdit( dlg );
 
  344   layout->addWidget( nameLabel );
 
  345   layout->addWidget( nameEdit );
 
  346   nameEdit->setFocus();
 
  348   if ( dlg->exec() == QDialog::Accepted )
 
  350     mLayer->storedExpressionManager()->addStoredExpression( nameEdit->text(), mFilterQuery->text() );
 
  352     updateCurrentStoredFilterExpression();
 
  353     storedFilterExpressionBoxInit();
 
  357 void QgsFeatureFilterWidget::editStoredFilterExpression()
 
  359   QgsDialog *dlg = 
new QgsDialog( 
this, Qt::WindowFlags(), QDialogButtonBox::Save | QDialogButtonBox::Cancel );
 
  360   dlg->setWindowTitle( tr( 
"Edit expression" ) );
 
  361   QVBoxLayout *layout = dlg->
layout();
 
  362   dlg->resize( std::max( 400, this->width() / 2 ), dlg->height() );
 
  364   QLabel *nameLabel = 
new QLabel( tr( 
"Name" ), dlg );
 
  365   QLineEdit *nameEdit = 
new QLineEdit( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).name, dlg );
 
  366   QLabel *expressionLabel = 
new QLabel( tr( 
"Expression" ), dlg );
 
  368   expressionEdit->
setExpression( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).expression );
 
  370   layout->addWidget( nameLabel );
 
  371   layout->addWidget( nameEdit );
 
  372   layout->addWidget( expressionLabel );
 
  373   layout->addWidget( expressionEdit );
 
  374   nameEdit->setFocus();
 
  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 );
 
  451   if ( filterExpression.hasParserError() )
 
  453     mMessageBar->pushMessage( tr( 
"Parsing error" ), filterExpression.parserErrorString(), Qgis::MessageLevel::Warning );
 
  459   if ( !filterExpression.prepare( &context ) )
 
  461     mMessageBar->pushMessage( tr( 
"Evaluation error" ), filterExpression.evalErrorString(), Qgis::MessageLevel::Warning );
 
  464   mMainView->filterFeatures( filterExpression, context );
 
  469 void QgsFeatureFilterWidget::replaceSearchWidget( QWidget *oldw, QWidget *neww )
 
  471   mFilterLayout->removeWidget( oldw );
 
  472   oldw->setVisible( 
false );
 
  473   mFilterLayout->addWidget( neww, 0, 0 );
 
  474   neww->setVisible( 
true );
 
  478 void QgsFeatureFilterWidget::onFilterQueryTextChanged( 
const QString &value )
 
  481   mFilterQueryTimer.start( 300 );
 
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.
@ 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
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.
Stored expression containing name, content (expression text) and a category tag.
QString id
generated uuid used for identification