mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-01 16:19:43 +02:00
Fix exception handling, as when trying to edit read-only database... (#607)
... Problem is that the delayed undo handling (in the lambda in AudacityApp :: OnExceptionInMainLoop) should itself have only non-throwing steps. But there was a redundant attempt at autosaving in ProjectHistory :: RollbackState, which itself requires another data base write. But when "rolling back" the in-memory structures to whatever the current state of undo history is, we can assume that any required autosave was completed before the current state of undo history was set. So for rollback only, do not autosave again when discarding changes and restoring the state. (But do it still, throwing on failure, when moving around in the undo history, among saved states. We do want to keep the last autosave consistent with the in-memory state.)
This commit is contained in:
parent
af6a23696b
commit
88ba35f520
@ -115,7 +115,7 @@ void ProjectHistory::RollbackState()
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &undoManager = UndoManager::Get( project );
|
||||
SetStateTo( undoManager.GetCurrentState() );
|
||||
SetStateTo( undoManager.GetCurrentState(), false );
|
||||
}
|
||||
|
||||
void ProjectHistory::ModifyState(bool bWantsAutoSave)
|
||||
@ -137,11 +137,12 @@ void ProjectHistory::ModifyState(bool bWantsAutoSave)
|
||||
// LL: Is there a memory leak here as "l" and "t" are not deleted???
|
||||
// Vaughan, 2010-08-29: No, as "l" is a TrackList* of an Undo stack state.
|
||||
// Need to keep it and its tracks "t" available for Undo/Redo/SetStateTo.
|
||||
void ProjectHistory::PopState(const UndoState &state)
|
||||
void ProjectHistory::PopState(const UndoState &state, bool doAutosave)
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &projectFileIO = ProjectFileIO::Get( project );
|
||||
AutoSaveOrThrow( projectFileIO );
|
||||
if (doAutosave)
|
||||
AutoSaveOrThrow( projectFileIO );
|
||||
|
||||
// remaining no-fail operations "commit" the changes of undo manager state
|
||||
auto &dstTracks = TrackList::Get( project );
|
||||
@ -163,11 +164,12 @@ void ProjectHistory::PopState(const UndoState &state)
|
||||
|
||||
}
|
||||
|
||||
void ProjectHistory::SetStateTo(unsigned int n)
|
||||
void ProjectHistory::SetStateTo(unsigned int n, bool doAutosave)
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &undoManager = UndoManager::Get( project );
|
||||
|
||||
undoManager.SetStateTo(n,
|
||||
[this]( const UndoState &state ){ PopState(state); } );
|
||||
[this, doAutosave]( const UndoState &state ){
|
||||
PopState(state, doAutosave); } );
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
~ProjectHistory() override;
|
||||
|
||||
void InitialState();
|
||||
void SetStateTo(unsigned int n);
|
||||
void SetStateTo(unsigned int n, bool doAutosave = true);
|
||||
bool UndoAvailable() const;
|
||||
bool RedoAvailable() const;
|
||||
void PushState(
|
||||
@ -46,7 +46,7 @@ public:
|
||||
// Should set only if you really want the state change restored after
|
||||
// a crash, as it can take many seconds for large (eg. 10 track-hours)
|
||||
// projects
|
||||
void PopState(const UndoState &state);
|
||||
void PopState(const UndoState &state, bool doAutosave = true);
|
||||
|
||||
bool GetDirty() const { return mDirty; }
|
||||
void SetDirty( bool value ) { mDirty = value; }
|
||||
|
@ -305,7 +305,8 @@ void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
|
||||
auto state = UndoManager::Get( *project ).GetCurrentState();
|
||||
auto cleanup = finally( [&] {
|
||||
if(!success)
|
||||
ProjectHistory::Get( *project ).SetStateTo( state );
|
||||
// This is like a rollback of state
|
||||
ProjectHistory::Get( *project ).SetStateTo( state, false );
|
||||
} );
|
||||
|
||||
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user