Example #1
0
        UnitResult Undo()
        {
            if (globallyRepeatableUnits.Count < 1)
            {
                throw new InvalidOperationException("No unit to undo.");
            }

            IUndoableUnit undoableUnit   = globallyUndoableUnits.Pop();
            IInternalUnit repeatableUnit = globallyRepeatableUnits.Pop();

            var eventArgs = new CancellableUndoServiceEventArgs(undoableUnit);

            OnUndoing(eventArgs);
            if (eventArgs.Cancel)
            {
                globallyUndoableUnits.AddLast(undoableUnit);
                globallyRepeatableUnits.AddLast(repeatableUnit);
                return(UnitResult.Cancelled);
            }

            globallyRedoableUnits.AddLast(undoableUnit);

            UnitResult result = undoableUnit.Undo();

            OnUndone(new UndoServiceEventArgs(undoableUnit));
            return(result);
        }
Example #2
0
        /// <summary>
        /// Undoes the execution of a previous <see cref="IUnit"/>.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Occurs if there are no previously executed units to undo.</exception>
        public UnitResult Undo(object ownerKey)
        {
            if (ownerKey == null)
            {
                return(Undo());
            }

            if (!undoableDictionary.TryGetValue(ownerKey,
                                                out UnitCollection <IUndoableUnit> undoableUnits))
            {
                throw new InvalidOperationException("No undoable units for the specified owner key.");
            }

            IUndoableUnit undoableUnit = undoableUnits.Pop();

            if (!repeatableDictionary.TryGetValue(ownerKey,
                                                  out UnitCollection <IInternalUnit> repeatableUnits))
            {
                throw new InvalidOperationException("No repeatable units for the specified owner key.");
            }

            repeatableUnits.RemoveLast();

            var eventArgs = new CancellableUndoServiceEventArgs(undoableUnit)
            {
                OwnerKey = ownerKey
            };

            OnUndoing(eventArgs);
            if (eventArgs.Cancel)
            {
                undoableUnits.AddLast(undoableUnit);
                return(UnitResult.Cancelled);
            }

            if (!redoableDictionary.TryGetValue(ownerKey,
                                                out UnitCollection <IUndoableUnit> redoableUnits))
            {
                redoableUnits = new UnitCollection <IUndoableUnit>();
                redoableDictionary[ownerKey] = redoableUnits;
            }
            redoableUnits.AddLast(undoableUnit);

            var result = undoableUnit.Undo();

            TrimIfRequired(ownerKey);

            OnUndone(new UndoServiceEventArgs(undoableUnit));
            return(result);
        }
Example #3
0
        /// <summary>
        /// Performs the execution of a <see cref="IUnit"/>
        /// instance that has been undone, then places it back
        /// into the command stack.
        /// </summary>
        public UnitResult Redo(object ownerKey)
        {
            if (ownerKey == null)
            {
                return(Redo());
            }

            if (!redoableDictionary.TryGetValue(ownerKey,
                                                out UnitCollection <IUndoableUnit> redoableUnits))
            {
                throw new InvalidOperationException("No units to be redone for the specified owner key.");
            }
            IUndoableUnit unit = redoableUnits.Pop();

            var eventArgs = new CancellableUndoServiceEventArgs(unit);

            OnRedoing(eventArgs);

            if (eventArgs.Cancel)
            {
                redoableUnits.AddLast(unit);
                return(UnitResult.Cancelled);
            }

            var internalUnit = (IInternalUnit)unit;

            if (!repeatableDictionary.TryGetValue(ownerKey,
                                                  out UnitCollection <IInternalUnit> repeatableUnits))
            {
                repeatableUnits = new UnitCollection <IInternalUnit>();
            }
            repeatableUnits.AddLast(internalUnit);

            if (!undoableDictionary.TryGetValue(ownerKey,
                                                out UnitCollection <IUndoableUnit> undoableUnits))
            {
                undoableUnits = new UnitCollection <IUndoableUnit>();
            }
            undoableUnits.AddLast(unit);

            UnitResult result = internalUnit.PerformUnit(internalUnit.Argument, UnitMode.Redo);

            TrimIfRequired(ownerKey);

            OnRedone(new UndoServiceEventArgs(unit));
            return(result);
        }