Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #41539 from elpaso/bugfix-gh41477-editbuffer-passt…
Browse files Browse the repository at this point in the history
…hrough

Bugfix gh41477 editbuffer passthrough
  • Loading branch information
m-kuhn committed Feb 24, 2021
2 parents 98a1b03 + 5fe3759 commit b3dae9a
Show file tree
Hide file tree
Showing 13 changed files with 471 additions and 72 deletions.
Expand Up @@ -208,6 +208,7 @@ Returns ``True`` if the specified feature ID has been deleted but not committed.
%End



protected slots:
void undoIndexChanged( int index );

Expand Down Expand Up @@ -269,8 +270,6 @@ Emitted after committing an attribute rename
Constructor for QgsVectorLayerEditBuffer
%End

void updateFields( QgsFields &fields );

void updateFeatureGeometry( QgsFeature &f );
%Docstring
Update feature with uncommitted geometry updates
Expand Down
Expand Up @@ -124,8 +124,7 @@ Constructor for QgsVectorLayerUndoCommandChangeGeometry
virtual void redo();

virtual int id() const;

virtual bool mergeWith( const QUndoCommand * );
virtual bool mergeWith( const QUndoCommand *other );


};
Expand Down
Expand Up @@ -169,6 +169,10 @@ Constructor for QgsVectorLayerUndoPassthroughCommandChangeGeometry
virtual void redo();


virtual int id() const;
virtual bool mergeWith( const QUndoCommand *other );


};


Expand Down
7 changes: 6 additions & 1 deletion src/core/qgstransaction.cpp
Expand Up @@ -218,7 +218,9 @@ QString QgsTransaction::createSavepoint( QString &error SIP_OUT )
return QString();

if ( !mLastSavePointIsDirty && !mSavepoints.isEmpty() )
{
return mSavepoints.top();
}

const QString name( QStringLiteral( "qgis" ) + ( QUuid::createUuid().toString().mid( 1, 24 ).replace( '-', QString() ) ) );

Expand Down Expand Up @@ -260,7 +262,10 @@ bool QgsTransaction::rollbackToSavepoint( const QString &name, QString &error SI
return false;

mSavepoints.resize( idx );
mLastSavePointIsDirty = false;
// Rolling back always dirties the previous savepoint because
// the status of the DB has changed between the previous savepoint and the
// one we are rolling back to.
mLastSavePointIsDirty = true;
return executeSql( QStringLiteral( "ROLLBACK TO SAVEPOINT %1" ).arg( QgsExpression::quotedColumnRef( name ) ), error );
}

Expand Down
50 changes: 26 additions & 24 deletions src/core/vector/qgsvectorlayer.cpp
Expand Up @@ -874,7 +874,7 @@ QgsRectangle QgsVectorLayer::extent() const
}

if ( !mEditBuffer ||
( mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mChangedGeometries.isEmpty() ) ||
( !mDataProvider->transaction() && ( mEditBuffer->deletedFeatureIds().isEmpty() && mEditBuffer->changedGeometries().isEmpty() ) ) ||
QgsDataSourceUri( mDataProvider->dataSourceUri() ).useEstimatedMetadata() )
{
mDataProvider->updateExtents();
Expand All @@ -887,9 +887,10 @@ QgsRectangle QgsVectorLayer::extent() const
rect.combineExtentWith( r );
}

if ( mEditBuffer )
if ( mEditBuffer && !mDataProvider->transaction() )
{
for ( QgsFeatureMap::const_iterator it = mEditBuffer->mAddedFeatures.constBegin(); it != mEditBuffer->mAddedFeatures.constEnd(); ++it )
const auto addedFeatures = mEditBuffer->addedFeatures();
for ( QgsFeatureMap::const_iterator it = addedFeatures.constBegin(); it != addedFeatures.constEnd(); ++it )
{
if ( it->hasGeometry() )
{
Expand Down Expand Up @@ -3363,13 +3364,13 @@ long QgsVectorLayer::featureCount() const
if ( ! mDataProvider )
return -1;
return mDataProvider->featureCount() +
( mEditBuffer ? mEditBuffer->mAddedFeatures.size() - mEditBuffer->mDeletedFeatureIds.size() : 0 );
( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->addedFeatures().size() - mEditBuffer->deletedFeatureIds().size() : 0 );
}

QgsFeatureSource::FeatureAvailability QgsVectorLayer::hasFeatures() const
{
const QgsFeatureIds deletedFeatures( mEditBuffer ? mEditBuffer->deletedFeatureIds() : QgsFeatureIds() );
const QgsFeatureMap addedFeatures( mEditBuffer ? mEditBuffer->addedFeatures() : QgsFeatureMap() );
const QgsFeatureIds deletedFeatures( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->deletedFeatureIds() : QgsFeatureIds() );
const QgsFeatureMap addedFeatures( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->addedFeatures() : QgsFeatureMap() );

if ( mEditBuffer && !deletedFeatures.empty() )
{
Expand Down Expand Up @@ -3453,9 +3454,9 @@ bool QgsVectorLayer::rollBack( bool deleteBuffer )
return false;
}

bool rollbackExtent = !mEditBuffer->mDeletedFeatureIds.isEmpty() ||
!mEditBuffer->mAddedFeatures.isEmpty() ||
!mEditBuffer->mChangedGeometries.isEmpty();
bool rollbackExtent = !mDataProvider->transaction() && ( !mEditBuffer->deletedFeatureIds().isEmpty() ||
!mEditBuffer->addedFeatures().isEmpty() ||
!mEditBuffer->changedGeometries().isEmpty() );

emit beforeRollBack();

Expand Down Expand Up @@ -4040,7 +4041,7 @@ QSet<QVariant> QgsVectorLayer::uniqueValues( int index, int limit ) const
{
uniqueValues = mDataProvider->uniqueValues( index, limit );

if ( mEditBuffer )
if ( mEditBuffer && ! mDataProvider->transaction() )
{
QSet<QString> vals;
const auto constUniqueValues = uniqueValues;
Expand Down Expand Up @@ -4088,10 +4089,11 @@ QSet<QVariant> QgsVectorLayer::uniqueValues( int index, int limit ) const

case QgsFields::OriginEdit:
// the layer is editable, but in certain cases it can still be avoided going through all features
if ( mEditBuffer->mDeletedFeatureIds.isEmpty() &&
mEditBuffer->mAddedFeatures.isEmpty() &&
!mEditBuffer->mDeletedAttributeIds.contains( index ) &&
mEditBuffer->mChangedAttributeValues.isEmpty() )
if ( mDataProvider->transaction() || (
mEditBuffer->deletedFeatureIds().isEmpty() &&
mEditBuffer->addedFeatures().isEmpty() &&
!mEditBuffer->deletedAttributeIds().contains( index ) &&
mEditBuffer->changedAttributeValues().isEmpty() ) )
{
uniqueValues = mDataProvider->uniqueValues( index, limit );
return uniqueValues;
Expand Down Expand Up @@ -4147,7 +4149,7 @@ QStringList QgsVectorLayer::uniqueStringsMatching( int index, const QString &sub
{
results = mDataProvider->uniqueStringsMatching( index, substring, limit, feedback );

if ( mEditBuffer )
if ( mEditBuffer && ! mDataProvider->transaction() )
{
QgsFeatureMap added = mEditBuffer->addedFeatures();
QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
Expand Down Expand Up @@ -4186,10 +4188,10 @@ QStringList QgsVectorLayer::uniqueStringsMatching( int index, const QString &sub

case QgsFields::OriginEdit:
// the layer is editable, but in certain cases it can still be avoided going through all features
if ( mEditBuffer->mDeletedFeatureIds.isEmpty() &&
mEditBuffer->mAddedFeatures.isEmpty() &&
!mEditBuffer->mDeletedAttributeIds.contains( index ) &&
mEditBuffer->mChangedAttributeValues.isEmpty() )
if ( mDataProvider->transaction() || ( mEditBuffer->deletedFeatureIds().isEmpty() &&
mEditBuffer->addedFeatures().isEmpty() &&
!mEditBuffer->deletedAttributeIds().contains( index ) &&
mEditBuffer->changedAttributeValues().isEmpty() ) )
{
return mDataProvider->uniqueStringsMatching( index, substring, limit, feedback );
}
Expand Down Expand Up @@ -4257,7 +4259,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 )
if ( mEditBuffer && ! mDataProvider->transaction() )
{
QgsFeatureMap added = mEditBuffer->addedFeatures();
QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
Expand Down Expand Up @@ -4290,10 +4292,10 @@ QVariant QgsVectorLayer::minimumOrMaximumValue( int index, bool minimum ) const
case QgsFields::OriginEdit:
{
// the layer is editable, but in certain cases it can still be avoided going through all features
if ( mEditBuffer->mDeletedFeatureIds.isEmpty() &&
mEditBuffer->mAddedFeatures.isEmpty() &&
!mEditBuffer->mDeletedAttributeIds.contains( index ) &&
mEditBuffer->mChangedAttributeValues.isEmpty() )
if ( mDataProvider->transaction() || ( mEditBuffer->deletedFeatureIds().isEmpty() &&
mEditBuffer->addedFeatures().isEmpty() &&
!mEditBuffer->deletedAttributeIds().contains( index ) &&
mEditBuffer->changedAttributeValues().isEmpty() ) )
{
return minimum ? mDataProvider->minimumValue( index ) : mDataProvider->maximumValue( index );
}
Expand Down
10 changes: 7 additions & 3 deletions src/core/vector/qgsvectorlayereditbuffer.h
Expand Up @@ -184,6 +184,13 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
*/
bool isFeatureDeleted( QgsFeatureId id ) const { return mDeletedFeatureIds.contains( id ); }

/**
* Updates \a fields
* \note Not available in Python bindings
* \since QGIS 3.18
*/
void updateFields( QgsFields &fields ) SIP_SKIP;

//QString dumpEditBuffer();

protected slots:
Expand Down Expand Up @@ -236,8 +243,6 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
//! Constructor for QgsVectorLayerEditBuffer
QgsVectorLayerEditBuffer() = default;

void updateFields( QgsFields &fields );

//! Update feature with uncommitted geometry updates
void updateFeatureGeometry( QgsFeature &f );

Expand All @@ -257,7 +262,6 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject

protected:
QgsVectorLayer *L = nullptr;
friend class QgsVectorLayer;

friend class QgsVectorLayerUndoCommand;
friend class QgsVectorLayerUndoCommandAddFeature;
Expand Down
2 changes: 1 addition & 1 deletion src/core/vector/qgsvectorlayereditpassthrough.cpp
Expand Up @@ -32,7 +32,7 @@ bool QgsVectorLayerEditPassthrough::isModified() const

bool QgsVectorLayerEditPassthrough::modify( QgsVectorLayerUndoPassthroughCommand *cmd )
{
L->undoStack()->push( cmd ); // push takes owneship -> no need for cmd to be a smart ptr
L->undoStack()->push( cmd ); // push takes ownership -> no need for cmd to be a smart ptr
if ( cmd->hasError() )
return false;

Expand Down
16 changes: 10 additions & 6 deletions src/core/vector/qgsvectorlayerfeatureiterator.cpp
Expand Up @@ -71,12 +71,16 @@ QgsVectorLayerFeatureSource::QgsVectorLayerFeatureSource( const QgsVectorLayer *
else
{
#endif
mAddedFeatures = QgsFeatureMap( layer->editBuffer()->addedFeatures() );
mChangedGeometries = QgsGeometryMap( layer->editBuffer()->changedGeometries() );
mDeletedFeatureIds = QgsFeatureIds( layer->editBuffer()->deletedFeatureIds() );
mChangedAttributeValues = QgsChangedAttributesMap( layer->editBuffer()->changedAttributeValues() );
mAddedAttributes = QList<QgsField>( layer->editBuffer()->addedAttributes() );
mDeletedAttributeIds = QgsAttributeList( layer->editBuffer()->deletedAttributeIds() );
// If we are inside a transaction the iterator "sees" the current status
if ( layer->dataProvider() && ! layer->dataProvider()->transaction() )
{
mAddedFeatures = QgsFeatureMap( layer->editBuffer()->addedFeatures() );
mChangedGeometries = QgsGeometryMap( layer->editBuffer()->changedGeometries() );
mDeletedFeatureIds = QgsFeatureIds( layer->editBuffer()->deletedFeatureIds() );
mChangedAttributeValues = QgsChangedAttributesMap( layer->editBuffer()->changedAttributeValues() );
mAddedAttributes = QList<QgsField>( layer->editBuffer()->addedAttributes() );
mDeletedAttributeIds = QgsAttributeList( layer->editBuffer()->deletedAttributeIds() );
}
#if 0
}
#endif
Expand Down
5 changes: 1 addition & 4 deletions src/core/vector/qgsvectorlayerundocommand.cpp
Expand Up @@ -122,10 +122,7 @@ QgsVectorLayerUndoCommandChangeGeometry::QgsVectorLayerUndoCommandChangeGeometry
}
}

int QgsVectorLayerUndoCommandChangeGeometry::id() const
{
return 1;
}


bool QgsVectorLayerUndoCommandChangeGeometry::mergeWith( const QUndoCommand *other )
{
Expand Down
4 changes: 2 additions & 2 deletions src/core/vector/qgsvectorlayerundocommand.h
Expand Up @@ -131,8 +131,8 @@ class CORE_EXPORT QgsVectorLayerUndoCommandChangeGeometry : public QgsVectorLaye

void undo() override;
void redo() override;
int id() const override;
bool mergeWith( const QUndoCommand * ) override;
int id() const override { return 1; }
bool mergeWith( const QUndoCommand *other ) override;

private:
QgsFeatureId mFid;
Expand Down

0 comments on commit b3dae9a

Please sign in to comment.