diff --git a/modules/juce_data_structures/undomanager/juce_UndoManager.cpp b/modules/juce_data_structures/undomanager/juce_UndoManager.cpp index 4dc27b870e..e552bb8630 100644 --- a/modules/juce_data_structures/undomanager/juce_UndoManager.cpp +++ b/modules/juce_data_structures/undomanager/juce_UndoManager.cpp @@ -153,7 +153,8 @@ bool UndoManager::perform (UndoableAction* const newAction) actionSet->actions.add (action.release()); newTransaction = false; - clearFutureTransactions(); + moveFutureTransactionsToStash(); + dropOldTransactionsIfTooLarge(); sendChangeMessage(); return true; } @@ -162,14 +163,36 @@ bool UndoManager::perform (UndoableAction* const newAction) return false; } -void UndoManager::clearFutureTransactions() +void UndoManager::moveFutureTransactionsToStash() { - while (nextIndex < transactions.size()) + if (nextIndex < transactions.size()) { - totalUnitsStored -= transactions.getLast()->getTotalSize(); - transactions.removeLast(); + stashedFutureTransactions.clear(); + + while (nextIndex < transactions.size()) + { + totalUnitsStored -= transactions.getLast()->getTotalSize(); + stashedFutureTransactions.add (transactions.removeAndReturn (nextIndex)); + } + } +} + +void UndoManager::restoreStashedFutureTransactions() +{ + jassert (nextIndex == transactions.size()); + + for (int i = 0; i < stashedFutureTransactions.size(); ++i) + { + ActionSet* action = stashedFutureTransactions.removeAndReturn (i); + totalUnitsStored += action->getTotalSize(); + transactions.add (action); } + stashedFutureTransactions.clearQuick (false); +} + +void UndoManager::dropOldTransactionsIfTooLarge() +{ while (nextIndex > 0 && totalUnitsStored > maxNumUnitsToKeep && transactions.size() > minimumTransactionsToKeep) @@ -290,7 +313,13 @@ Time UndoManager::getTimeOfRedoTransaction() const bool UndoManager::undoCurrentTransactionOnly() { - return newTransaction ? false : undo(); + if ((! newTransaction) && undo()) + { + restoreStashedFutureTransactions(); + return true; + } + + return false; } void UndoManager::getActionsInCurrentTransaction (Array& actionsFound) const diff --git a/modules/juce_data_structures/undomanager/juce_UndoManager.h b/modules/juce_data_structures/undomanager/juce_UndoManager.h index 1e740eea3d..4bb9cf997f 100644 --- a/modules/juce_data_structures/undomanager/juce_UndoManager.h +++ b/modules/juce_data_structures/undomanager/juce_UndoManager.h @@ -229,13 +229,15 @@ private: //============================================================================== struct ActionSet; friend struct ContainerDeletePolicy; - OwnedArray transactions; + OwnedArray transactions, stashedFutureTransactions; String newTransactionName; int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex; bool newTransaction, reentrancyCheck; ActionSet* getCurrentSet() const noexcept; ActionSet* getNextSet() const noexcept; - void clearFutureTransactions(); + void moveFutureTransactionsToStash(); + void restoreStashedFutureTransactions(); + void dropOldTransactionsIfTooLarge(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) };