QGIS API Documentation 3.41.0-Master (45a0abf3bec)
Loading...
Searching...
No Matches
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
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#include "moc_qgsfeaturepickermodelbase.cpp"
19
20#include "qgsvectorlayer.h"
21#include "qgsconditionalstyle.h"
23
25 : QAbstractItemModel( parent )
26{
27 mReloadTimer.setInterval( 100 );
28 mReloadTimer.setSingleShot( true );
29 connect( &mReloadTimer, &QTimer::timeout, this, &QgsFeaturePickerModelBase::scheduledReload );
30
31 // The fact that the feature changed is a combination of the 2 signals:
32 // If the extra value is set to a feature currently not fetched, it will go through an intermediate step while the extra value does not exist (as it call reloadFeature)
34}
35
36
38{
39 if ( mGatherer )
40 connect( mGatherer, &QgsFeatureExpressionValuesGatherer::finished, mGatherer, &QgsFeatureExpressionValuesGatherer::deleteLater );
41}
42
43
45{
46 return mSourceLayer;
47}
48
49
51{
52 if ( mSourceLayer == sourceLayer )
53 return;
54
55 mSourceLayer = sourceLayer;
56 if ( mSourceLayer )
57 mExpressionContext = mSourceLayer->createExpressionContext();
58
59 reload();
60 emit sourceLayerChanged();
61
62 if ( mSourceLayer )
63 setDisplayExpression( mSourceLayer->displayExpression() );
64}
65
66
68{
69 return mDisplayExpression.expression();
70}
71
72
73void QgsFeaturePickerModelBase::setDisplayExpression( const QString &displayExpression )
74{
75 if ( mDisplayExpression.expression() == displayExpression )
76 return;
77
78 mDisplayExpression = QgsExpression( displayExpression );
79 reload();
81}
82
83
85{
86 return mFilterValue;
87}
88
89
90void QgsFeaturePickerModelBase::setFilterValue( const QString &filterValue )
91{
92 if ( mFilterValue == filterValue )
93 return;
94
95 mFilterValue = filterValue;
96 reload();
97 emit filterValueChanged();
98}
99
100
102{
103 return mFilterExpression;
104}
105
106
107void QgsFeaturePickerModelBase::setFilterExpression( const QString &filterExpression )
108{
109 if ( mFilterExpression == filterExpression )
110 return;
111
112 mFilterExpression = filterExpression;
113 reload();
115}
116
117
119{
120 return mGatherer;
121}
122
127
128
129QModelIndex QgsFeaturePickerModelBase::index( int row, int column, const QModelIndex &parent ) const
130{
131 Q_UNUSED( parent )
132 return createIndex( row, column, nullptr );
133}
134
135
136QModelIndex QgsFeaturePickerModelBase::parent( const QModelIndex &child ) const
137{
138 Q_UNUSED( child )
139 return QModelIndex();
140}
141
142
143int QgsFeaturePickerModelBase::rowCount( const QModelIndex &parent ) const
144{
145 Q_UNUSED( parent )
146 return mEntries.size();
147}
148
149
150
151QVariant QgsFeaturePickerModelBase::data( const QModelIndex &index, int role ) const
152{
153 if ( !index.isValid() )
154 return QVariant();
155
156 switch ( role )
157 {
158 case Qt::DisplayRole:
159 case Qt::EditRole:
160 case static_cast< int >( CustomRole::Value ):
161 return mEntries.value( index.row() ).value;
162
163 case static_cast< int >( CustomRole::FeatureId ):
164 return mEntries.value( index.row() ).featureId;
165
166 case static_cast< int >( CustomRole::Feature ):
167 return mEntries.value( index.row() ).feature;
168
169 case static_cast< int >( CustomRole::IdentifierValue ):
170 {
171 const QVariantList values = mEntries.value( index.row() ).identifierFields;
172 return values.value( 0 );
173 }
174
175 case static_cast< int >( CustomRole::IdentifierValues ):
176 return mEntries.value( index.row() ).identifierFields;
177
178 case Qt::BackgroundRole:
179 case Qt::ForegroundRole:
180 case Qt::DecorationRole:
181 case Qt::FontRole:
182 {
183 const bool isNull = identifierIsNull( entryIdentifier( mEntries.value( index.row() ) ) );
184 if ( isNull )
185 {
186 // Representation for NULL value
187 if ( role == Qt::ForegroundRole )
188 {
189 return QBrush( QColor( Qt::gray ) );
190 }
191 if ( role == Qt::FontRole )
192 {
193 QFont font = QFont();
194 if ( index.row() == mExtraValueIndex )
195 font.setBold( true );
196 else
197 font.setItalic( true );
198 return font;
199 }
200 }
201 else
202 {
203 // Respect conditional style
204 const QgsConditionalStyle style = featureStyle( mEntries.value( index.row() ).feature );
205
206 if ( style.isValid() )
207 {
208 if ( role == Qt::BackgroundRole && style.validBackgroundColor() )
209 return style.backgroundColor();
210 if ( role == Qt::ForegroundRole && style.validTextColor() )
211 return style.textColor();
212 if ( role == Qt::DecorationRole )
213 return style.icon();
214 if ( role == Qt::FontRole )
215 return style.font();
216 }
217 }
218 break;
219 }
220 }
221
222 return QVariant();
223}
224
225
226void QgsFeaturePickerModelBase::updateCompleter()
227{
228 emit beginUpdate();
229
230 QgsFeatureExpressionValuesGatherer *gatherer = qobject_cast<QgsFeatureExpressionValuesGatherer *>( sender() );
231 if ( gatherer->wasCanceled() )
232 {
233 delete gatherer;
234 return;
235 }
236
237 QVector<QgsFeatureExpressionValuesGatherer::Entry> entries = mGatherer->entries();
238
239 if ( mExtraValueIndex == -1 )
240 {
242 }
243
244 // Only reloading the current entry?
245 const bool reloadCurrentFeatureOnly = mGatherer->data().toBool();
246 if ( reloadCurrentFeatureOnly )
247 {
248 if ( !entries.isEmpty() )
249 {
250 mEntries.replace( mExtraValueIndex, entries.at( 0 ) );
251 emit dataChanged( index( mExtraValueIndex, 0, QModelIndex() ), index( mExtraValueIndex, 0, QModelIndex() ) );
252 mShouldReloadCurrentFeature = false;
253 setExtraValueDoesNotExist( false );
254 }
255 else
256 {
257 setExtraValueDoesNotExist( true );
258 }
259
260 mKeepCurrentEntry = true;
261 mShouldReloadCurrentFeature = false;
262
263 if ( mFilterValue.isEmpty() )
264 reload();
265 }
266 else
267 {
268 // We got strings for a filter selection
269 std::sort( entries.begin(), entries.end(), []( const QgsFeatureExpressionValuesGatherer::Entry & a, const QgsFeatureExpressionValuesGatherer::Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );
270
271 if ( mAllowNull && mSourceLayer )
272 {
273 entries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry( mSourceLayer ) );
274 }
275
276 const int newEntriesSize = entries.size();
277
278 // fixed entry is either NULL or extra value
279 const int nbFixedEntry = ( mKeepCurrentEntry ? 1 : 0 ) + ( mAllowNull ? 1 : 0 );
280
281 // Find the index of the current entry in the new list
282 int currentEntryInNewList = -1;
283 if ( mExtraValueIndex != -1 && mExtraValueIndex < mEntries.count() )
284 {
285 for ( int i = 0; i < newEntriesSize; ++i )
286 {
287 if ( compareEntries( entries.at( i ), mEntries.at( mExtraValueIndex ) ) )
288 {
289 mEntries.replace( mExtraValueIndex, entries.at( i ) );
290 currentEntryInNewList = i;
291 setExtraValueDoesNotExist( false );
292 break;
293 }
294 }
295 }
296
297 int firstRow = 0;
298
299 // Move current entry to the first position if this is a fixed entry or because
300 // the entry exists in the new list
301 if ( mExtraValueIndex > -1 && ( mExtraValueIndex < nbFixedEntry || currentEntryInNewList != -1 ) )
302 {
303 if ( mExtraValueIndex != 0 )
304 {
305 beginMoveRows( QModelIndex(), mExtraValueIndex, mExtraValueIndex, QModelIndex(), 0 );
306 mEntries.move( mExtraValueIndex, 0 );
307 endMoveRows();
308 }
309 firstRow = 1;
310 }
311
312 // Remove all entries (except for extra entry if existent)
313 beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
314 mEntries.remove( firstRow, mEntries.size() - firstRow );
315
316 // if we remove all rows before endRemoveRows, setExtraIdentifierValuesUnguarded will be called
317 // and a null value will be added to mEntries, so we block setExtraIdentifierValuesUnguarded call
318
319 mIsSettingExtraIdentifierValue = true;
320 endRemoveRows();
321 mIsSettingExtraIdentifierValue = false;
322
323 if ( currentEntryInNewList == -1 )
324 {
325 beginInsertRows( QModelIndex(), firstRow, entries.size() + 1 );
326 mEntries += entries;
327 endInsertRows();
328
329 // if all entries have been cleaned (firstRow == 0)
330 // and there is a value in entries, prefer this value over NULL
331 // else chose the first one (the previous one)
332 setExtraIdentifierValueIndex( firstRow == 0 && mAllowNull && !entries.isEmpty() ? 1 : 0, firstRow == 0 );
333 }
334 else
335 {
336 if ( currentEntryInNewList != 0 )
337 {
338 beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
339 mEntries = entries.mid( 0, currentEntryInNewList ) + mEntries;
340 endInsertRows();
341 }
342 else
343 {
344 mEntries.replace( 0, entries.at( 0 ) );
345 }
346
347 // don't notify for a change if it's a fixed entry
348 if ( currentEntryInNewList >= nbFixedEntry )
349 {
350 emit dataChanged( index( currentEntryInNewList, 0, QModelIndex() ), index( currentEntryInNewList, 0, QModelIndex() ) );
351 }
352
353 beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
354 mEntries += entries.mid( currentEntryInNewList + 1 );
355 endInsertRows();
356 setExtraIdentifierValueIndex( currentEntryInNewList );
357 }
358
359 emit filterJobCompleted();
360
361 mKeepCurrentEntry = false;
362 }
363 emit endUpdate();
364
365 // scheduleReload and updateCompleter lives in the same thread so if the gatherer hasn't been stopped
366 // (checked before), mGatherer still references the current gatherer
367 Q_ASSERT( gatherer == mGatherer );
368 delete mGatherer;
369 mGatherer = nullptr;
370 emit isLoadingChanged();
371}
372
373
374void QgsFeaturePickerModelBase::scheduledReload()
375{
376 if ( !mSourceLayer )
377 return;
378
379 bool wasLoading = false;
380
381 if ( mGatherer )
382 {
383 mGatherer->stop();
384 wasLoading = true;
385 }
386
387 QgsFeatureRequest request;
388
389 if ( mShouldReloadCurrentFeature )
390 {
392 }
393 else
394 {
395 QString filterClause;
396
397 if ( mFilterValue.isEmpty() && !mFilterExpression.isEmpty() )
398 filterClause = mFilterExpression;
399 else if ( mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
400 filterClause = QStringLiteral( "(%1) ILIKE '%%2%'" ).arg( mDisplayExpression, mFilterValue );
401 else if ( !mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
402 filterClause = QStringLiteral( "(%1) AND ((%2) ILIKE '%%3%')" ).arg( mFilterExpression, mDisplayExpression, mFilterValue );
403
404 if ( !filterClause.isEmpty() )
405 {
406 request.setFilterExpression( filterClause );
408 }
409 }
410 QSet<QString> attributes = requestedAttributes();
411 if ( !attributes.isEmpty() )
412 {
413 if ( auto *lFilterExpression = request.filterExpression() )
414 attributes += lFilterExpression->referencedColumns();
415 attributes += requestedAttributesForStyle();
416
417 request.setSubsetOfAttributes( attributes, mSourceLayer->fields() );
418 }
419
420 if ( !mFetchGeometry )
422 if ( mFetchLimit > 0 )
423 request.setLimit( mFetchLimit );
424
425 mGatherer = createValuesGatherer( request );
426 mGatherer->setData( mShouldReloadCurrentFeature );
427 connect( mGatherer, &QgsFeatureExpressionValuesGatherer::finished, this, &QgsFeaturePickerModelBase::updateCompleter );
428
429 mGatherer->start();
430 if ( !wasLoading )
431 emit isLoadingChanged();
432}
433
434
435QSet<QString> QgsFeaturePickerModelBase::requestedAttributesForStyle() const
436{
437 QSet<QString> requestedAttrs;
438
439 const auto rowStyles = mSourceLayer->conditionalStyles()->rowStyles();
440
441 for ( const QgsConditionalStyle &style : rowStyles )
442 {
443 const QgsExpression exp( style.rule() );
444 requestedAttrs += exp.referencedColumns();
445 }
446
447 if ( mDisplayExpression.isField() )
448 {
449 const QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
450 const auto constFieldStyles = mSourceLayer->conditionalStyles()->fieldStyles( fieldName );
451 for ( const QgsConditionalStyle &style : constFieldStyles )
452 {
453 const QgsExpression exp( style.rule() );
454 requestedAttrs += exp.referencedColumns();
455 }
456 }
457
458 return requestedAttrs;
459}
460
461
462void QgsFeaturePickerModelBase::setExtraIdentifierValueIndex( int index, bool force )
463{
464 if ( mExtraValueIndex == index && !force )
465 return;
466
469}
470
471
472void QgsFeaturePickerModelBase::reloadCurrentFeature()
473{
474 mShouldReloadCurrentFeature = true;
475 mReloadTimer.start();
476}
477
478
480{
481 const QVector<QgsFeatureExpressionValuesGatherer::Entry> entries = mEntries;
482
483 int index = 0;
484 for ( const QgsFeatureExpressionValuesGatherer::Entry &entry : entries )
485 {
486 if ( compareEntries( entry, createEntry( identifierValue ) ) )
487 {
488 setExtraIdentifierValueIndex( index );
489 break;
490 }
491
492 index++;
493 }
494
495 // Value not found in current entries
496 if ( mExtraValueIndex != index )
497 {
498 const bool isNull = identifierIsNull( identifierValue );
499 if ( !isNull || mAllowNull )
500 {
501 beginInsertRows( QModelIndex(), 0, 0 );
502 if ( !isNull )
503 {
504 mEntries.prepend( createEntry( identifierValue ) );
505 setExtraValueDoesNotExist( true );
506 reloadCurrentFeature();
507 }
508 else
509 {
510 mEntries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry( mSourceLayer ) );
511 setExtraValueDoesNotExist( false );
512 }
513 endInsertRows();
514
515 setExtraIdentifierValueIndex( 0, true );
516 }
517 }
518}
519
520
521QgsConditionalStyle QgsFeaturePickerModelBase::featureStyle( const QgsFeature &feature ) const
522{
523 if ( !mSourceLayer )
524 return QgsConditionalStyle();
525
526 QgsVectorLayer *layer = mSourceLayer;
527 const QgsFeatureId fid = feature.id();
528 mExpressionContext.setFeature( feature );
529
530 auto styles = QgsConditionalStyle::matchingConditionalStyles( layer->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
531
532 if ( mDisplayExpression.referencedColumns().count() == 1 )
533 {
534 // Style specific for this field
535 const QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
536 const auto allStyles = layer->conditionalStyles()->fieldStyles( fieldName );
537 const auto matchingFieldStyles = QgsConditionalStyle::matchingConditionalStyles( allStyles, feature.attribute( fieldName ), mExpressionContext );
538
539 styles += matchingFieldStyles;
540 }
541
543 style = QgsConditionalStyle::compressStyles( styles );
544 mEntryStylesMap.insert( fid, style );
545
546 return style;
547}
548
549
551{
552 return mAllowNull;
553}
554
555
557{
558 if ( mAllowNull == allowNull )
559 return;
560
561 mAllowNull = allowNull;
562 emit allowNullChanged();
563
564 reload();
565}
566
568{
569 return mFetchGeometry;
570}
571
573{
574 if ( mFetchGeometry == fetchGeometry )
575 return;
576
577 mFetchGeometry = fetchGeometry;
578 reload();
579}
580
582{
583 return mFetchLimit;
584}
585
587{
588 if ( fetchLimit == mFetchLimit )
589 return;
590
591 mFetchLimit = fetchLimit;
592 emit fetchLimitChanged();
593
594 reload();
595}
596
597
599{
600 return mExtraValueDoesNotExist;
601}
602
603
604void QgsFeaturePickerModelBase::setExtraValueDoesNotExist( bool extraValueDoesNotExist )
605{
606 if ( mExtraValueDoesNotExist == extraValueDoesNotExist )
607 return;
608
609 mExtraValueDoesNotExist = extraValueDoesNotExist;
610 emit extraValueDoesNotExistChanged( mExtraValueDoesNotExist );
611}
612
613
618
619
620void QgsFeaturePickerModelBase::reload()
621{
622 mReloadTimer.start();
623}
624
625
626void QgsFeaturePickerModelBase::setExtraIdentifierValue( const QVariant &extraIdentifierValue )
627{
629 return;
630
631 if ( mIsSettingExtraIdentifierValue )
632 return;
633
634 mIsSettingExtraIdentifierValue = true;
635
637
639
640 mIsSettingExtraIdentifierValue = false;
641
643}
644
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
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.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of 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 extraValueDoesNotExistChanged(bool found)
Notification whether the model has found a feature tied to the extraIdentifierValue or not.
virtual QgsFeatureExpressionValuesGatherer * createValuesGatherer(const QgsFeatureRequest &request) const =0
Creates the value gatherer.
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...
virtual QSet< QString > requestedAttributes() const
Returns the attributes to be fetched in the request.
@ IdentifierValues
Used to retrieve the identifierValues (primary keys) of a feature.
@ FeatureId
Used to retrieve the id of a feature.
@ IdentifierValue
Used to retrieve the identifier value (primary key) of a feature.
@ Feature
Used to retrieve the feature, it might be incomplete if the request doesn't fetch all attributes or g...
@ Value
Used to retrieve the displayExpression of a feature.
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::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.
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 currentFeatureChanged()
Emitted when the current feature in the model has changed This emitted both when the extra value chan...
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 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).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
QgsExpressionContext * expressionContext()
Returns the expression context used to evaluate filter expressions.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsExpression * filterExpression() const
Returns the filter expression (if set).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsFeatureId id
Definition qgsfeature.h:66
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Represents a vector layer which manages a vector based data sets.
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