/// <summary> /// Undo's the action done with <see cref="Do"/>. /// </summary> protected internal override void Undo() { PopCommandQueueFromActiveStackIfRequired(); // first undo commands in own command queue from back to front, that is: from the active command in the own command queue while (this.OwnCommandQueue.CanUndo) { this.OwnCommandQueue.UndoPreviousCommand(); } // then, if we're not in an Undoable period clear the own command queue and rollback ourselves. if (!CommandQueueManagerSingleton.GetInstance().IsInUndoablePeriod) { this.OwnCommandQueue.Clear(); } if (_useParameterLessUndo) { if (_undoFunc0 != null) { // undo ourselves, by setting the original state back using the undoFunc0. This func is responsible for the original state to set back. _undoFunc0(); } } else { if (_undoFunc1 != null) { // undo ourselves, by setting the original state back to the state we gathered using the getStateFunc _undoFunc1(_originalState); } } }
/// <summary> /// Enqueues the command specified and makes it the current command. /// </summary> /// <param name="toEnqueue">To enqueue.</param> /// <returns>true if enqueue action succeeded, false otherwise</returns> public bool EnqueueCommand(CommandBase toEnqueue) { ArgumentVerifier.CantBeNull(toEnqueue, "toEnqueue"); if (CommandQueueManagerSingleton.GetInstance().IsInUndoablePeriod) { // ignore, all commands are already there in this mode and this command therefore already is either there or is not important return(false); } if (this.UndoInProgress) { if (CommandQueueManager.ThrowExceptionOnDoDuringUndo) { // can't add new commands to a queue of a command which executed an undoFunc. This happens through bugs in the using code so we have to // thrown an exception to illustrate that there's a problem with the code using this library. throw new DoDuringUndoException(); } // ignore return(false); } // clear queue from the active index if (_currentCommandBucket == null) { // clear the complete queue from any commands which might have been undone, as the new command makes them unreachable. _commands.Clear(); } else { _commands.RemoveAfter(_currentCommandBucket); } _commands.InsertAfter(new ListBucket <CommandBase>(toEnqueue), _currentCommandBucket); return(true); }
/// <summary> /// Pops the command queue from active stack if required. /// </summary> internal void PopCommandQueueFromActiveStackIfRequired() { if (_commandQueuePushed) { CommandQueueManagerSingleton.GetInstance().PopCommandQueueFromActiveStack(); _commandQueuePushed = false; } }
/// <summary> /// Pushes the command queue on active stack if required. /// </summary> internal void PushCommandQueueOnActiveStackIfRequired() { if (!_commandQueuePushed) { CommandQueueManagerSingleton.GetInstance().PushCommandQueueOnActiveStack(this.OwnCommandQueue); _commandQueuePushed = true; } }
/// <summary> /// Re-executes the command. Normally this is simply calling 'Do', however in an undoable period redo it's calling PerformRedo. /// </summary> protected internal virtual void Redo() { if (CommandQueueManagerSingleton.GetInstance().IsInUndoablePeriod) { PerformRedo(); } else { Do(); } }
/// <summary> /// Undo's the action done with <see cref="Do"/>. /// </summary> protected internal override void Undo() { try { _originalIsInUndoablePeriodFlagValue = CommandQueueManagerSingleton.GetInstance().IsInUndoablePeriod; CommandQueueManagerSingleton.GetInstance().SetUndoablePeriodFlag(true); base.Undo(); } finally { CommandQueueManagerSingleton.GetInstance().SetUndoablePeriodFlag(_originalIsInUndoablePeriodFlagValue); } }
/// <summary> /// Re-executes the command. Normally this is simply calling 'Do', however in an undoable period redo it's calling PerformRedo. /// </summary> protected internal override void Redo() { try { _originalIsInUndoablePeriodFlagValue = CommandQueueManagerSingleton.GetInstance().IsInUndoablePeriod; CommandQueueManagerSingleton.GetInstance().SetUndoablePeriodFlag(true); base.Redo(); } finally { CommandQueueManagerSingleton.GetInstance().SetUndoablePeriodFlag(_originalIsInUndoablePeriodFlagValue); // perform pop on queue, as our queue was pushed on the stack by the Do() method which was called by the Redo method this.PopCommandQueueFromActiveStackIfRequired(); } }
/// <summary> /// Enqueues and runs a new command by passing the function specified. Use this shortcut to wrap several statements into a single undo block. /// </summary> /// <param name="doFunc">The do func.</param> /// <param name="undoFunc">The undo func.</param> /// <param name="description">The description.</param> public static void DoNow(Action doFunc, Action undoFunc, string description) { CommandQueueManagerSingleton.GetInstance().EnqueueAndRunCommand(new Command <TState>(doFunc, undoFunc, description)); }