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