void UndoManager::getActionsInCurrentTransaction (Array<const UndoableAction*>& actionsFound) const { if (! newTransaction) if (auto* s = getCurrentSet()) for (auto* a : s->actions) actionsFound.add (a); }
String UndoManager::getUndoDescription() const { if (auto* s = getCurrentSet()) return s->name; return {}; }
Time UndoManager::getTimeOfUndoTransaction() const { if (auto* s = getCurrentSet()) return s->time; return {}; }
void UndoManager::setCurrentTransactionName (const String& newName) noexcept { if (newTransaction) newTransactionName = newName; else if (auto* action = getCurrentSet()) action->name = newName; }
String UndoManager::getCurrentTransactionName() const noexcept { if (auto* action = getCurrentSet()) return action->name; return newTransactionName; }
void UndoManager::getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const { if (! newTransaction) if (const ActionSet* const s = getCurrentSet()) for (int i = 0; i < s->actions.size(); ++i) actionsFound.add (s->actions.getUnchecked(i)); }
Time UndoManager::getTimeOfUndoTransaction() const { if (const ActionSet* const s = getCurrentSet()) return s->time; return Time(); }
String UndoManager::getUndoDescription() const { if (const ActionSet* const s = getCurrentSet()) return s->name; return String::empty; }
int UndoManager::getNumActionsInCurrentTransaction() const { if (! newTransaction) if (auto* s = getCurrentSet()) return s->actions.size(); return 0; }
//============================================================================== 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* newAction) { if (newAction != nullptr) { std::unique_ptr<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 (action->perform()) { auto* actionSet = getCurrentSet(); if (actionSet != nullptr && ! newTransaction) { if (auto* lastAction = actionSet->actions.getLast()) { if (auto coalescedAction = lastAction->createCoalescedAction (action.get())) { action.reset (coalescedAction); totalUnitsStored -= lastAction->getSizeInUnits(); actionSet->actions.removeLast(); } } } else { actionSet = new ActionSet (newTransactionName); transactions.insert (nextIndex, actionSet); ++nextIndex; } totalUnitsStored += action->getSizeInUnits(); actionSet->actions.add (action.release()); newTransaction = false; moveFutureTransactionsToStash(); dropOldTransactionsIfTooLarge(); sendChangeMessage(); return true; } } return false; }
bool UndoManager::undo() { if (auto* s = getCurrentSet()) { const ScopedValueSetter<bool> setter (reentrancyCheck, true); if (s->undo()) --nextIndex; else clearUndoHistory(); beginNewTransaction(); sendChangeMessage(); return true; } return false; }
bool UndoManager::canUndo() const noexcept { return getCurrentSet() != nullptr; }