25   : QAbstractItemModel( parent )
    27   mReloadTimer.setInterval( 100 );
    28   mReloadTimer.setSingleShot( 
true );
    29   connect( &mReloadTimer, &QTimer::timeout, 
this, &QgsFeatureFilterModel::scheduledReload );
    30   setExtraIdentifierValueUnguarded( QVariant() );
    36     connect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, mGatherer, &QgsFieldExpressionValuesGatherer::deleteLater );
    46   if ( mSourceLayer == sourceLayer )
    77   if ( mFilterValue == filterValue )
    87   return mFilterExpression;
    92   if ( mFilterExpression == filterExpression )
   108   return createIndex( row, column, 
nullptr );
   114   return QModelIndex();
   121   return mEntries.size();
   132   if ( !index.isValid() )
   137     case Qt::DisplayRole:
   140       return mEntries.value( index.row() ).value;
   143       return mEntries.value( index.row() ).identifierValue;
   145     case Qt::BackgroundColorRole:
   146     case Qt::TextColorRole:
   147     case Qt::DecorationRole:
   150       if ( mEntries.value( index.row() ).identifierValue.isNull() )
   153         if ( role == Qt::TextColorRole )
   155           return QBrush( QColor( Qt::gray ) );
   157         else if ( role == Qt::FontRole )
   159           QFont font = QFont();
   160           if ( index.row() == mExtraIdentifierValueIndex )
   161             font.setBold( 
true );
   163           if ( mEntries.value( index.row() ).identifierValue.isNull() )
   165             font.setItalic( 
true );
   181           if ( role == Qt::DecorationRole )
   183           if ( role == Qt::FontRole )
   194 void QgsFeatureFilterModel::updateCompleter()
   197   QVector<Entry> entries = mGatherer->entries();
   199   if ( mExtraIdentifierValueIndex == -1 )
   200     setExtraIdentifierValueUnguarded( QVariant() );
   203   if ( mGatherer->data().toBool() )
   205     if ( !entries.isEmpty() )
   207       mEntries.replace( mExtraIdentifierValueIndex, entries.at( 0 ) );
   208       emit dataChanged( 
index( mExtraIdentifierValueIndex, 0, QModelIndex() ), 
index( mExtraIdentifierValueIndex, 0, QModelIndex() ) );
   209       mShouldReloadCurrentFeature = 
false;
   210       setExtraValueDoesNotExist( 
false );
   214       setExtraValueDoesNotExist( 
true );
   217     mShouldReloadCurrentFeature = 
false;
   219     if ( mFilterValue.isEmpty() )
   225     std::sort( entries.begin(), entries.end(), []( 
const Entry & a, 
const Entry & b ) { 
return a.value.localeAwareCompare( b.value ) < 0; } );
   230     const int newEntriesSize = entries.size();
   233     int currentEntryInNewList = -1;
   234     if ( mExtraIdentifierValueIndex != -1 )
   236       for ( 
int i = 0; i < newEntriesSize; ++i )
   238         if ( entries.at( i ).identifierValue == mExtraIdentifierValue )
   240           currentEntryInNewList = i;
   241           mEntries.replace( mExtraIdentifierValueIndex, entries.at( i ) );
   242           emit dataChanged( 
index( mExtraIdentifierValueIndex, 0, QModelIndex() ), 
index( mExtraIdentifierValueIndex, 0, QModelIndex() ) );
   243           setExtraValueDoesNotExist( 
false );
   250       Q_ASSERT_X( 
false, 
"QgsFeatureFilterModel::updateCompleter", 
"No extra identifier value generated. Should not get here." );
   256     if ( mExtraIdentifierValueIndex != -1 )
   258       if ( mExtraIdentifierValueIndex != 0 )
   260         beginMoveRows( QModelIndex(), mExtraIdentifierValueIndex, mExtraIdentifierValueIndex, QModelIndex(), 0 );
   261         mEntries.move( mExtraIdentifierValueIndex, 0 );
   268     beginRemoveRows( QModelIndex(), firstRow, mEntries.size() - firstRow );
   269     mEntries.remove( firstRow, mEntries.size() - firstRow );
   272     if ( currentEntryInNewList == -1 )
   274       beginInsertRows( QModelIndex(), 1, entries.size() + 1 );
   277       setExtraIdentifierValueIndex( 0 );
   281       if ( currentEntryInNewList != 0 )
   283         beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
   284         mEntries = entries.mid( 0, currentEntryInNewList ) + mEntries;
   289         mEntries.replace( 0, entries.at( 0 ) );
   292       emit dataChanged( 
index( currentEntryInNewList, 0, QModelIndex() ), 
index( currentEntryInNewList, 0, QModelIndex() ) );
   294       beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
   295       mEntries += entries.mid( currentEntryInNewList + 1 );
   297       setExtraIdentifierValueIndex( currentEntryInNewList );
   305 void QgsFeatureFilterModel::gathererThreadFinished()
   312 void QgsFeatureFilterModel::scheduledReload()
   317   bool wasLoading = 
false;
   323     disconnect( mGatherer, &QgsFieldExpressionValuesGatherer::collectedValues, 
this, &QgsFeatureFilterModel::updateCompleter );
   324     disconnect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, 
this, &QgsFeatureFilterModel::gathererThreadFinished );
   325     connect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, mGatherer, &QgsFieldExpressionValuesGatherer::deleteLater );
   332   if ( mShouldReloadCurrentFeature )
   338     QString filterClause;
   340     if ( mFilterValue.isEmpty() && !mFilterExpression.isEmpty() )
   341       filterClause = mFilterExpression;
   342     else if ( mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
   343       filterClause = QStringLiteral( 
"(%1) ILIKE '%%2%'" ).arg( mDisplayExpression, mFilterValue );
   344     else if ( !mFilterExpression.isEmpty() && !mFilterValue.isEmpty() )
   345       filterClause = QStringLiteral( 
"(%1) AND ((%2) ILIKE '%%3%')" ).arg( mFilterExpression, mDisplayExpression, mFilterValue );
   347     if ( !filterClause.isEmpty() )
   350   QSet<QString> attributes;
   353   attributes << mIdentifierField;
   360   mGatherer->setData( mShouldReloadCurrentFeature );
   362   connect( mGatherer, &QgsFieldExpressionValuesGatherer::collectedValues, 
this, &QgsFeatureFilterModel::updateCompleter );
   363   connect( mGatherer, &QgsFieldExpressionValuesGatherer::finished, 
this, &QgsFeatureFilterModel::gathererThreadFinished );
   370 QSet<QString> QgsFeatureFilterModel::requestedAttributes()
 const   372   QSet<QString> requestedAttrs;
   382   if ( mDisplayExpression.
isField() )
   392   return requestedAttrs;
   395 void QgsFeatureFilterModel::setExtraIdentifierValueIndex( 
int index, 
bool force )
   397   if ( mExtraIdentifierValueIndex == 
index && !force )
   400   mExtraIdentifierValueIndex = 
index;
   404 void QgsFeatureFilterModel::reloadCurrentFeature()
   406   mShouldReloadCurrentFeature = 
true;
   407   mReloadTimer.start();
   410 void QgsFeatureFilterModel::setExtraIdentifierValueUnguarded( 
const QVariant &
extraIdentifierValue )
   412   const QVector<Entry> entries = mEntries;
   415   for ( 
const Entry &entry : entries )
   417     if ( entry.identifierValue == extraIdentifierValue
   418          && entry.identifierValue.isNull() == extraIdentifierValue.isNull()
   419          && entry.identifierValue.isValid() == extraIdentifierValue.isValid() )
   421       setExtraIdentifierValueIndex( index );
   429   if ( mExtraIdentifierValueIndex != index )
   431     beginInsertRows( QModelIndex(), 0, 0 );
   432     if ( extraIdentifierValue.isNull() )
   435       mEntries.prepend( Entry( extraIdentifierValue, QStringLiteral( 
"(%1)" ).arg( extraIdentifierValue.toString() ), 
QgsFeature() ) );
   438     setExtraIdentifierValueIndex( 0, 
true );
   440     reloadCurrentFeature();
   462     styles += matchingFieldStyles;
   467   mEntryStylesMap.insert( fid, style );
   479   if ( mAllowNull == allowNull )
   490   return mExtraValueDoesNotExist;
   495   if ( mExtraValueDoesNotExist == extraValueDoesNotExist )
   504   return mExtraIdentifierValueIndex;
   509   return mIdentifierField;
   514   if ( mIdentifierField == identifierField )
   521 void QgsFeatureFilterModel::reload()
   523   mReloadTimer.start();
   528   return mExtraIdentifierValue;
   533   if ( 
qgsVariantEqual( extraIdentifierValue, mExtraIdentifierValue ) && mExtraIdentifierValue.isValid() )
   536   if ( mIsSettingExtraIdentifierValue )
   539   mIsSettingExtraIdentifierValue = 
true;
   543   setExtraIdentifierValueUnguarded( extraIdentifierValue );
   545   mIsSettingExtraIdentifierValue = 
false;
 Class for parsing and evaluation of expressions (formerly called "search strings"). 
 
void filterValueChanged()
This value will be used to filter the features available from this model. 
 
bool allowNull() const
Add a NULL entry to the list. 
 
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes) 
 
void beginUpdate()
Notification that the model is about to be changed because a job was completed. 
 
This class is a composition of two QSettings instances: 
 
int rowCount(const QModelIndex &parent) const override
 
Used to retrieve the displayExpression of a feature. 
 
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context. 
 
void setFilterExpression(const QString &filterExpression)
An additional filter expression to apply, next to the filterValue. 
 
QString filterValue() const
This value will be used to filter the features available from this model. 
 
QList< QgsConditionalStyle > fieldStyles(const QString &fieldName)
Returns the conditional styles set for the field UI properties. 
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched. 
 
QVariant extraIdentifierValue() const
Allows specifying one value that does not need to match the filter criteria but will still be availab...
 
void filterJobCompleted()
Indicates that a filter job has been completed and new data may be available. 
 
bool validBackgroundColor() const
Check if the background color is valid for render. 
 
QPixmap icon() const
The icon set for style generated from the set symbol. 
 
bool extraValueDoesNotExist() const
Flag indicating that the extraIdentifierValue does not exist in the data. 
 
void extraIdentifierValueIndexChanged(int index)
The index at which the extra identifier value is available within the model. 
 
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
friend class QgsFieldExpressionValuesGatherer
 
QgsConditionalLayerStyles * conditionalStyles() const
Returns the conditional styles that are set for this layer. 
 
QgsExpression * filterExpression() const
Returns the filter expression if set. 
 
int extraIdentifierValueIndex() const
The index at which the extra identifier value is available within the model. 
 
QList< QgsConditionalStyle > rowStyles()
 
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression. 
 
void identifierFieldChanged()
The identifier field should be a unique field that can be used to identify individual features...
 
QgsFields fields() const FINAL
Returns the list of fields of this layer. 
 
Conditional styling for a rule. 
 
QString displayExpression() const
The display expression will be used for. 
 
bool isValid() const
isValid Check if this rule is valid. 
 
static QList< QgsConditionalStyle > matchingConditionalStyles(const QList< QgsConditionalStyle > &styles, const QVariant &value, QgsExpressionContext &context)
Find and return the matching styles for the value and feature. 
 
void setFilterValue(const QString &filterValue)
This value will be used to filter the features available from this model. 
 
QModelIndex index(int row, int column, const QModelIndex &parent) const override
 
This class wraps a request for features to a vector layer (or directly its vector data provider)...
 
QColor backgroundColor() const
The background color for style. 
 
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS. 
 
static QgsConditionalStyle compressStyles(const QList< QgsConditionalStyle > &styles)
Compress a list of styles into a single style. 
 
void isLoadingChanged()
Indicator if the model is currently performing any feature iteration in the background. 
 
QModelIndex parent(const QModelIndex &child) const override
 
void allowNullChanged()
Add a NULL entry to the list. 
 
QgsFeatureFilterModel(QObject *parent=nullptr)
Create a new QgsFeatureFilterModel, optionally specifying a parent. 
 
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
 
bool isLoading() const
Indicator if the model is currently performing any feature iteration in the background. 
 
QString filterExpression() const
An additional filter expression to apply, next to the filterValue. 
 
void filterExpressionChanged()
An additional filter expression to apply, next to the filterValue. 
 
void endUpdate()
Notification that the model change is finished. 
 
QString identifierField() const
The identifier field should be a unique field that can be used to identify individual features...
 
QString expression() const
Returns the original, unmodified expression string. 
 
int columnCount(const QModelIndex &parent) const override
 
void extraIdentifierValueChanged()
Allows specifying one value that does not need to match the filter criteria but will still be availab...
 
void setIdentifierField(const QString &identifierField)
The identifier field should be a unique field that can be used to identify individual features...
 
void setSourceLayer(QgsVectorLayer *sourceLayer)
The source layer from which features will be fetched. 
 
QColor textColor() const
The text color set for style. 
 
void sourceLayerChanged()
The source layer from which features will be fetched. 
 
bool validTextColor() const
Check if the text color is valid for render. 
 
bool isField() const
Checks whether an expression consists only of a single field reference. 
 
void setExtraIdentifierValue(const QVariant &extraIdentifierValue)
Allows specifying one value that does not need to match the filter criteria but will still be availab...
 
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request. 
 
QVariant data(const QModelIndex &index, int role) const override
 
void setAllowNull(bool allowNull)
Add a NULL entry to the list. 
 
QFont font() const
The font for the style. 
 
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required...
 
QgsVectorLayer * sourceLayer() const
The source layer from which features will be fetched. 
 
bool qgsVariantEqual(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether they are equal, NULL values are treated as equal...
 
Geometry is not required. It may still be returned if e.g. required for a filter condition. 
 
Used to retrieve the identifierValue (primary key) of a feature. 
 
void setDisplayExpression(const QString &displayExpression)
The display expression will be used for. 
 
Represents a vector layer which manages a vector based data sets. 
 
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name. 
 
void extraValueDoesNotExistChanged()
Flag indicating that the extraIdentifierValue does not exist in the data. 
 
QString rule() const
The condition rule set for the style. 
 
~QgsFeatureFilterModel() override
 
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched. 
 
void displayExpressionChanged()
The display expression will be used for.