@@ -41,6 +41,7 @@ processing. See also MacrosWindow and ApplyMacroDialog.
4141#include " SelectUtilities.h"
4242#include " Shuttle.h"
4343#include " Track.h"
44+ #include " UndoManager.h"
4445
4546#include " AllThemeResources.h"
4647
@@ -728,6 +729,9 @@ bool MacroCommands::ApplyMacro(
728729
729730 // Save the project state before making any changes. It will be rolled
730731 // back if an error occurs.
732+ // It also causes any calls to ModifyState (such as by simple
733+ // view-changing commands) to append changes to this state, not to the
734+ // previous state in history. See Bug 2076
731735 if (proj) {
732736 ProjectHistory::Get (*proj).PushState (longDesc, shortDesc);
733737 }
@@ -736,8 +740,18 @@ bool MacroCommands::ApplyMacro(
736740 // Upon exit of the top level apply, roll back the state if an error occurs.
737741 auto cleanup2 = finally ([&, macroReentryCount = MacroReentryCount] {
738742 if (macroReentryCount == 1 && !res && proj) {
739- // Macro failed or was cancelled; revert to the previous state
740- ProjectHistory::Get (*proj).RollbackState ();
743+ // Be sure that exceptions do not escape this destructor
744+ GuardedCall ([&]{
745+ // Macro failed or was cancelled; revert to the previous state
746+ auto &history = ProjectHistory::Get (*proj);
747+ history.RollbackState ();
748+ // The added undo state is now vacuous. Remove it (Bug 2759)
749+ auto &undoManager = UndoManager::Get (*proj);
750+ undoManager.Undo (
751+ [&]( const UndoStackElem &elem ){
752+ history.PopState ( elem.state ); } );
753+ undoManager.AbandonRedo ();
754+ });
741755 }
742756 });
743757
0 commit comments