QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsfeaturepickermodelbase.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfeaturepickermodelbase.cpp - QgsFeaturePickerModelBase
3  ---------------------
4  begin : 10.3.2017
5  copyright : (C) 2017 by Matthias Kuhn
6  email : matthias@opengis.ch
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 
18 
19 #include "qgsvectorlayer.h"
20 #include "qgsconditionalstyle.h"
21 #include "qgsapplication.h"
22 #include "qgssettings.h"
23 
24 
26  : QAbstractItemModel( parent )
27 {
28  mReloadTimer.setInterval( 100 );
29  mReloadTimer.setSingleShot( true );
30  connect( &mReloadTimer, &QTimer::timeout, this, &QgsFeaturePickerModelBase::scheduledReload );
31 }
32 
33 
35 {
36  if ( mGatherer )
37  connect( mGatherer, &QgsFeatureExpressionValuesGatherer::finished, mGatherer, &QgsFeatureExpressionValuesGatherer::deleteLater );
38 }
39 
40 
42 {
43  return mSourceLayer;
44 }
45 
46 
48 {
49  if ( mSourceLayer == sourceLayer )
50  return;
51 
52  mSourceLayer = sourceLayer;
53  if ( mSourceLayer )
54  mExpressionContext = mSourceLayer->createExpressionContext();
55 
56  reload();
57  emit sourceLayerChanged();
58 
59  if ( mSourceLayer )
60  setDisplayExpression( mSourceLayer->displayExpression() );
61 }
62 
63 
65 {
66  return mDisplayExpression.expression();
67 }
68 
69 
70 void QgsFeaturePickerModelBase::setDisplayExpression( const QString &displayExpression )
71 {
72  if ( mDisplayExpression.expression() == displayExpression )
73  return;
74 
75  mDisplayExpression = QgsExpression( displayExpression );
76  reload();
78 }
79 
80 
82 {
83  return mFilterValue;
84 }
85 
86 
87 void QgsFeaturePickerModelBase::setFilterValue( const QString &filterValue )
88 {
89  if ( mFilterValue == filterValue )
90  return;
91 
92  mFilterValue = filterValue;
93  reload();
94  emit filterValueChanged();
95 }
96 
97 
99 {
100  return mFilterExpression;
101 }
102 
103 
104 void QgsFeaturePickerModelBase::setFilterExpression( const QString &filterExpression )
105 {
106  if ( mFilterExpression == filterExpression )
107  return;
108 
109  mFilterExpression = filterExpression;
110  reload();
112 }
113 
114 
116 {
117  return mGatherer;
118 }
119 
121 {
122  return mExtraIdentifierValue;
123 }
124 
125 
126 QModelIndex QgsFeaturePickerModelBase::index( int row, int column, const QModelIndex &parent ) const
127 {
128  Q_UNUSED( parent )
129  return createIndex( row, column, nullptr );
130 }
131 
132 
133 QModelIndex QgsFeaturePickerModelBase::parent( const QModelIndex &child ) const
134 {
135  Q_UNUSED( child )
136  return QModelIndex();
137 }
138 
139 
140 int QgsFeaturePickerModelBase::rowCount( const QModelIndex &parent ) const
141 {
142  Q_UNUSED( parent )
143  return mEntries.size();
144 }
145 
146 
147 
148 QVariant QgsFeaturePickerModelBase::data( const QModelIndex &index, int role ) const
149 {
150  if ( !index.isValid() )
151  return QVariant();
152 
153  switch ( role )
154  {
155  case Qt::DisplayRole:
156  case Qt::EditRole:
157  case ValueRole:
158  return mEntries.value( index.row() ).value;
159 
160  case FeatureIdRole:
161  return mEntries.value( index.row() ).featureId;
162 
163  case FeatureRole:
164  return mEntries.value( index.row() ).feature;
165 
166  case IdentifierValueRole:
167  {
168  const QVariantList values = mEntries.value( index.row() ).identifierFields;
169  return values.value( 0 );
170  }
171 
173  return mEntries.value( index.row() ).identifierFields;
174 
175 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
176  case Qt::BackgroundColorRole:
177  case Qt::TextColorRole:
178 #else
179  case Qt::BackgroundRole:
180  case Qt::ForegroundRole:
181 #endif
182  case Qt::DecorationRole:
183  case Qt::FontRole:
184  {
185  bool isNull = identifierIsNull( entryIdentifier( mEntries.value( index.row() ) ) );
186  if ( isNull )
187  {
188  // Representation for NULL value
189 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
190  if ( role == Qt::TextColorRole )
191 #else
192  if ( role == Qt::ForegroundRole )
193 #endif
194  {
195  return QBrush( QColor( Qt::gray ) );
196  }
197  if ( role == Qt::FontRole )
198  {
199  QFont font = QFont();
200  if ( index.row() == mExtraValueIndex )
201  font.setBold( true );
202  else
203  font.setItalic( true );
204  return font;
205  }
206  }
207  else
208  {
209  // Respect conditional style
210  const QgsConditionalStyle style = featureStyle( mEntries.value( index.row() ).feature );
211 
212  if ( style.isValid() )
213  {
214 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
215  if ( role == Qt::BackgroundColorRole && style.validBackgroundColor() )
216 #else
217  if ( role == Qt::BackgroundRole && style.validBackgroundColor() )
218 #endif
219  return style.backgroundColor();
220 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
221  if ( role == Qt::TextColorRole && style.validTextColor() )
222 #else
223  if ( role == Qt::ForegroundRole && style.validTextColor() )
224 #endif
225  return style.textColor();
226  if ( role == Qt::DecorationRole )
227  return style.icon();
228  if ( role == Qt::FontRole )
229  return style.font();
230  }
231  }
232  break;
233  }
234  }
235 
236  return QVariant();
237 }
238 
239 
240 void QgsFeaturePickerModelBase::updateCompleter()
241 {
242  emit beginUpdate();
243 
244  QgsFeatureExpressionValuesGatherer *gatherer = qobject_cast<QgsFeatureExpressionValuesGatherer *>( sender() );
245  if ( gatherer->wasCanceled() )
246  {
247  delete gatherer;
248  return;
249  }
250 
251  QVector<QgsFeatureExpressionValuesGatherer::Entry> entries = mGatherer->entries();
252 
253  if ( mExtraValueIndex == -1 )
254  {
256  }
257 
258  // Only reloading the current entry?
259  bool reloadCurrentFeatureOnly = mGatherer->data().toBool();
260  if ( reloadCurrentFeatureOnly )
261  {
262  if ( !entries.isEmpty() )
263  {
264  mEntries.replace( mExtraValueIndex, entries.at( 0 ) );
265  emit dataChanged( index( mExtraValueIndex, 0, QModelIndex() ), index( mExtraValueIndex, 0, QModelIndex() ) );
266  mShouldReloadCurrentFeature = false;
267  setExtraValueDoesNotExist( false );
268  }
269  else
270  {
271  setExtraValueDoesNotExist( true );
272  }
273 
274  mKeepCurrentEntry = true;
275  mShouldReloadCurrentFeature = false;
276 
277  if ( mFilterValue.isEmpty() )
278  reload();
279  }
280  else
281  {
282  // We got strings for a filter selection
283  std::sort( entries.begin(), entries.end(), []( const QgsFeatureExpressionValuesGatherer::Entry & a, const QgsFeatureExpressionValuesGatherer::Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );
284 
285  if ( mAllowNull && mSourceLayer )
286  {
287  entries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry( mSourceLayer ) );
288  }
289 
290  const int newEntriesSize = entries.size();
291 
292  // fixed entry is either NULL or extra value
293  const int nbFixedEntry = ( mKeepCurrentEntry ? 1 : 0 ) + ( mAllowNull ? 1 : 0 );
294 
295  // Find the index of the current entry in the new list
296  int currentEntryInNewList = -1;
297  if ( mExtraValueIndex != -1 && mExtraValueIndex < mEntries.count() )
298  {
299  for ( int i = 0; i < newEntriesSize; ++i )
300  {
301  if ( compareEntries( entries.at( i ), mEntries.at( mExtraValueIndex ) ) )
302  {
303  mEntries.replace( mExtraValueIndex, entries.at( i ) );
304  currentEntryInNewList = i;
305  setExtraValueDoesNotExist( false );
306  break;
307  }
308  }
309  }
310 
311  int firstRow = 0;
312 
313  // Move current entry to the first position if this is a fixed entry or because
314  // the entry exists in the new list
315  if ( mExtraValueIndex > -1 && ( mExtraValueIndex < nbFixedEntry || currentEntryInNewList != -1 ) )
316  {
317  if ( mExtraValueIndex != 0 )
318  {
319  beginMoveRows( QModelIndex(), mExtraValueIndex, mExtraValueIndex, QModelIndex(), 0 );
320  mEntries.move( mExtraValueIndex, 0 );
321  endMoveRows();
322  }
323  firstRow = 1;
324  }
325 
326  // Remove all entries (except for extra entry if existent)
327  beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
328  mEntries.remove( firstRow, mEntries.size() - firstRow );
329 
330  // if we remove all rows before endRemoveRows, setExtraIdentifierValuesUnguarded will be called
331  // and a null value will be added to mEntries, so we block setExtraIdentifierValuesUnguarded call
332 
333  mIsSettingExtraIdentifierValue = true;
334  endRemoveRows();
335  mIsSettingExtraIdentifierValue = false;
336 
337  if ( currentEntryInNewList == -1 )
338  {
339  beginInsertRows( QModelIndex(), firstRow, entries.size() + 1 );
340  mEntries += entries;
341  endInsertRows();
342 
343  // if all entries have been cleaned (firstRow == 0)
344  // and there is a value in entries, prefer this value over NULL
345  // else chose the first one (the previous one)
346  setExtraIdentifierValueIndex( firstRow == 0 && mAllowNull && !entries.isEmpty() ? 1 : 0, firstRow == 0 );
347  }
348  else
349  {
350  if ( currentEntryInNewList != 0 )
351  {
352  beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
353  mEntries = entries.mid( 0, currentEntryInNewList ) + mEntries;
354  endInsertRows();
355  }
356  else
357  {
358  mEntries.replace( 0, entries.at( 0 ) );
359  }
360 
361  // don't notify for a change if it's a fixed entry
362  if ( currentEntryInNewList >= nbFixedEntry )
363  {
364  emit dataChanged( index( currentEntryInNewList, 0, QModelIndex() ), index( currentEntryInNewList, 0, QModelIndex() ) );
365  }
366 
367  beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
368  mEntries += entries.mid( currentEntryInNewList + 1 );
369  endInsertRows();
370  setExtraIdentifierValueIndex( currentEntryInNewList );
371  }
372 
373  emit filterJobCompleted();
374 
375  mKeepCurrentEntry = false;
376  }
377  emit endUpdate();
378 
379  // scheduleReload and updateCompleter lives in the same thread so if the gatherer hasn't been stopped
380  // (checked before), mGatherer still references the current gatherer
381  Q_ASSERT( gatherer == mGatherer );
382  delete mGatherer;
383  mGatherer = nullptr;
384  emit isLoadingChanged();
385 }
386 
387 
388 void QgsFeaturePickerModelBase::scheduledReload()
389 {
390  if ( !mSourceLayer )
391  return;
392 
393  bool wasLoading = false;
394 
395  if ( mGatherer )
396  {
397  mGatherer->stop();
398  wasLoading = true;
399  }
400 
401  QgsFeatureRequest request;
402 
403  if ( mShouldReloadCurrentFeature )
404  {
406  }
407  else
408  {
409  QString filterClause;
410 
411  if ( mFilterValue.isEmpty() && !mFilterExpression.isEmpty() )
412  filterClause = mFilterExpression;
413  else if ( mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
414  filterClause = QStringLiteral( "(%1) ILIKE '%%2%'" ).arg( mDisplayExpression, mFilterValue );
415  else if ( !mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
416  filterClause = QStringLiteral( "(%1) AND ((%2) ILIKE '%%3%')" ).arg( mFilterExpression, mDisplayExpression, mFilterValue );
417 
418  if ( !filterClause.isEmpty() )
419  request.setFilterExpression( filterClause );
420  }
421  QSet<QString> attributes = requestedAttributes();
422  if ( !attributes.isEmpty() )
423  {
424  if ( auto *lFilterExpression = request.filterExpression() )
425  attributes += lFilterExpression->referencedColumns();
426  attributes += requestedAttributesForStyle();
427 
428  request.setSubsetOfAttributes( attributes, mSourceLayer->fields() );
429  }
430 
431  if ( !mFetchGeometry )
433  if ( mFetchLimit > 0 )
434  request.setLimit( mFetchLimit );
435 
436  mGatherer = createValuesGatherer( request );
437  mGatherer->setData( mShouldReloadCurrentFeature );
438  connect( mGatherer, &QgsFeatureExpressionValuesGatherer::finished, this, &QgsFeaturePickerModelBase::updateCompleter );
439 
440  mGatherer->start();
441  if ( !wasLoading )
442  emit isLoadingChanged();
443 }
444 
445 
446 QSet<QString> QgsFeaturePickerModelBase::requestedAttributesForStyle() const
447 {
448  QSet<QString> requestedAttrs;
449 
450  const auto rowStyles = mSourceLayer->conditionalStyles()->rowStyles();
451 
452  for ( const QgsConditionalStyle &style : rowStyles )
453  {
454  QgsExpression exp( style.rule() );
455  requestedAttrs += exp.referencedColumns();
456  }
457 
458  if ( mDisplayExpression.isField() )
459  {
460  QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
461  const auto constFieldStyles = mSourceLayer->conditionalStyles()->fieldStyles( fieldName );
462  for ( const QgsConditionalStyle &style : constFieldStyles )
463  {
464  QgsExpression exp( style.rule() );
465  requestedAttrs += exp.referencedColumns();
466  }
467  }
468 
469  return requestedAttrs;
470 }
471 
472 
473 void QgsFeaturePickerModelBase::setExtraIdentifierValueIndex( int index, bool force )
474 {
475  if ( mExtraValueIndex == index && !force )
476  return;
477 
480 }
481 
482 
483 void QgsFeaturePickerModelBase::reloadCurrentFeature()
484 {
485  mShouldReloadCurrentFeature = true;
486  mReloadTimer.start();
487 }
488 
489 
490 void QgsFeaturePickerModelBase::setExtraIdentifierValueUnguarded( const QVariant &identifierValue )
491 {
492  const QVector<QgsFeatureExpressionValuesGatherer::Entry> entries = mEntries;
493 
494  int index = 0;
495  for ( const QgsFeatureExpressionValuesGatherer::Entry &entry : entries )
496  {
497  if ( compareEntries( entry, createEntry( identifierValue ) ) )
498  {
499  setExtraIdentifierValueIndex( index );
500  break;
501  }
502 
503  index++;
504  }
505 
506  // Value not found in current entries
507  if ( mExtraValueIndex != index )
508  {
509  bool isNull = identifierIsNull( identifierValue );
510  if ( !isNull || mAllowNull )
511  {
512  beginInsertRows( QModelIndex(), 0, 0 );
513  if ( !isNull )
514  {
515  mEntries.prepend( createEntry( identifierValue ) );
516  reloadCurrentFeature();
517  }
518  else
519  {
520  mEntries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry( mSourceLayer ) );
521  }
522  endInsertRows();
523 
524  setExtraIdentifierValueIndex( 0, true );
525  }
526  }
527 }
528 
529 
530 QgsConditionalStyle QgsFeaturePickerModelBase::featureStyle( const QgsFeature &feature ) const
531 {
532  if ( !mSourceLayer )
533  return QgsConditionalStyle();
534 
535  QgsVectorLayer *layer = mSourceLayer;
536  QgsFeatureId fid = feature.id();
537  mExpressionContext.setFeature( feature );
538 
539  auto styles = QgsConditionalStyle::matchingConditionalStyles( layer->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
540 
541  if ( mDisplayExpression.referencedColumns().count() == 1 )
542  {
543  // Style specific for this field
544  QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
545  const auto allStyles = layer->conditionalStyles()->fieldStyles( fieldName );
546  const auto matchingFieldStyles = QgsConditionalStyle::matchingConditionalStyles( allStyles, feature.attribute( fieldName ), mExpressionContext );
547 
548  styles += matchingFieldStyles;
549  }
550 
551  QgsConditionalStyle style;
552  style = QgsConditionalStyle::compressStyles( styles );
553  mEntryStylesMap.insert( fid, style );
554 
555  return style;
556 }
557 
558 
560 {
561  return mAllowNull;
562 }
563 
564 
566 {
567  if ( mAllowNull == allowNull )
568  return;
569 
570  mAllowNull = allowNull;
571  emit allowNullChanged();
572 
573  reload();
574 }
575 
577 {
578  return mFetchGeometry;
579 }
580 
582 {
583  if ( mFetchGeometry == fetchGeometry )
584  return;
585 
586  mFetchGeometry = fetchGeometry;
587  reload();
588 }
589 
591 {
592  return mFetchLimit;
593 }
594 
596 {
597  if ( fetchLimit == mFetchLimit )
598  return;
599 
600  mFetchLimit = fetchLimit;
601  emit fetchLimitChanged();
602 }
603 
604 
606 {
607  return mExtraValueDoesNotExist;
608 }
609 
610 
611 void QgsFeaturePickerModelBase::setExtraValueDoesNotExist( bool extraValueDoesNotExist )
612 {
613  if ( mExtraValueDoesNotExist == extraValueDoesNotExist )
614  return;
615 
616  mExtraValueDoesNotExist = extraValueDoesNotExist;
618 }
619 
620 
622 {
623  return mExtraValueIndex;
624 }
625 
626 
627 void QgsFeaturePickerModelBase::reload()
628 {
629  mReloadTimer.start();
630 }
631 
632 
633 void QgsFeaturePickerModelBase::setExtraIdentifierValue( const QVariant &extraIdentifierValue )
634 {
636  return;
637 
638  if ( mIsSettingExtraIdentifierValue )
639  return;
640 
641  mIsSettingExtraIdentifierValue = true;
642 
644 
646 
647  mIsSettingExtraIdentifierValue = false;
648 
650 }
651 
QgsConditionalStyles rowStyles() const
Returns a list of row styles associated with the layer.
QList< QgsConditionalStyle > fieldStyles(const QString &fieldName) const
Returns the conditional styles set for the field with matching fieldName.
Conditional styling for a rule.
static QgsConditionalStyle compressStyles(const QList< QgsConditionalStyle > &styles)
Compress a list of styles into a single style.
static QList< QgsConditionalStyle > matchingConditionalStyles(const QList< QgsConditionalStyle > &styles, const QVariant &value, QgsExpressionContext &context)
Find and return the matching styles for the value and feature.
QColor backgroundColor() const
The background color for style.
QColor textColor() const
The text color set for style.
QFont font() const
The font for the style.
bool validTextColor() const
Check if the text color is valid for render.
bool isValid() const
isValid Check if this rule is valid.
QPixmap icon() const
The icon set for style generated from the set symbol.
bool validBackgroundColor() const
Check if the background color is valid for render.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
QString expression() const
Returns the original, unmodified expression string.
bool isField() const
Checks whether an expression consists only of a single field reference.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
void extraIdentifierValueIndexChanged(int index)
The index at which the extra identifier value is available within the model.
void beginUpdate()
Notification that the model is about to be changed because a job was completed.
virtual QVariant entryIdentifier(const QgsFeatureExpressionValuesGatherer::Entry &entry) const =0
Returns the identifier of the given entry.
void filterValueChanged()
This value will be used to filter the features available from this model.
void setFilterValue(const QString &filterValue)
This value will be used to filter the features available from this model.
void setExtraIdentifierValue(const QVariant &extraIdentifierValue)
Allows specifying one value that does not need to match the filter criteria but will still be availab...
virtual void requestToReloadCurrentFeature(QgsFeatureRequest &request)=0
Update the request to match the current feature to be reloaded.
void filterExpressionChanged()
An additional filter expression to apply, next to the filterValue.
void setFetchLimit(int fetchLimit)
Defines the feature request fetch limit If set to 0, no limit is applied when fetching.
QVariant extraIdentifierValue() const
Allows specifying one value that does not need to match the filter criteria but will still be availab...
void setFetchGeometry(bool fetchGeometry)
Defines if the geometry will be fetched.
void setExtraIdentifierValueUnguarded(const QVariant &identifierValue)
This will set the identifier value to be set in the model even if it doesn't exist currently in the d...
void extraIdentifierValueChanged()
Allows specifying one value that does not need to match the filter criteria but will still be availab...
int mExtraValueIndex
The current index.
QModelIndex parent(const QModelIndex &child) const override
void filterJobCompleted()
Indicates that a filter job has been completed and new data may be available.
void setAllowNull(bool allowNull)
Add a NULL entry to the list.
void setDisplayExpression(const QString &displayExpression)
The display expression will be used for.
QVariant mExtraIdentifierValue
The current identifier value.
QgsFeaturePickerModelBase(QObject *parent=nullptr)
Create a new QgsFeaturePickerModelBase, optionally specifying a parent.
virtual QgsFeatureExpressionValuesGatherer * createValuesGatherer(const QgsFeatureRequest &request) const =0
Creates the value gatherer.
virtual QgsFeatureExpressionValuesGatherer::Entry createEntry(const QVariant &identifier) const =0
Creates an entry with just the identifier so the feature can be retrieved in a next iteration.
bool isLoading() const
Indicator if the model is currently performing any feature iteration in the background.
virtual bool identifierIsNull(const QVariant &identifier) const =0
Returns true if the entry is null The identifier can be either the feature ID or the list of identifi...
QVariant data(const QModelIndex &index, int role) const override
QModelIndex index(int row, int column, const QModelIndex &parent) const override
void fetchLimitChanged()
Emitted when the fetching limit for the feature request changes.
void sourceLayerChanged()
The source layer from which features will be fetched.
virtual QSet< QString > requestedAttributes() const
Returns the attributes to be fetched in the request.
@ FeatureIdRole
Used to retrieve the id of a feature.
@ IdentifierValuesRole
Used to retrieve the identifierValues (primary keys) of a feature.
@ FeatureRole
Used to retrieve the feature, it might be incomplete if the request doesn't fetch all attributes or g...
@ ValueRole
Used to retrieve the displayExpression of a feature.
void setFilterExpression(const QString &filterExpression)
An additional filter expression to apply, next to the filterValue.
void allowNullChanged()
Add a NULL entry to the list.
int rowCount(const QModelIndex &parent) const override
virtual bool compareEntries(const QgsFeatureExpressionValuesGatherer::Entry &a, const QgsFeatureExpressionValuesGatherer::Entry &b) const =0
Returns true if the 2 entries refers to the same feature.
void isLoadingChanged()
Indicator if the model is currently performing any feature iteration in the background.
QVector< QgsFeatureExpressionValuesGatherer::Entry > mEntries
virtual QVariant nullIdentifier() const =0
Returns a null identifier.
void endUpdate()
Notification that the model change is finished.
void displayExpressionChanged()
The display expression will be used for.
void extraValueDoesNotExistChanged()
Flag indicating that the extraIdentifierValue does not exist in the data.
void setSourceLayer(QgsVectorLayer *sourceLayer)
The source layer from which features will be fetched.
bool extraValueDoesNotExist() const
Flag indicating that the extraIdentifierValue does not exist in the data.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsExpression * filterExpression() const
Returns the filter expression if set.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:287
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString displayExpression
QgsConditionalLayerStyles * conditionalStyles() const
Returns the conditional styles that are set for this layer.
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28