comparison Commands/CommandStack.cs @ 0:961030992bd2

Initial commit of IBBoard libraries
author IBBoard <dev@ibboard.co.uk>
date Fri, 19 Dec 2008 11:13:48 +0000
parents
children 0352fa33ee8f
comparison
equal deleted inserted replaced
-1:000000000000 0:961030992bd2
1 using System;
2 using System.Collections;
3
4 namespace IBBoard.Commands
5 {
6 /// <summary>
7 /// Summary description for CommandStack.
8 /// </summary>
9 public class CommandStack
10 {
11 private ArrayList commandStack;
12 private int listPos = -1;
13 private int listMax = -1;
14 private int cleanPos;
15
16 public event MethodInvoker CommandStackUpdated;
17
18 public CommandStack()
19 {
20 commandStack = new ArrayList(10);
21 cleanPos = -1;
22 }
23
24 public bool IsDirty()
25 {
26 return listPos!=cleanPos;
27 }
28
29 public void setCleanMark()
30 {
31 cleanPos = listPos;
32 }
33
34 public bool IsEmpty()
35 {
36 return listMax == -1;
37 }
38
39 public bool CanUndo()
40 {
41 return listPos > -1;
42 }
43
44 public int UndoLength
45 {
46 get { return listPos + 1; }
47 }
48
49 public int RedoLength
50 {
51 get { return listMax - listPos; }
52 }
53
54 public bool CanRedo()
55 {
56 return listPos < listMax;
57 }
58
59 public void Reset()
60 {
61 commandStack.Clear();
62 listMax = -1;
63 listPos = -1;
64 DoCommandStackUpdated();
65 }
66
67 public void Undo()
68 {
69 if (CanUndo())
70 {
71 ((Command)commandStack[listPos]).Undo();
72 listPos--;
73 DoCommandStackUpdated();
74 }
75 else
76 {
77 throw new InvalidOperationException("Cannot undo action on empty command stack");
78 }
79 }
80
81 public void Redo()
82 {
83 if (CanRedo())
84 {
85 ((Command)commandStack[listPos+1]).Redo();
86 listPos++;
87 DoCommandStackUpdated();
88 }
89 else
90 {
91 throw new InvalidOperationException("No actions to redo");
92 }
93 }
94
95 public bool Execute(Command cmd)
96 {
97 if (cmd.CanExecute())
98 {
99 if (cmd.Execute())
100 {
101 //if we can't redo, i.e. there's no commands beyond our current point, add to the end else insert
102 if (!CanRedo())
103 {
104 commandStack.Add(cmd);
105 listPos++;
106 }
107 else
108 {
109 if (cleanPos>listPos)
110 {
111 cleanPos = -2;
112 }
113
114 //else overwrite at our current position, setting the listMax value will ignore any commands we could have redone beyond here
115 commandStack[++listPos] = cmd;
116 }
117
118 listMax = listPos;
119 DoCommandStackUpdated();
120 return true;
121 }
122 else
123 {
124 throw new InvalidOperationException("Executable command failed to execute");
125 }
126 }
127 else
128 {
129 return false;
130 }
131 }
132
133 protected void DoCommandStackUpdated()
134 {
135 if (CommandStackUpdated!=null)
136 {
137 CommandStackUpdated();
138 }
139 }
140
141 public Command PeekUndoCommand()
142 {
143 return PeekUndoCommand(1);
144 }
145
146 public Command PeekUndoCommand(int backCount)
147 {
148 backCount = backCount - 1;
149 if (backCount > -1 && backCount <= listPos)
150 {
151 return (Command)commandStack[listPos-backCount];
152 }
153 else
154 {
155 return null;
156 }
157 }
158
159 public Command PeekRedoCommand()
160 {
161 return PeekRedoCommand(1);
162 }
163
164 public Command PeekRedoCommand(int forwardCount)
165 {
166 if (forwardCount > 0 && listPos+forwardCount <= listMax)
167 {
168 return (Command)commandStack[listPos+forwardCount];
169 }
170 else
171 {
172 return null;
173 }
174 }
175 }
176 }