Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix infinite loop in QgsVectorLayer::deleteSelectedFeatures if remova…
…l of feature fails
  • Loading branch information
manisandro committed Jan 19, 2015
1 parent 40ad3b0 commit 7b31a17
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 16 deletions.
2 changes: 1 addition & 1 deletion python/core/qgsvectorlayer.sip
Expand Up @@ -578,7 +578,7 @@ class QgsVectorLayer : QgsMapLayer
/** Deletes the selected features
* @return true in case of success and false otherwise
*/
bool deleteSelectedFeatures();
bool deleteSelectedFeatures(int* deletedCount = 0);

/**Adds a ring to polygon/multipolygon features
@return
Expand Down
13 changes: 7 additions & 6 deletions src/app/qgisapp.cpp
Expand Up @@ -5246,30 +5246,31 @@ void QgisApp::deleteSelected( QgsMapLayer *layer, QWidget* parent, bool promptCo
}

//validate selection
int numberOfDeletedFeatures = vlayer->selectedFeaturesIds().size();
if ( numberOfDeletedFeatures == 0 )
int numberOfSelectedFeatures = vlayer->selectedFeaturesIds().size();
if ( numberOfSelectedFeatures == 0 )
{
messageBar()->pushMessage( tr( "No Features Selected" ),
tr( "The current layer has no selected features" ),
QgsMessageBar::INFO, messageTimeout() );
return;
}
//display a warning
if ( promptConfirmation && QMessageBox::warning( parent, tr( "Delete features" ), tr( "Delete %n feature(s)?", "number of features to delete", numberOfDeletedFeatures ), QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
if ( promptConfirmation && QMessageBox::warning( parent, tr( "Delete features" ), tr( "Delete %n feature(s)?", "number of features to delete", numberOfSelectedFeatures ), QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
{
return;
}

vlayer->beginEditCommand( tr( "Features deleted" ) );
if ( !vlayer->deleteSelectedFeatures() )
int deletedCount = 0;
if ( !vlayer->deleteSelectedFeatures( &deletedCount ) )
{
messageBar()->pushMessage( tr( "Problem deleting features" ),
tr( "A problem occured during deletion of features" ),
tr( "A problem occured during deletion of %1 feature(s)" ).arg( numberOfSelectedFeatures - deletedCount ),
QgsMessageBar::WARNING );
}
else
{
showStatusMessage( tr( "%n feature(s) deleted.", "number of features deleted", numberOfDeletedFeatures ) );
showStatusMessage( tr( "%n feature(s) deleted.", "number of features deleted", numberOfSelectedFeatures ) );
}

vlayer->endEditCommand();
Expand Down
21 changes: 13 additions & 8 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -1036,7 +1036,7 @@ bool QgsVectorLayer::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
}


bool QgsVectorLayer::deleteSelectedFeatures()
bool QgsVectorLayer::deleteSelectedFeatures( int* deletedCount )
{
if ( !( mDataProvider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
{
Expand All @@ -1048,19 +1048,24 @@ bool QgsVectorLayer::deleteSelectedFeatures()
return false;
}

if ( mSelectedFeatureIds.size() == 0 )
return true;

while ( mSelectedFeatureIds.size() > 0 )
int deleted = 0;
int count = mSelectedFeatureIds.size();
// Make a copy since deleteFeature modifies mSelectedFeatureIds
QgsFeatureIds selectedFeatures( mSelectedFeatureIds );
foreach ( QgsFeatureId fid, selectedFeatures )
{
QgsFeatureId fid = *mSelectedFeatureIds.begin();
deleteFeature( fid ); // removes from selection
deleted += deleteFeature( fid ); // removes from selection
}

triggerRepaint();
updateExtents();

return true;
if ( deletedCount )
{
*deletedCount = deleted;
}

return deleted == count;
}

int QgsVectorLayer::addRing( const QList<QgsPoint>& ring )
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayer.h
Expand Up @@ -940,7 +940,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** Deletes the selected features
* @return true in case of success and false otherwise
*/
bool deleteSelectedFeatures();
bool deleteSelectedFeatures( int *deletedCount = 0 );

/**Adds a ring to polygon/multipolygon features
@return
Expand Down

0 comments on commit 7b31a17

Please sign in to comment.