Example #1
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;
}
Example #2
0
//==============================================================================
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;
}