From c824e4deaf35ec6a37f6ff2661164fbeb4953fb8 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Tue, 6 Apr 2021 09:44:58 +0200 Subject: [PATCH] Add isPassthrough() to edit buffer classes --- .../vector/qgsvectorlayereditbuffer.sip.in | 8 ++++++++ .../qgsvectorlayereditpassthrough.sip.in | 2 ++ src/core/vector/qgsvectorlayer.cpp | 18 +++++++++--------- src/core/vector/qgsvectorlayereditbuffer.cpp | 4 ++++ src/core/vector/qgsvectorlayereditbuffer.h | 7 +++++++ .../vector/qgsvectorlayereditpassthrough.cpp | 5 +++++ .../vector/qgsvectorlayereditpassthrough.h | 2 ++ 7 files changed, 37 insertions(+), 9 deletions(-) diff --git a/python/core/auto_generated/vector/qgsvectorlayereditbuffer.sip.in b/python/core/auto_generated/vector/qgsvectorlayereditbuffer.sip.in index 92656e048441..774d302fd890 100644 --- a/python/core/auto_generated/vector/qgsvectorlayereditbuffer.sip.in +++ b/python/core/auto_generated/vector/qgsvectorlayereditbuffer.sip.in @@ -212,6 +212,14 @@ Returns ``True`` if the specified feature ID has been deleted but not committed. Updates ``fields`` %End + virtual bool isPassthrough(); +%Docstring +Returns ``True`` if the edit buffer makes direct changes to the data provider, such in case of transactions. +Subclasses may override this method to indicate that they support this behavior, the default implementation returns ``False``. + +.. versionadded:: 3.18 +%End + protected slots: void undoIndexChanged( int index ); diff --git a/python/core/auto_generated/vector/qgsvectorlayereditpassthrough.sip.in b/python/core/auto_generated/vector/qgsvectorlayereditpassthrough.sip.in index e7cd5801b7b4..4ad5c1de392a 100644 --- a/python/core/auto_generated/vector/qgsvectorlayereditpassthrough.sip.in +++ b/python/core/auto_generated/vector/qgsvectorlayereditpassthrough.sip.in @@ -40,6 +40,8 @@ class QgsVectorLayerEditPassthrough : QgsVectorLayerEditBuffer virtual bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() ); + virtual bool isPassthrough(); + virtual bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues ); diff --git a/src/core/vector/qgsvectorlayer.cpp b/src/core/vector/qgsvectorlayer.cpp index aa502fe3f735..48605aefcf30 100644 --- a/src/core/vector/qgsvectorlayer.cpp +++ b/src/core/vector/qgsvectorlayer.cpp @@ -877,7 +877,7 @@ QgsRectangle QgsVectorLayer::extent() const } if ( !mEditBuffer || - ( !mDataProvider->transaction() && ( mEditBuffer->deletedFeatureIds().isEmpty() && mEditBuffer->changedGeometries().isEmpty() ) ) || + ( !mEditBuffer->isPassthrough() && ( mEditBuffer->deletedFeatureIds().isEmpty() && mEditBuffer->changedGeometries().isEmpty() ) ) || QgsDataSourceUri( mDataProvider->dataSourceUri() ).useEstimatedMetadata() ) { mDataProvider->updateExtents(); @@ -890,7 +890,7 @@ QgsRectangle QgsVectorLayer::extent() const rect.combineExtentWith( r ); } - if ( mEditBuffer && !mDataProvider->transaction() ) + if ( mEditBuffer && !mEditBuffer->isPassthrough() ) { const auto addedFeatures = mEditBuffer->addedFeatures(); for ( QgsFeatureMap::const_iterator it = addedFeatures.constBegin(); it != addedFeatures.constEnd(); ++it ) @@ -3367,13 +3367,13 @@ long QgsVectorLayer::featureCount() const if ( ! mDataProvider ) return -1; return mDataProvider->featureCount() + - ( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->addedFeatures().size() - mEditBuffer->deletedFeatureIds().size() : 0 ); + ( mEditBuffer && ! mEditBuffer->isPassthrough() ? mEditBuffer->addedFeatures().size() - mEditBuffer->deletedFeatureIds().size() : 0 ); } QgsFeatureSource::FeatureAvailability QgsVectorLayer::hasFeatures() const { - const QgsFeatureIds deletedFeatures( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->deletedFeatureIds() : QgsFeatureIds() ); - const QgsFeatureMap addedFeatures( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->addedFeatures() : QgsFeatureMap() ); + const QgsFeatureIds deletedFeatures( mEditBuffer && ! mEditBuffer->isPassthrough() ? mEditBuffer->deletedFeatureIds() : QgsFeatureIds() ); + const QgsFeatureMap addedFeatures( mEditBuffer && ! mEditBuffer->isPassthrough() ? mEditBuffer->addedFeatures() : QgsFeatureMap() ); if ( mEditBuffer && !deletedFeatures.empty() ) { @@ -3457,7 +3457,7 @@ bool QgsVectorLayer::rollBack( bool deleteBuffer ) return false; } - bool rollbackExtent = !mDataProvider->transaction() && ( !mEditBuffer->deletedFeatureIds().isEmpty() || + bool rollbackExtent = !mEditBuffer->isPassthrough() && ( !mEditBuffer->deletedFeatureIds().isEmpty() || !mEditBuffer->addedFeatures().isEmpty() || !mEditBuffer->changedGeometries().isEmpty() ); @@ -4044,7 +4044,7 @@ QSet QgsVectorLayer::uniqueValues( int index, int limit ) const { uniqueValues = mDataProvider->uniqueValues( index, limit ); - if ( mEditBuffer && ! mDataProvider->transaction() ) + if ( mEditBuffer && ! mEditBuffer->isPassthrough() ) { QSet vals; const auto constUniqueValues = uniqueValues; @@ -4152,7 +4152,7 @@ QStringList QgsVectorLayer::uniqueStringsMatching( int index, const QString &sub { results = mDataProvider->uniqueStringsMatching( index, substring, limit, feedback ); - if ( mEditBuffer && ! mDataProvider->transaction() ) + if ( mEditBuffer && ! mEditBuffer->isPassthrough() ) { QgsFeatureMap added = mEditBuffer->addedFeatures(); QMapIterator< QgsFeatureId, QgsFeature > addedIt( added ); @@ -4262,7 +4262,7 @@ QVariant QgsVectorLayer::minimumOrMaximumValue( int index, bool minimum ) const case QgsFields::OriginProvider: //a provider field { QVariant val = minimum ? mDataProvider->minimumValue( index ) : mDataProvider->maximumValue( index ); - if ( mEditBuffer && ! mDataProvider->transaction() ) + if ( mEditBuffer && ! mEditBuffer->isPassthrough() ) { QgsFeatureMap added = mEditBuffer->addedFeatures(); QMapIterator< QgsFeatureId, QgsFeature > addedIt( added ); diff --git a/src/core/vector/qgsvectorlayereditbuffer.cpp b/src/core/vector/qgsvectorlayereditbuffer.cpp index a0b491645988..ce6b9b10947c 100644 --- a/src/core/vector/qgsvectorlayereditbuffer.cpp +++ b/src/core/vector/qgsvectorlayereditbuffer.cpp @@ -256,6 +256,10 @@ bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field return true; } +bool QgsVectorLayerEditBuffer::isPassthrough() +{ + return false; +} bool QgsVectorLayerEditBuffer::addAttribute( const QgsField &field ) { diff --git a/src/core/vector/qgsvectorlayereditbuffer.h b/src/core/vector/qgsvectorlayereditbuffer.h index c2c6a3ffb28b..d16a9d2f1c58 100644 --- a/src/core/vector/qgsvectorlayereditbuffer.h +++ b/src/core/vector/qgsvectorlayereditbuffer.h @@ -189,6 +189,13 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject */ void updateFields( QgsFields &fields ); + /** + * Returns TRUE if the edit buffer makes direct changes to the data provider, such in case of transactions. + * Subclasses may override this method to indicate that they support this behavior, the default implementation returns FALSE. + * \since QGIS 3.18 + */ + virtual bool isPassthrough(); + //QString dumpEditBuffer(); protected slots: diff --git a/src/core/vector/qgsvectorlayereditpassthrough.cpp b/src/core/vector/qgsvectorlayereditpassthrough.cpp index 6ac4d31c4193..358a6823f69a 100644 --- a/src/core/vector/qgsvectorlayereditpassthrough.cpp +++ b/src/core/vector/qgsvectorlayereditpassthrough.cpp @@ -66,6 +66,11 @@ bool QgsVectorLayerEditPassthrough::addFeatures( QgsFeatureList &features ) return true; } +bool QgsVectorLayerEditPassthrough::isPassthrough() +{ + return true; +} + bool QgsVectorLayerEditPassthrough::deleteFeature( QgsFeatureId fid ) { return modify( new QgsVectorLayerUndoPassthroughCommandDeleteFeatures( this, QgsFeatureIds() << fid ) ); diff --git a/src/core/vector/qgsvectorlayereditpassthrough.h b/src/core/vector/qgsvectorlayereditpassthrough.h index 1aecf8a536b7..76baa8da77da 100644 --- a/src/core/vector/qgsvectorlayereditpassthrough.h +++ b/src/core/vector/qgsvectorlayereditpassthrough.h @@ -54,6 +54,7 @@ class CORE_EXPORT QgsVectorLayerEditPassthrough : public QgsVectorLayerEditBuffe bool deleteFeatures( const QgsFeatureIds &fids ) override; bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geom ) override; bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() ) override; + bool isPassthrough() override; /** * Changes values of attributes (but does not commit it). @@ -87,6 +88,7 @@ class CORE_EXPORT QgsVectorLayerEditPassthrough : public QgsVectorLayerEditBuffe // utility function to avoid cpy/paste bool modify( QgsVectorLayerUndoPassthroughCommand *cmd ); + }; #endif // QGSVECTORLAYEREDITPASSTHROUGH_H