17#include "moc_qgsfeaturepickermodelbase.cpp"
25 : QAbstractItemModel( parent )
27 mReloadTimer.setInterval( 100 );
28 mReloadTimer.setSingleShot(
true );
29 connect( &mReloadTimer, &QTimer::timeout,
this, &QgsFeaturePickerModelBase::scheduledReload );
40 connect( mGatherer, &QgsFeatureExpressionValuesGatherer::finished, mGatherer, &QgsFeatureExpressionValuesGatherer::deleteLater );
103 return mFilterExpression;
132 return createIndex( row, column,
nullptr );
139 return QModelIndex();
153 if ( !
index.isValid() )
158 case Qt::DisplayRole:
171 const QVariantList values =
mEntries.value(
index.row() ).identifierFields;
172 return values.value( 0 );
178 case Qt::BackgroundRole:
179 case Qt::ForegroundRole:
180 case Qt::DecorationRole:
187 if ( role == Qt::ForegroundRole )
189 return QBrush( QColor( Qt::gray ) );
191 if ( role == Qt::FontRole )
193 QFont font = QFont();
195 font.setBold(
true );
197 font.setItalic(
true );
212 if ( role == Qt::DecorationRole )
214 if ( role == Qt::FontRole )
226void QgsFeaturePickerModelBase::updateCompleter()
230 QgsFeatureExpressionValuesGatherer *gatherer = qobject_cast<QgsFeatureExpressionValuesGatherer *>( sender() );
231 if ( gatherer->wasCanceled() )
237 QVector<QgsFeatureExpressionValuesGatherer::Entry> entries = mGatherer->entries();
245 const bool reloadCurrentFeatureOnly = mGatherer->data().toBool();
246 if ( reloadCurrentFeatureOnly )
248 if ( !entries.isEmpty() )
252 mShouldReloadCurrentFeature =
false;
253 setExtraValueDoesNotExist(
false );
257 setExtraValueDoesNotExist(
true );
260 mKeepCurrentEntry =
true;
261 mShouldReloadCurrentFeature =
false;
263 if ( mFilterValue.isEmpty() )
269 std::sort( entries.begin(), entries.end(), [](
const QgsFeatureExpressionValuesGatherer::Entry & a,
const QgsFeatureExpressionValuesGatherer::Entry & b ) { return a.value.localeAwareCompare( b.value ) < 0; } );
271 if ( mAllowNull && mSourceLayer )
273 entries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry( mSourceLayer ) );
276 const int newEntriesSize = entries.size();
279 const int nbFixedEntry = ( mKeepCurrentEntry ? 1 : 0 ) + ( mAllowNull ? 1 : 0 );
282 int currentEntryInNewList = -1;
285 for (
int i = 0; i < newEntriesSize; ++i )
290 currentEntryInNewList = i;
291 setExtraValueDoesNotExist(
false );
313 beginRemoveRows( QModelIndex(), firstRow,
mEntries.size() - firstRow );
319 mIsSettingExtraIdentifierValue =
true;
321 mIsSettingExtraIdentifierValue =
false;
323 if ( currentEntryInNewList == -1 )
325 beginInsertRows( QModelIndex(), firstRow, entries.size() + 1 );
332 setExtraIdentifierValueIndex( firstRow == 0 && mAllowNull && !entries.isEmpty() ? 1 : 0, firstRow == 0 );
336 if ( currentEntryInNewList != 0 )
338 beginInsertRows( QModelIndex(), 0, currentEntryInNewList - 1 );
344 mEntries.replace( 0, entries.at( 0 ) );
348 if ( currentEntryInNewList >= nbFixedEntry )
350 emit dataChanged(
index( currentEntryInNewList, 0, QModelIndex() ),
index( currentEntryInNewList, 0, QModelIndex() ) );
353 beginInsertRows( QModelIndex(), currentEntryInNewList + 1, newEntriesSize - currentEntryInNewList - 1 );
354 mEntries += entries.mid( currentEntryInNewList + 1 );
356 setExtraIdentifierValueIndex( currentEntryInNewList );
361 mKeepCurrentEntry =
false;
367 Q_ASSERT( gatherer == mGatherer );
374void QgsFeaturePickerModelBase::scheduledReload()
379 bool wasLoading =
false;
389 if ( mShouldReloadCurrentFeature )
395 QString filterClause;
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 );
404 if ( !filterClause.isEmpty() )
411 if ( !attributes.isEmpty() )
414 attributes += lFilterExpression->referencedColumns();
415 attributes += requestedAttributesForStyle();
420 if ( !mFetchGeometry )
422 if ( mFetchLimit > 0 )
426 mGatherer->setData( mShouldReloadCurrentFeature );
427 connect( mGatherer, &QgsFeatureExpressionValuesGatherer::finished,
this, &QgsFeaturePickerModelBase::updateCompleter );
435QSet<QString> QgsFeaturePickerModelBase::requestedAttributesForStyle()
const
437 QSet<QString> requestedAttrs;
444 requestedAttrs += exp.referencedColumns();
447 if ( mDisplayExpression.
isField() )
454 requestedAttrs += exp.referencedColumns();
458 return requestedAttrs;
462void QgsFeaturePickerModelBase::setExtraIdentifierValueIndex(
int index,
bool force )
472void QgsFeaturePickerModelBase::reloadCurrentFeature()
474 mShouldReloadCurrentFeature =
true;
475 mReloadTimer.start();
481 const QVector<QgsFeatureExpressionValuesGatherer::Entry> entries =
mEntries;
484 for (
const QgsFeatureExpressionValuesGatherer::Entry &entry : entries )
488 setExtraIdentifierValueIndex(
index );
499 if ( !isNull || mAllowNull )
501 beginInsertRows( QModelIndex(), 0, 0 );
505 setExtraValueDoesNotExist(
true );
506 reloadCurrentFeature();
510 mEntries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry( mSourceLayer ) );
511 setExtraValueDoesNotExist(
false );
515 setExtraIdentifierValueIndex( 0,
true );
539 styles += matchingFieldStyles;
544 mEntryStylesMap.insert( fid, style );
569 return mFetchGeometry;
600 return mExtraValueDoesNotExist;
604void QgsFeaturePickerModelBase::setExtraValueDoesNotExist(
bool extraValueDoesNotExist )
620void QgsFeaturePickerModelBase::reload()
622 mReloadTimer.start();
631 if ( mIsSettingExtraIdentifierValue )
634 mIsSettingExtraIdentifierValue =
true;
640 mIsSettingExtraIdentifierValue =
false;
@ 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.
int mExtraValueIndex
The current index.
@ 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...
QgsVectorLayer * sourceLayer
QVariant data(const QModelIndex &index, int role) const override
QModelIndex index(int row, int column, const QModelIndex &parent) const override
int extraIdentifierValueIndex
void fetchLimitChanged()
Emitted when the fetching limit for the feature request changes.
void sourceLayerChanged()
The source layer from which features will be fetched.
~QgsFeaturePickerModelBase() override
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.
QString displayExpression
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...
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