@@ -5142,7 +5142,7 @@ void QgisApp::fileExit()
5142
5142
return;
5143
5143
}
5144
5144
5145
- if ( checkUnsavedLayerEdits() && saveDirty() )
5145
+ if ( checkUnsavedLayerEdits() && checkMemoryLayers() && saveDirty() )
5146
5146
{
5147
5147
closeProject();
5148
5148
userProfileManager()->setDefaultFromActive();
@@ -5177,7 +5177,7 @@ bool QgisApp::fileNew( bool promptToSaveFlag, bool forceBlank )
5177
5177
5178
5178
if ( promptToSaveFlag )
5179
5179
{
5180
- if ( !checkUnsavedLayerEdits() || !saveDirty() )
5180
+ if ( !checkUnsavedLayerEdits() || !checkMemoryLayers() || ! saveDirty() )
5181
5181
{
5182
5182
return false; //cancel pressed
5183
5183
}
@@ -5271,7 +5271,7 @@ bool QgisApp::fileNewFromTemplate( const QString &fileName )
5271
5271
if ( checkTasksDependOnProject() )
5272
5272
return false;
5273
5273
5274
- if ( !checkUnsavedLayerEdits() || !saveDirty() )
5274
+ if ( !checkUnsavedLayerEdits() || !checkMemoryLayers() || ! saveDirty() )
5275
5275
{
5276
5276
return false; //cancel pressed
5277
5277
}
@@ -5570,7 +5570,7 @@ void QgisApp::fileOpen()
5570
5570
return;
5571
5571
5572
5572
// possibly save any pending work before opening a new project
5573
- if ( checkUnsavedLayerEdits() && saveDirty() )
5573
+ if ( checkUnsavedLayerEdits() && checkMemoryLayers() && saveDirty() )
5574
5574
{
5575
5575
// Retrieve last used project dir from persistent settings
5576
5576
QgsSettings settings;
@@ -5604,7 +5604,7 @@ void QgisApp::fileRevert()
5604
5604
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::No )
5605
5605
return;
5606
5606
5607
- if ( !checkUnsavedLayerEdits() )
5607
+ if ( !checkUnsavedLayerEdits() || !checkMemoryLayers() )
5608
5608
return;
5609
5609
5610
5610
// re-open the current project
@@ -6034,7 +6034,7 @@ void QgisApp::openProject( QAction *action )
6034
6034
return;
6035
6035
6036
6036
QString debugme = action->data().toString();
6037
- if ( checkUnsavedLayerEdits() && saveDirty() )
6037
+ if ( checkUnsavedLayerEdits() && checkMemoryLayers() && saveDirty() )
6038
6038
addProject( debugme );
6039
6039
}
6040
6040
@@ -6060,7 +6060,7 @@ void QgisApp::openProject( const QString &fileName )
6060
6060
return;
6061
6061
6062
6062
// possibly save any pending work before opening a different project
6063
- if ( checkUnsavedLayerEdits() && saveDirty() )
6063
+ if ( checkUnsavedLayerEdits() && checkMemoryLayers() && saveDirty() )
6064
6064
{
6065
6065
// error handling and reporting is in addProject() function
6066
6066
addProject( fileName );
@@ -10777,7 +10777,9 @@ bool QgisApp::saveDirty()
10777
10777
for ( QMap<QString, QgsMapLayer *>::iterator it = layers.begin(); it != layers.end(); ++it )
10778
10778
{
10779
10779
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
10780
- if ( !vl )
10780
+ // note that we skip the unsaved edits check for memory layers -- it's misleading, because their contents aren't actually
10781
+ // saved if this is part of a project close operation. Instead we let these get picked up by checkMemoryLayers().
10782
+ if ( !vl || vl->dataProvider()->name() == QLatin1String( "memory" ) )
10781
10783
{
10782
10784
continue;
10783
10785
}
@@ -10831,7 +10833,27 @@ bool QgisApp::saveDirty()
10831
10833
10832
10834
freezeCanvases( false );
10833
10835
10834
- return answer != QMessageBox::Cancel;
10836
+ if ( answer == QMessageBox::Cancel )
10837
+ return false;
10838
+
10839
+ // for memory layers, we discard all unsaved changes manually. Users have already been warned about
10840
+ // these by an earlier call to checkMemoryLayers(), and we don't want duplicate "unsaved changes" prompts
10841
+ // and anyway, saving the changes to a memory layer here won't actually save ANYTHING!
10842
+ // we do this at the very end here, because if the user opted to cancel above then ALL unsaved
10843
+ // changes in memory layers should still exist for them.
10844
+ const QMap<QString, QgsMapLayer *> layers = QgsProject::instance()->mapLayers();
10845
+ for ( auto it = layers.begin(); it != layers.end(); ++it )
10846
+ {
10847
+ if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
10848
+ {
10849
+ if ( vl->dataProvider()->name() == QLatin1String( "memory" ) && vl->isEditable() && vl->isModified() )
10850
+ {
10851
+ vl->rollBack();
10852
+ }
10853
+ }
10854
+ }
10855
+
10856
+ return true;
10835
10857
}
10836
10858
10837
10859
bool QgisApp::checkUnsavedLayerEdits()
@@ -10845,6 +10867,11 @@ bool QgisApp::checkUnsavedLayerEdits()
10845
10867
{
10846
10868
if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
10847
10869
{
10870
+ // note that we skip the unsaved edits check for memory layers -- it's misleading, because their contents aren't actually
10871
+ // saved if this is part of a project close operation. Instead we let these get picked up by checkMemoryLayers()
10872
+ if ( vl->dataProvider()->name() == QLatin1String( "memory" ) )
10873
+ continue;
10874
+
10848
10875
const bool hasUnsavedEdits = ( vl->isEditable() && vl->isModified() );
10849
10876
if ( !hasUnsavedEdits )
10850
10877
continue;
@@ -10858,6 +10885,38 @@ bool QgisApp::checkUnsavedLayerEdits()
10858
10885
return true;
10859
10886
}
10860
10887
10888
+ bool QgisApp::checkMemoryLayers()
10889
+ {
10890
+ // check to see if there are any memory layers present (with features)
10891
+ bool hasMemoryLayers = false;
10892
+ const QMap<QString, QgsMapLayer *> layers = QgsProject::instance()->mapLayers();
10893
+ for ( auto it = layers.begin(); it != layers.end(); ++it )
10894
+ {
10895
+ if ( it.value() && it.value()->dataProvider()->name() == QLatin1String( "memory" ) )
10896
+ {
10897
+ QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() );
10898
+ if ( vl && vl->featureCount() != 0 )
10899
+ {
10900
+ hasMemoryLayers = true;
10901
+ break;
10902
+ }
10903
+ }
10904
+ }
10905
+
10906
+ if ( hasMemoryLayers )
10907
+ {
10908
+ if ( QMessageBox::warning( this,
10909
+ tr( "Close Project" ),
10910
+ 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?" ),
10911
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel ) == QMessageBox::Yes )
10912
+ return true;
10913
+ else
10914
+ return false;
10915
+ }
10916
+ else
10917
+ return true;
10918
+ }
10919
+
10861
10920
bool QgisApp::checkTasksDependOnProject()
10862
10921
{
10863
10922
QSet< QString > activeTaskDescriptions;
0 commit comments