@@ -5218,7 +5218,7 @@ void QgisApp::fileExit()
5218
5218
return ;
5219
5219
}
5220
5220
5221
- if ( checkUnsavedLayerEdits () && saveDirty () )
5221
+ if ( checkUnsavedLayerEdits () && checkMemoryLayers () && saveDirty () )
5222
5222
{
5223
5223
closeProject ();
5224
5224
userProfileManager ()->setDefaultFromActive ();
@@ -5253,7 +5253,7 @@ bool QgisApp::fileNew( bool promptToSaveFlag, bool forceBlank )
5253
5253
5254
5254
if ( promptToSaveFlag )
5255
5255
{
5256
- if ( !checkUnsavedLayerEdits () || !saveDirty () )
5256
+ if ( !checkUnsavedLayerEdits () || !checkMemoryLayers () || ! saveDirty () )
5257
5257
{
5258
5258
return false ; // cancel pressed
5259
5259
}
@@ -5347,7 +5347,7 @@ bool QgisApp::fileNewFromTemplate( const QString &fileName )
5347
5347
if ( checkTasksDependOnProject () )
5348
5348
return false ;
5349
5349
5350
- if ( !checkUnsavedLayerEdits () || !saveDirty () )
5350
+ if ( !checkUnsavedLayerEdits () || !checkMemoryLayers () || ! saveDirty () )
5351
5351
{
5352
5352
return false ; // cancel pressed
5353
5353
}
@@ -5646,7 +5646,7 @@ void QgisApp::fileOpen()
5646
5646
return ;
5647
5647
5648
5648
// possibly save any pending work before opening a new project
5649
- if ( checkUnsavedLayerEdits () && saveDirty () )
5649
+ if ( checkUnsavedLayerEdits () && checkMemoryLayers () && saveDirty () )
5650
5650
{
5651
5651
// Retrieve last used project dir from persistent settings
5652
5652
QgsSettings settings;
@@ -5680,7 +5680,7 @@ void QgisApp::fileRevert()
5680
5680
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::No )
5681
5681
return ;
5682
5682
5683
- if ( !checkUnsavedLayerEdits () )
5683
+ if ( !checkUnsavedLayerEdits () || ! checkMemoryLayers () )
5684
5684
return ;
5685
5685
5686
5686
// re-open the current project
@@ -6110,7 +6110,7 @@ void QgisApp::openProject( QAction *action )
6110
6110
return ;
6111
6111
6112
6112
QString debugme = action->data ().toString ();
6113
- if ( checkUnsavedLayerEdits () && saveDirty () )
6113
+ if ( checkUnsavedLayerEdits () && checkMemoryLayers () && saveDirty () )
6114
6114
addProject ( debugme );
6115
6115
}
6116
6116
@@ -6136,7 +6136,7 @@ void QgisApp::openProject( const QString &fileName )
6136
6136
return ;
6137
6137
6138
6138
// possibly save any pending work before opening a different project
6139
- if ( checkUnsavedLayerEdits () && saveDirty () )
6139
+ if ( checkUnsavedLayerEdits () && checkMemoryLayers () && saveDirty () )
6140
6140
{
6141
6141
// error handling and reporting is in addProject() function
6142
6142
addProject ( fileName );
@@ -10863,7 +10863,9 @@ bool QgisApp::saveDirty()
10863
10863
for ( QMap<QString, QgsMapLayer *>::iterator it = layers.begin (); it != layers.end (); ++it )
10864
10864
{
10865
10865
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value () );
10866
- if ( !vl )
10866
+ // note that we skip the unsaved edits check for memory layers -- it's misleading, because their contents aren't actually
10867
+ // saved if this is part of a project close operation. Instead we let these get picked up by checkMemoryLayers().
10868
+ if ( !vl || vl->dataProvider ()->name () == QLatin1String ( " memory" ) )
10867
10869
{
10868
10870
continue ;
10869
10871
}
@@ -10917,7 +10919,27 @@ bool QgisApp::saveDirty()
10917
10919
10918
10920
freezeCanvases ( false );
10919
10921
10920
- return answer != QMessageBox::Cancel;
10922
+ if ( answer == QMessageBox::Cancel )
10923
+ return false ;
10924
+
10925
+ // for memory layers, we discard all unsaved changes manually. Users have already been warned about
10926
+ // these by an earlier call to checkMemoryLayers(), and we don't want duplicate "unsaved changes" prompts
10927
+ // and anyway, saving the changes to a memory layer here won't actually save ANYTHING!
10928
+ // we do this at the very end here, because if the user opted to cancel above then ALL unsaved
10929
+ // changes in memory layers should still exist for them.
10930
+ const QMap<QString, QgsMapLayer *> layers = QgsProject::instance ()->mapLayers ();
10931
+ for ( auto it = layers.begin (); it != layers.end (); ++it )
10932
+ {
10933
+ if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value () ) )
10934
+ {
10935
+ if ( vl->dataProvider ()->name () == QLatin1String ( " memory" ) && vl->isEditable () && vl->isModified () )
10936
+ {
10937
+ vl->rollBack ();
10938
+ }
10939
+ }
10940
+ }
10941
+
10942
+ return true ;
10921
10943
}
10922
10944
10923
10945
bool QgisApp::checkUnsavedLayerEdits ()
@@ -10931,6 +10953,11 @@ bool QgisApp::checkUnsavedLayerEdits()
10931
10953
{
10932
10954
if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value () ) )
10933
10955
{
10956
+ // note that we skip the unsaved edits check for memory layers -- it's misleading, because their contents aren't actually
10957
+ // saved if this is part of a project close operation. Instead we let these get picked up by checkMemoryLayers()
10958
+ if ( vl->dataProvider ()->name () == QLatin1String ( " memory" ) )
10959
+ continue ;
10960
+
10934
10961
const bool hasUnsavedEdits = ( vl->isEditable () && vl->isModified () );
10935
10962
if ( !hasUnsavedEdits )
10936
10963
continue ;
@@ -10944,6 +10971,38 @@ bool QgisApp::checkUnsavedLayerEdits()
10944
10971
return true ;
10945
10972
}
10946
10973
10974
+ bool QgisApp::checkMemoryLayers ()
10975
+ {
10976
+ // check to see if there are any memory layers present (with features)
10977
+ bool hasMemoryLayers = false ;
10978
+ const QMap<QString, QgsMapLayer *> layers = QgsProject::instance ()->mapLayers ();
10979
+ for ( auto it = layers.begin (); it != layers.end (); ++it )
10980
+ {
10981
+ if ( it.value () && it.value ()->dataProvider ()->name () == QLatin1String ( " memory" ) )
10982
+ {
10983
+ QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value () );
10984
+ if ( vl && vl->featureCount () != 0 )
10985
+ {
10986
+ hasMemoryLayers = true ;
10987
+ break ;
10988
+ }
10989
+ }
10990
+ }
10991
+
10992
+ if ( hasMemoryLayers )
10993
+ {
10994
+ if ( QMessageBox::warning ( this ,
10995
+ tr ( " Close Project" ),
10996
+ tr ( " This project includes one or more temporary scratch layers. These layers are not saved to disk and their contents will be permanently lost. Are you sure you want to proceed?" ),
10997
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel ) == QMessageBox::Yes )
10998
+ return true ;
10999
+ else
11000
+ return false ;
11001
+ }
11002
+ else
11003
+ return true ;
11004
+ }
11005
+
10947
11006
bool QgisApp::checkTasksDependOnProject ()
10948
11007
{
10949
11008
QSet< QString > activeTaskDescriptions;
0 commit comments