Skip to content

Commit 02bd1cc

Browse files
committed
Improved UX when closing projects with layers with unsaved changes
Previously, the unsaved layer warnings would come AFTER the unsaved project warning. The unsaved layer warnings had no cancel option, which meant that there was no way to cancel a project close when unsaved layer edits exist, and you were forced to either save these edits or discard them. Now, the unsaved layer edits checks occur before the unsaved project check, and you have the option now to 'Cancel' the project close from the unsaved layer edits messagebox. This allows users to cancel the project close operation if they want to e.g. inspect manually unsaved layers to decide what action is appropriate to take on these. Also fixes the unsaved layer edits prompt sometimes didn't appear, even though unsaved changes were present...
1 parent e5604f9 commit 02bd1cc

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

src/app/qgisapp.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5218,7 +5218,7 @@ void QgisApp::fileExit()
52185218
return;
52195219
}
52205220

5221-
if ( saveDirty() )
5221+
if ( checkUnsavedLayerEdits() && saveDirty() )
52225222
{
52235223
closeProject();
52245224
userProfileManager()->setDefaultFromActive();
@@ -5253,7 +5253,7 @@ bool QgisApp::fileNew( bool promptToSaveFlag, bool forceBlank )
52535253

52545254
if ( promptToSaveFlag )
52555255
{
5256-
if ( !saveDirty() )
5256+
if ( !checkUnsavedLayerEdits() || !saveDirty() )
52575257
{
52585258
return false; //cancel pressed
52595259
}
@@ -5347,7 +5347,7 @@ bool QgisApp::fileNewFromTemplate( const QString &fileName )
53475347
if ( checkTasksDependOnProject() )
53485348
return false;
53495349

5350-
if ( !saveDirty() )
5350+
if ( !checkUnsavedLayerEdits() || !saveDirty() )
53515351
{
53525352
return false; //cancel pressed
53535353
}
@@ -5646,7 +5646,7 @@ void QgisApp::fileOpen()
56465646
return;
56475647

56485648
// possibly save any pending work before opening a new project
5649-
if ( saveDirty() )
5649+
if ( checkUnsavedLayerEdits() && saveDirty() )
56505650
{
56515651
// Retrieve last used project dir from persistent settings
56525652
QgsSettings settings;
@@ -5680,6 +5680,9 @@ void QgisApp::fileRevert()
56805680
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::No )
56815681
return;
56825682

5683+
if ( !checkUnsavedLayerEdits() )
5684+
return;
5685+
56835686
// re-open the current project
56845687
addProject( QgsProject::instance()->fileName() );
56855688
}
@@ -6107,7 +6110,7 @@ void QgisApp::openProject( QAction *action )
61076110
return;
61086111

61096112
QString debugme = action->data().toString();
6110-
if ( saveDirty() )
6113+
if ( checkUnsavedLayerEdits() && saveDirty() )
61116114
addProject( debugme );
61126115
}
61136116

@@ -6133,7 +6136,7 @@ void QgisApp::openProject( const QString &fileName )
61336136
return;
61346137

61356138
// possibly save any pending work before opening a different project
6136-
if ( saveDirty() )
6139+
if ( checkUnsavedLayerEdits() && saveDirty() )
61376140
{
61386141
// error handling and reporting is in addProject() function
61396142
addProject( fileName );
@@ -10917,6 +10920,30 @@ bool QgisApp::saveDirty()
1091710920
return answer != QMessageBox::Cancel;
1091810921
}
1091910922

10923+
bool QgisApp::checkUnsavedLayerEdits()
10924+
{
10925+
// check to see if there are any vector layers with unsaved provider edits
10926+
// to ensure user has opportunity to save any editing
10927+
if ( QgsProject::instance()->count() > 0 )
10928+
{
10929+
const QMap<QString, QgsMapLayer *> layers = QgsProject::instance()->mapLayers();
10930+
for ( auto it = layers.begin(); it != layers.end(); ++it )
10931+
{
10932+
if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
10933+
{
10934+
const bool hasUnsavedEdits = ( vl->isEditable() && vl->isModified() );
10935+
if ( !hasUnsavedEdits )
10936+
continue;
10937+
10938+
if ( !toggleEditing( vl, true ) )
10939+
return false;
10940+
}
10941+
}
10942+
}
10943+
10944+
return true;
10945+
}
10946+
1092010947
bool QgisApp::checkTasksDependOnProject()
1092110948
{
1092210949
QSet< QString > activeTaskDescriptions;

src/app/qgisapp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,17 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
17871787
* \returns true if saved or discarded, false if canceled
17881788
*/
17891789
bool saveDirty();
1790+
1791+
/**
1792+
* Checks for unsaved changes in open layers and prompts the user to save
1793+
* or discard these changes for each layer.
1794+
*
1795+
* Returns true if there are no unsaved layer edits remaining, or the user
1796+
* opted to discard them all. Returns false if the user opted to cancel
1797+
* on any layer.
1798+
*/
1799+
bool checkUnsavedLayerEdits();
1800+
17901801
//! Checks for running tasks dependent on the open project
17911802
bool checkTasksDependOnProject();
17921803

0 commit comments

Comments
 (0)