//============================================================================== bool UndoManager::perform (UndoableAction* const newAction, const String& actionName) { if (newAction != nullptr) { ScopedPointer<UndoableAction> action (newAction); if (reentrancyCheck) { jassertfalse; // don't call perform() recursively from the UndoableAction::perform() // or undo() methods, or else these actions will be discarded! return false; } if (actionName.isNotEmpty()) currentTransactionName = actionName; if (action->perform()) { ActionSet* actionSet = getCurrentSet(); if (actionSet != nullptr && ! newTransaction) { if (UndoableAction* const lastAction = actionSet->actions.getLast()) { if (UndoableAction* const coalescedAction = lastAction->createCoalescedAction (action)) { action = coalescedAction; totalUnitsStored -= lastAction->getSizeInUnits(); actionSet->actions.removeLast(); } } } else { actionSet = new ActionSet (currentTransactionName); transactions.insert (nextIndex, actionSet); ++nextIndex; } totalUnitsStored += action->getSizeInUnits(); actionSet->actions.add (action.release()); newTransaction = false; clearFutureTransactions(); sendChangeMessage(); return true; } } return false; }
//============================================================================== bool UndoManager::perform (UndoableAction* const command_, const String& actionName) { if (command_ != 0) { ScopedPointer<UndoableAction> command (command_); if (actionName.isNotEmpty()) currentTransactionName = actionName; if (reentrancyCheck) { jassertfalse; // don't call perform() recursively from the UndoableAction::perform() or // undo() methods, or else these actions won't actually get done. return false; } else if (command->perform()) { OwnedArray<UndoableAction>* commandSet = transactions [nextIndex - 1]; if (commandSet != 0 && ! newTransaction) { UndoableAction* lastAction = commandSet->getLast(); if (lastAction != 0) { UndoableAction* coalescedAction = lastAction->createCoalescedAction (command); if (coalescedAction != 0) { command = coalescedAction; totalUnitsStored -= lastAction->getSizeInUnits(); commandSet->removeLast(); } } } else { commandSet = new OwnedArray<UndoableAction>(); transactions.insert (nextIndex, commandSet); transactionNames.insert (nextIndex, currentTransactionName); ++nextIndex; } totalUnitsStored += command->getSizeInUnits(); commandSet->add (command.release()); newTransaction = false; while (nextIndex < transactions.size()) { const OwnedArray <UndoableAction>* const lastSet = transactions.getLast(); for (int i = lastSet->size(); --i >= 0;) totalUnitsStored -= lastSet->getUnchecked (i)->getSizeInUnits(); transactions.removeLast(); transactionNames.remove (transactionNames.size() - 1); } while (nextIndex > 0 && totalUnitsStored > maxNumUnitsToKeep && transactions.size() > minimumTransactionsToKeep) { const OwnedArray <UndoableAction>* const firstSet = transactions.getFirst(); for (int i = firstSet->size(); --i >= 0;) totalUnitsStored -= firstSet->getUnchecked (i)->getSizeInUnits(); jassert (totalUnitsStored >= 0); // something fishy going on if this fails! transactions.remove (0); transactionNames.remove (0); --nextIndex; } sendChangeMessage(); return true; } } return false; }