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 const int idx = mLayer->fields().lookupField(
field.
name() );
211 const QIcon icon = mLayer->fields().iconForField( idx );
212 const 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 const QString fieldName = mFilterButton->defaultAction()->data().toString();
294 const 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 const 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 );