Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ensures QgsVectorLayer::featuresDeleted is only called once and with all
deleted FIDs when changes are commited by QgsVectorLayer::commitChanges

implemented related test
(testCommitChangesReportsDeletedFeatureIDs(self)) in
test_qgsvectorlayer.py

Fixes #45228
  • Loading branch information
jakimowb committed Oct 26, 2021
1 parent 570d754 commit 5a36681
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/core/vector/qgsvectorlayer.cpp
Expand Up @@ -3475,7 +3475,15 @@ bool QgsVectorLayer::commitChanges( bool stopEditing )
if ( !mAllowCommit )
return false;

mCommitChangesActive = true;
bool success = mEditBuffer->commitChanges( mCommitErrors );
mCommitChangesActive = false;

if ( !mDeletedFids.empty() )
{
emit featuresDeleted( mDeletedFids );
mDeletedFids.clear();
}

if ( success )
{
Expand Down Expand Up @@ -5286,7 +5294,7 @@ void QgsVectorLayer::onJoinedFieldsChanged()

void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid )
{
if ( mEditCommandActive )
if ( mEditCommandActive || mCommitChangesActive )
{
mDeletedFids << fid;
}
Expand Down
3 changes: 3 additions & 0 deletions src/core/vector/qgsvectorlayer.h
Expand Up @@ -2951,6 +2951,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
//! True while an undo command is active
bool mEditCommandActive = false;

//! True while a commit is active
bool mCommitChangesActive = false;

bool mReadExtentFromXml;
QgsRectangle mXmlExtent;

Expand Down
26 changes: 26 additions & 0 deletions tests/src/python/test_qgsvectorlayer.py
Expand Up @@ -3660,6 +3660,32 @@ def onFeaturesDeleted(deleted_fids):
self.assertEqual(layer.featureCount(), 0)
self.assertEqual(layer.selectedFeatureIds(), [])

def testCommitChangesReportsDeletedFeatureIDs(self):
"""
Tests if commitChanges emits "featuresDeleted" with all deleted feature IDs,
e.g. in case (negative) temporary FIDs are converted into (positive) persistent FIDs.
"""
temp_fids = []

def onFeaturesDeleted(deleted_fids):
self.assertEqual(len(deleted_fids), len(temp_fids),
msg=f'featuresDeleted returned {len(deleted_fids)} instead of 2 deleted feature IDs: '
f'{deleted_fids}')
for d in deleted_fids:
self.assertTrue(d in temp_fids)

layer = QgsVectorLayer("point?crs=epsg:4326&field=name:string", "Scratch point layer", "memory")
layer.featuresDeleted.connect(onFeaturesDeleted)

layer.startEditing()
layer.beginEditCommand(f'add 2 features')
layer.addFeature(QgsFeature(layer.fields()))
layer.addFeature(QgsFeature(layer.fields()))
layer.endEditCommand()
temp_fids.extend(layer.allFeatureIds())

layer.commitChanges()

def testSubsetStringInvalidLayer(self):
"""
Test that subset strings can be set on invalid layers, and retrieved later...
Expand Down

0 comments on commit 5a36681

Please sign in to comment.