CPF/CPF.ReoGrid/Common/ActionManager.cs
2024-06-24 10:15:59 +08:00

199 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace CPF.ReoGrid.Common
{
internal sealed class ActionManager
{
public List<IUndoableAction> UndoStack
{
get
{
return this.undoStack;
}
}
public Stack<IUndoableAction> 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<IUndoableAction>() > this.capacity;
if (flag3)
{
int count = this.undoStack.Count<IUndoableAction>() - this.capacity;
this.undoStack.RemoveRange(0, count);
Logger.Log(ActionManager.LOGKEY, "action stack full. remove " + count.ToString() + " action(s).");
}
}
EventHandler<ActionEventArgs> 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<IUndoableAction>() > 0;
}
public IAction Undo()
{
bool flag = this.undoStack.Count<IUndoableAction>() > 0;
IAction result;
if (flag)
{
IUndoableAction undoableAction = null;
while (this.undoStack.Count > 0)
{
undoableAction = this.undoStack.Last<IUndoableAction>();
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<ActionEventArgs> 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<ActionEventArgs> 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<ActionEventArgs> BeforePerformAction;
//[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public event EventHandler<ActionEventArgs> AfterPerformAction;
private static readonly string LOGKEY = "actionmanager";
private List<IUndoableAction> undoStack = new List<IUndoableAction>();
private Stack<IUndoableAction> redoStack = new Stack<IUndoableAction>();
private int capacity = 30;
}
}