QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
qgsfeaturefilterwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfeaturefilterwidget.cpp
3  --------------------------------------
4  Date : 20.9.2019
5  Copyright : (C) 2019 Julien Cabieces
6  Email : julien dot cabieces at oslandia dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 //
19 // W A R N I N G
20 // -------------
21 //
22 // This file is not part of the QGIS API. It exists purely as an
23 // implementation detail. This header file may change from version to
24 // version without notice, or even be removed.
25 //
26 
28 
29 #include "qgsapplication.h"
30 #include "qgssearchwidgetwrapper.h"
31 #include "qgsdualview.h"
36 #include "qgsgui.h"
37 #include "qgsdialog.h"
38 #include "qgsexpressionlineedit.h"
39 #include "qgsmessagebar.h"
40 
41 #include <QMenu>
42 
43 QgsFeatureFilterWidget::QgsFeatureFilterWidget( QWidget *parent )
44  : QWidget( parent )
45 {
46  setupUi( this );
47 
48  // Initialize filter gui elements
49  mFilterColumnsMenu = new QMenu( this );
50  mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu );
51  mStoredFilterExpressionMenu = new QMenu( this );
52  mActionStoredFilterExpressions->setMenu( mStoredFilterExpressionMenu );
53 
54  // Set filter icon in a couple of places
55  QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter2.svg" );
56  mActionShowAllFilter->setIcon( filterIcon );
57  mActionAdvancedFilter->setIcon( filterIcon );
58  mActionSelectedFilter->setIcon( filterIcon );
59  mActionVisibleFilter->setIcon( filterIcon );
60  mActionEditedFilter->setIcon( filterIcon );
61 
62 
63  // Set button to store or delete stored filter expressions
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 );
69 
70  // Connect filter signals
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 );
79 }
80 
81 void QgsFeatureFilterWidget::init( QgsVectorLayer *layer, const QgsAttributeEditorContext &context, QgsDualView *mainView,
82  QgsMessageBar *messageBar, int messageBarTimeout )
83 {
84  mMainView = mainView;
85  mLayer = layer;
86  mEditorContext = context;
87  mMessageBar = messageBar;
88  mMessageBarTimeout = messageBarTimeout;
89 
90  connect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsFeatureFilterWidget::columnBoxInit );
91  connect( mLayer, &QgsVectorLayer::attributeDeleted, this, &QgsFeatureFilterWidget::columnBoxInit );
92 
93  //set delay on entering text
94  mFilterQueryTimer.setSingleShot( true );
95  connect( &mFilterQueryTimer, &QTimer::timeout, this, &QgsFeatureFilterWidget::updateCurrentStoredFilterExpression );
96 
97  columnBoxInit();
98  storedFilterExpressionBoxInit();
99  storeExpressionButtonInit();
100 }
101 
102 void QgsFeatureFilterWidget::filterShowAll()
103 {
104  mFilterButton->setDefaultAction( mActionShowAllFilter );
105  mFilterButton->setPopupMode( QToolButton::InstantPopup );
106  mFilterQuery->setVisible( false );
107  mFilterQuery->setText( QString() );
108  if ( mCurrentSearchWidgetWrapper )
109  {
110  mCurrentSearchWidgetWrapper->widget()->setVisible( false );
111  }
112  mApplyFilterButton->setVisible( false );
113  mStoreFilterExpressionButton->setVisible( false );
114  mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowAll );
115 }
116 
117 void QgsFeatureFilterWidget::filterSelected()
118 {
119  mFilterButton->setDefaultAction( mActionSelectedFilter );
120  mFilterButton->setPopupMode( QToolButton::InstantPopup );
121  mFilterQuery->setVisible( false );
122  mApplyFilterButton->setVisible( false );
123  mStoreFilterExpressionButton->setVisible( false );
124  mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowSelected );
125 }
126 
127 void QgsFeatureFilterWidget::filterVisible()
128 {
129  if ( !mLayer->isSpatial() )
130  {
131  filterShowAll();
132  return;
133  }
134 
135  mFilterButton->setDefaultAction( mActionVisibleFilter );
136  mFilterButton->setPopupMode( QToolButton::InstantPopup );
137  mFilterQuery->setVisible( false );
138  mApplyFilterButton->setVisible( false );
139  mStoreFilterExpressionButton->setVisible( false );
140  mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowVisible );
141 }
142 
143 void QgsFeatureFilterWidget::filterEdited()
144 {
145  mFilterButton->setDefaultAction( mActionEditedFilter );
146  mFilterButton->setPopupMode( QToolButton::InstantPopup );
147  mFilterQuery->setVisible( false );
148  mApplyFilterButton->setVisible( false );
149  mStoreFilterExpressionButton->setVisible( false );
150  mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowEdited );
151 }
152 
153 
154 void QgsFeatureFilterWidget::filterQueryAccepted()
155 {
156  if ( ( mFilterQuery->isVisible() && mFilterQuery->text().isEmpty() ) ||
157  ( mCurrentSearchWidgetWrapper && mCurrentSearchWidgetWrapper->widget()->isVisible()
158  && mCurrentSearchWidgetWrapper->expression().isEmpty() ) )
159  {
160  filterShowAll();
161  return;
162  }
163  filterQueryChanged( mFilterQuery->text() );
164 }
165 
166 void QgsFeatureFilterWidget::filterQueryChanged( const QString &query )
167 {
168  QString str;
169  if ( mFilterButton->defaultAction() == mActionAdvancedFilter )
170  {
171  str = query;
172  }
173  else if ( mCurrentSearchWidgetWrapper )
174  {
175  str = mCurrentSearchWidgetWrapper->expression();
176  }
177 
178  setFilterExpression( str );
179 }
180 
181 void QgsFeatureFilterWidget::columnBoxInit()
182 {
183  const auto constActions = mFilterColumnsMenu->actions();
184  for ( QAction *a : constActions )
185  {
186  mFilterColumnsMenu->removeAction( a );
187  mFilterButton->removeAction( a );
188  delete a;
189  }
190 
191  mFilterButton->addAction( mActionShowAllFilter );
192  mFilterButton->addAction( mActionSelectedFilter );
193  if ( mLayer->isSpatial() )
194  {
195  mFilterButton->addAction( mActionVisibleFilter );
196  }
197  mFilterButton->addAction( mActionEditedFilter );
198  mFilterButton->addAction( mActionFilterColumnsMenu );
199  mFilterButton->addAction( mActionAdvancedFilter );
200  mFilterButton->addAction( mActionStoredFilterExpressions );
201 
202  const QList<QgsField> fields = mLayer->fields().toList();
203 
204  const auto constFields = fields;
205  for ( const QgsField &field : constFields )
206  {
207  int idx = mLayer->fields().lookupField( field.name() );
208  if ( idx < 0 )
209  continue;
210 
211  if ( QgsGui::editorWidgetRegistry()->findBest( mLayer, field.name() ).type() != QLatin1String( "Hidden" ) )
212  {
213  QIcon icon = mLayer->fields().iconForField( idx );
214  QString alias = mLayer->attributeDisplayName( idx );
215 
216  // Generate action for the filter popup button
217  QAction *filterAction = new QAction( icon, alias, mFilterButton );
218  filterAction->setData( field.name() );
219 
220  connect( filterAction, &QAction::triggered, this, [ = ] { filterColumnChanged( filterAction ); } );
221  mFilterColumnsMenu->addAction( filterAction );
222  }
223  }
224 }
225 
226 void QgsFeatureFilterWidget::handleStoreFilterExpression()
227 {
228  if ( !mActionHandleStoreFilterExpression->isChecked() )
229  {
230  mLayer->storedExpressionManager()->removeStoredExpression( mActionHandleStoreFilterExpression->data().toString() );
231  }
232  else
233  {
234  mLayer->storedExpressionManager()->addStoredExpression( mFilterQuery->text(), mFilterQuery->text() );
235  }
236 
237  updateCurrentStoredFilterExpression();
238  storedFilterExpressionBoxInit();
239 }
240 
241 void QgsFeatureFilterWidget::storedFilterExpressionBoxInit()
242 {
243  const auto constActions = mStoredFilterExpressionMenu->actions();
244  for ( QAction *a : constActions )
245  {
246  mStoredFilterExpressionMenu->removeAction( a );
247  delete a;
248  }
249 
250  const QList< QgsStoredExpression > storedExpressions = mLayer->storedExpressionManager()->storedExpressions();
251  for ( const QgsStoredExpression &storedExpression : storedExpressions )
252  {
253  QAction *storedExpressionAction = new QAction( storedExpression.name, mFilterButton );
254  connect( storedExpressionAction, &QAction::triggered, this, [ = ]()
255  {
256  setFilterExpression( storedExpression.expression, QgsAttributeForm::ReplaceFilter, true );
257  } );
258  mStoredFilterExpressionMenu->addAction( storedExpressionAction );
259  }
260 }
261 
262 void QgsFeatureFilterWidget::storeExpressionButtonInit()
263 {
264  if ( mActionHandleStoreFilterExpression->isChecked() )
265  {
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 );
271  }
272  else
273  {
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 );
279  }
280 }
281 
282 
283 void QgsFeatureFilterWidget::filterColumnChanged( QAction *filterAction )
284 {
285  mFilterButton->setDefaultAction( filterAction );
286  mFilterButton->setPopupMode( QToolButton::InstantPopup );
287  // replace the search line edit with a search widget that is suited to the selected field
288  // delete previous widget
289  if ( mCurrentSearchWidgetWrapper )
290  {
291  mCurrentSearchWidgetWrapper->widget()->setVisible( false );
292  delete mCurrentSearchWidgetWrapper;
293  }
294  QString fieldName = mFilterButton->defaultAction()->data().toString();
295  // get the search widget
296  int fldIdx = mLayer->fields().lookupField( fieldName );
297  if ( fldIdx < 0 )
298  return;
299  const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, fieldName );
300  mCurrentSearchWidgetWrapper = QgsGui::editorWidgetRegistry()->
301  createSearchWidget( setup.type(), mLayer, fldIdx, setup.config(), mFilterContainer, mEditorContext );
302  if ( mCurrentSearchWidgetWrapper->applyDirectly() )
303  {
304  connect( mCurrentSearchWidgetWrapper, &QgsSearchWidgetWrapper::expressionChanged, this, &QgsFeatureFilterWidget::filterQueryChanged );
305  mApplyFilterButton->setVisible( false );
306  mStoreFilterExpressionButton->setVisible( false );
307  }
308  else
309  {
310  connect( mCurrentSearchWidgetWrapper, &QgsSearchWidgetWrapper::expressionChanged, this, &QgsFeatureFilterWidget::filterQueryAccepted );
311  mApplyFilterButton->setVisible( true );
312  mStoreFilterExpressionButton->setVisible( true );
313  }
314 
315  replaceSearchWidget( mFilterQuery, mCurrentSearchWidgetWrapper->widget() );
316 }
317 
318 void QgsFeatureFilterWidget::filterExpressionBuilder()
319 {
320  // Show expression builder
322 
323  QgsExpressionBuilderDialog dlg( mLayer, mFilterQuery->text(), this, QStringLiteral( "generic" ), context );
324  dlg.setWindowTitle( tr( "Expression Based Filter" ) );
325 
326  QgsDistanceArea myDa;
327  myDa.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() );
328  myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
329  dlg.setGeomCalculator( myDa );
330 
331  if ( dlg.exec() == QDialog::Accepted )
332  {
333  setFilterExpression( dlg.expressionText(), QgsAttributeForm::ReplaceFilter, true );
334  }
335 }
336 
337 void QgsFeatureFilterWidget::saveAsStoredFilterExpression()
338 {
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() );
343 
344  QLabel *nameLabel = new QLabel( tr( "Name" ), dlg );
345  QLineEdit *nameEdit = new QLineEdit( dlg );
346  layout->addWidget( nameLabel );
347  layout->addWidget( nameEdit );
348 
349  if ( dlg->exec() == QDialog::Accepted )
350  {
351  mLayer->storedExpressionManager()->addStoredExpression( nameEdit->text(), mFilterQuery->text() );
352 
353  updateCurrentStoredFilterExpression();
354  storedFilterExpressionBoxInit();
355  }
356 }
357 
358 void QgsFeatureFilterWidget::editStoredFilterExpression()
359 {
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() );
364 
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 );
368  QgsExpressionLineEdit *expressionEdit = new QgsExpressionLineEdit( dlg );
369  expressionEdit->setExpression( mLayer->storedExpressionManager()->storedExpression( mActionHandleStoreFilterExpression->data().toString() ).expression );
370 
371  layout->addWidget( nameLabel );
372  layout->addWidget( nameEdit );
373  layout->addWidget( expressionLabel );
374  layout->addWidget( expressionEdit );
375 
376  if ( dlg->exec() == QDialog::Accepted )
377  {
378  //update stored expression
379  mLayer->storedExpressionManager()->updateStoredExpression( mActionHandleStoreFilterExpression->data().toString(), nameEdit->text(), expressionEdit->expression(), QgsStoredExpression::Category::FilterExpression );
380 
381  //update text
382  mFilterQuery->setValue( expressionEdit->expression() );
383 
384  storedFilterExpressionBoxInit();
385  }
386 }
387 
388 void QgsFeatureFilterWidget::updateCurrentStoredFilterExpression()
389 {
390  QgsStoredExpression currentStoredExpression = mLayer->storedExpressionManager()->findStoredExpressionByExpression( mFilterQuery->value() );
391 
392  //set checked when it's an existing stored expression
393  mActionHandleStoreFilterExpression->setChecked( !currentStoredExpression.id.isNull() );
394 
395  mActionHandleStoreFilterExpression->setData( currentStoredExpression.id );
396  mActionEditStoredFilterExpression->setData( currentStoredExpression.id );
397 
398  //update bookmark button
399  storeExpressionButtonInit();
400 }
401 
402 void QgsFeatureFilterWidget::setFilterExpression( const QString &filterString, QgsAttributeForm::FilterType type, bool alwaysShowFilter )
403 {
404  QString filter;
405  if ( !mFilterQuery->text().isEmpty() && !filterString.isEmpty() )
406  {
407  switch ( type )
408  {
410  filter = filterString;
411  break;
412 
414  filter = QStringLiteral( "(%1) AND (%2)" ).arg( mFilterQuery->text(), filterString );
415  break;
416 
418  filter = QStringLiteral( "(%1) OR (%2)" ).arg( mFilterQuery->text(), filterString );
419  break;
420  }
421  }
422  else if ( !filterString.isEmpty() )
423  {
424  filter = filterString;
425  }
426  else
427  {
428  filterShowAll();
429  return;
430  }
431 
432  mFilterQuery->setText( filter );
433 
434  if ( alwaysShowFilter || !mCurrentSearchWidgetWrapper || !mCurrentSearchWidgetWrapper->applyDirectly() )
435  {
436 
437  mFilterButton->setDefaultAction( mActionAdvancedFilter );
438  mFilterButton->setPopupMode( QToolButton::MenuButtonPopup );
439  mFilterQuery->setVisible( true );
440  mApplyFilterButton->setVisible( true );
441  mStoreFilterExpressionButton->setVisible( true );
442  if ( mCurrentSearchWidgetWrapper )
443  {
444  // replace search widget widget with the normal filter query line edit
445  replaceSearchWidget( mCurrentSearchWidgetWrapper->widget(), mFilterQuery );
446  }
447  }
448 
449  QgsFeatureIds filteredFeatures;
450  QgsDistanceArea myDa;
451 
452  myDa.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() );
453  myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
454 
455  // parse search string and build parsed tree
456  QgsExpression filterExpression( filter );
457  if ( filterExpression.hasParserError() )
458  {
459  mMessageBar->pushMessage( tr( "Parsing error" ), filterExpression.parserErrorString(), Qgis::Warning, mMessageBarTimeout );
460  return;
461  }
462 
464 
465  if ( !filterExpression.prepare( &context ) )
466  {
467  mMessageBar->pushMessage( tr( "Evaluation error" ), filterExpression.evalErrorString(), Qgis::Warning, mMessageBarTimeout );
468  }
469 
470  bool fetchGeom = filterExpression.needsGeometry();
471 
472  QApplication::setOverrideCursor( Qt::WaitCursor );
473 
474  filterExpression.setGeomCalculator( &myDa );
475  filterExpression.setDistanceUnits( QgsProject::instance()->distanceUnits() );
476  filterExpression.setAreaUnits( QgsProject::instance()->areaUnits() );
477  QgsFeatureRequest request( mMainView->masterModel()->request() );
478  request.setSubsetOfAttributes( filterExpression.referencedColumns(), mLayer->fields() );
479  if ( !fetchGeom )
480  {
482  }
483  else
484  {
485  // force geometry extraction if the filter requests it
486  request.setFlags( request.flags() & ~QgsFeatureRequest::NoGeometry );
487  }
488  QgsFeatureIterator featIt = mLayer->getFeatures( request );
489 
490  QgsFeature f;
491 
492  while ( featIt.nextFeature( f ) )
493  {
494  context.setFeature( f );
495  if ( filterExpression.evaluate( &context ).toInt() != 0 )
496  filteredFeatures << f.id();
497 
498  // check if there were errors during evaluating
499  if ( filterExpression.hasEvalError() )
500  break;
501  }
502 
503  featIt.close();
504 
505  mMainView->setFilteredFeatures( filteredFeatures );
506 
507  QApplication::restoreOverrideCursor();
508 
509  if ( filterExpression.hasEvalError() )
510  {
511  mMessageBar->pushMessage( tr( "Error filtering" ), filterExpression.evalErrorString(), Qgis::Warning, mMessageBarTimeout );
512  return;
513  }
514  mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowFilteredList );
515 }
516 
517 void QgsFeatureFilterWidget::replaceSearchWidget( QWidget *oldw, QWidget *neww )
518 {
519  mFilterLayout->removeWidget( oldw );
520  oldw->setVisible( false );
521  mFilterLayout->addWidget( neww, 0, 0, nullptr );
522  neww->setVisible( true );
523  neww->setFocus();
524 }
525 
526 void QgsFeatureFilterWidget::onFilterQueryTextChanged( const QString &value )
527 {
528  Q_UNUSED( value );
529  mFilterQueryTimer.start( 300 );
530 }
531 
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsFeatureId id
Definition: qgsfeature.h:64
Wrapper for iterator of features from vector data provider or vector layer.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:34
QVariantMap config() const
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.
Definition: qgsdialog.h:33
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:45
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...
Definition: qgsfeature.h:55
Show only visible features (depends on the map canvas)
FilterType
Filter types.
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...
Definition: qgsgui.cpp:73
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Filter should be combined using "AND".
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QString id
generated uuid used for identification
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
Show only features which have unsaved changes.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:49
Show only features whose ids are on the filter list. {.
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:98
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.
Filter should be combined using "OR".
QgsEditorWidgetSetup findBest(const QgsVectorLayer *vl, const QString &fieldName) const
Find the best editor widget and its configuration for a given field.
The QgsExpressionLineEdit widget includes a line edit for entering expressions together with a button...
Holder for the widget type and its configuration for a field.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:450
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
Definition: qgsdialog.h:46
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Filter should replace any existing filter.
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.
Definition: qgsdualview.h:41
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.