using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace CPF.ReoGrid.Common { internal sealed class ActionManager { public List UndoStack { get { return this.undoStack; } } public Stack RedoStack { get { return this.redoStack; } } public void DoAction(IAction action) { this.DoAction(action, true); } public void AddAction(IAction action) { this.DoAction(action, false); } private void DoAction(IAction action, bool perform) { this.Do(action, perform, action is IUndoableAction); } private void Do(IAction action, bool perform, bool isCanUndo) { Logger.Log(ActionManager.LOGKEY, string.Format("{0} action: {1}[{2}]", perform ? "do" : "add", action.GetType().Name, action.GetName())); bool flag = this.BeforePerformAction != null; if (flag) { ActionEventArgs actionEventArgs = new ActionEventArgs(action, ActionBehavior.Do); this.BeforePerformAction(this, actionEventArgs); bool cancel = actionEventArgs.Cancel; if (cancel) { return; } } if (perform) { action.Do(); } bool flag2 = action is IUndoableAction && isCanUndo; if (flag2) { this.redoStack.Clear(); this.undoStack.Add(action as IUndoableAction); bool flag3 = this.undoStack.Count() > this.capacity; if (flag3) { int count = this.undoStack.Count() - this.capacity; this.undoStack.RemoveRange(0, count); Logger.Log(ActionManager.LOGKEY, "action stack full. remove " + count.ToString() + " action(s)."); } } EventHandler afterPerformAction = this.AfterPerformAction; if (afterPerformAction != null) { afterPerformAction(this, new ActionEventArgs(action, ActionBehavior.Do)); } } public void Reset() { this.redoStack.Clear(); this.undoStack.Clear(); } public bool CanUndo() { return this.undoStack.Count > 0; } public bool CanRedo() { return this.redoStack.Count() > 0; } public IAction Undo() { bool flag = this.undoStack.Count() > 0; IAction result; if (flag) { IUndoableAction undoableAction = null; while (this.undoStack.Count > 0) { undoableAction = this.undoStack.Last(); Logger.Log(ActionManager.LOGKEY, "undo action: " + undoableAction.ToString()); bool flag2 = this.BeforePerformAction != null; if (flag2) { ActionEventArgs actionEventArgs = new ActionEventArgs(undoableAction, ActionBehavior.Undo); this.BeforePerformAction(this, new ActionEventArgs(undoableAction, ActionBehavior.Undo)); bool cancel = actionEventArgs.Cancel; if (cancel) { break; } } this.undoStack.Remove(undoableAction); undoableAction.Undo(); this.redoStack.Push(undoableAction); EventHandler afterPerformAction = this.AfterPerformAction; if (afterPerformAction != null) { afterPerformAction(this, new ActionEventArgs(undoableAction, ActionBehavior.Undo)); } bool flag3 = !(undoableAction is ISerialUndoAction); if (flag3) { break; } } result = undoableAction; } else { result = null; } return result; } public IAction Redo() { bool flag = this.redoStack.Count > 0; IAction result; if (flag) { IUndoableAction undoableAction = null; while (this.redoStack.Count > 0) { undoableAction = this.redoStack.Pop(); Logger.Log(ActionManager.LOGKEY, "redo action: " + undoableAction.ToString()); bool flag2 = this.BeforePerformAction != null; if (flag2) { ActionEventArgs actionEventArgs = new ActionEventArgs(undoableAction, ActionBehavior.Redo); this.BeforePerformAction(this, actionEventArgs); bool cancel = actionEventArgs.Cancel; if (cancel) { break; } } undoableAction.Redo(); this.undoStack.Add(undoableAction); EventHandler afterPerformAction = this.AfterPerformAction; if (afterPerformAction != null) { afterPerformAction(this, new ActionEventArgs(undoableAction, ActionBehavior.Redo)); } bool flag3 = !(undoableAction is ISerialUndoAction); if (flag3) { break; } } result = undoableAction; } else { result = null; } return result; } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event EventHandler BeforePerformAction; //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event EventHandler AfterPerformAction; private static readonly string LOGKEY = "actionmanager"; private List undoStack = new List(); private Stack redoStack = new Stack(); private int capacity = 30; } }