예제 #1
0
        public IAction Undo()
        {
            if (undoStack.Count() > 0)
            {
                IUndoableAction action = null;
                while (undoStack.Count > 0)
                {
                    action = undoStack.Last();
                    Logger.Log(LOGKEY, "undo action: " + action.ToString());

                    if (BeforePerformAction != null)
                    {
                        var arg = new ActionEventArgs(action, ActionBehavior.Undo);
                        BeforePerformAction(this, new ActionEventArgs(action, ActionBehavior.Undo));
                        if (arg.Cancel) break;
                    }

                    undoStack.Remove(action);
                    action.Undo();
                    redoStack.Push(action);
                    if (AfterPerformAction != null) AfterPerformAction(this, new ActionEventArgs(action, ActionBehavior.Undo));

                    if (!(action is ISerialUndoAction)) break;
                }
                return action;
            }
            return null;
        }
예제 #2
0
        /*
         * isCanUndo attribute specifies whether the action can be undo.
         * sometimes an action doesn't need undo even it's a IUndoable action.
         * the action will not be pushed in undo stack after performed immediately.
         */
        private void Do(IAction action, bool perform, bool isCanUndo)
        {
            Logger.Log(LOGKEY, string.Format("{0} action: {1}[{2}]", perform ? "do" : "add", action.GetType().Name, action.GetName()));

            if (BeforePerformAction != null)
            {
                var arg = new ActionEventArgs(action, ActionBehavior.Do);
                BeforePerformAction(this, arg);
                if (arg.Cancel) return;
            }

            if (perform) action.Do();

            if (action is IUndoableAction && isCanUndo)
            {
                redoStack.Clear();
                undoStack.Add(action as IUndoableAction);

                if(undoStack.Count() > capacity)
                {
                    undoStack.RemoveRange(0, undoStack.Count() - capacity);
                    Logger.Log(LOGKEY, "action stack full. remove " + (capacity - undoStack.Count()) + " action(s).");
                }
            }

            if (AfterPerformAction != null) AfterPerformAction(this, new ActionEventArgs(action, ActionBehavior.Do));
        }
예제 #3
0
        public IAction Redo()
        {
            if (redoStack.Count > 0)
            {
                IUndoableAction action = null;
                while (redoStack.Count > 0)
                {
                    action = redoStack.Pop();
                    Logger.Log(LOGKEY, "redo action: " + action.ToString());

                    if (BeforePerformAction != null)
                    {
                        var arg = new ActionEventArgs(action, ActionBehavior.Redo);
                        BeforePerformAction(this, arg);
                        if (arg.Cancel) break;
                    }

                    action.Do();
                    undoStack.Add(action);
                    if (AfterPerformAction != null) AfterPerformAction(this, new ActionEventArgs(action, ActionBehavior.Redo));

                    if (!(action is ISerialUndoAction)) break;
                }
                return action;
            }
            else
                return null;
        }