CraftSynth.ImageEditor – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Generic;
3  
4 /// Undo-Redo code is written using the article:
5 /// http://www.codeproject.com/cs/design/commandpatterndemo.asp
6 // The Command Pattern and MVC Architecture
7 // By David Veeneman.
8 namespace CraftSynth.ImageEditor
9 {
10 /// <summary>
11 /// Class is responsible for executing Undo - Redo operations
12 /// </summary>
13 internal class UndoManager:IDisposable
14 {
15 #region Class Members
16 private Layers layers;
17  
18 private List<Command> historyList;
19 private int nextUndo;
20 #endregion Class Members
21  
22 #region Constructor
23 public UndoManager(Layers layerList)
24 {
25 layers = layerList;
26  
27 ClearHistory();
28 }
29 #endregion Constructor
30  
31 #region Destruction
32 public void Dispose()
33 {
34 this.Dispose(true);
35 GC.SuppressFinalize(this);
36 }
37  
38 private bool _disposed = false;
39  
40 protected void Dispose(bool disposing)
41 {
42 if (!this._disposed)
43 {
44 if (disposing)
45 {
46 // Free any managed objects here.
47 if (this.historyList != null)
48 {
49 foreach (Command command in this.historyList)
50 {
51 if (command != null)
52 {
53 command.Dispose();
54 }
55 }
56 }
57 if (this.layers != null)
58 {
59 for (int i = 0; i < this.layers.Count; i++)
60 {
61 if (this.layers[i] != null)
62 {
63 this.layers[i].Dispose();
64 }
65 }
66 }
67 }
68  
69 // Free any unmanaged objects here.
70  
71 this._disposed = true;
72 }
73 }
74  
75 ~UndoManager()
76 {
77 this.Dispose(false);
78 }
79 #endregion
80  
81 #region Properties
82 /// <summary>
83 /// Return true if Undo operation is available
84 /// </summary>
85 public bool CanUndo
86 {
87 get
88 {
89 // If the NextUndo pointer is -1, no commands to undo
90 if (nextUndo < 0 ||
91 nextUndo > historyList.Count - 1) // precaution
92 {
93 return false;
94 }
95  
96 return true;
97 }
98 }
99  
100 /// <summary>
101 /// Return true if Redo operation is available
102 /// </summary>
103 public bool CanRedo
104 {
105 get
106 {
107 // If the NextUndo pointer points to the last item, no commands to redo
108 if (nextUndo == historyList.Count - 1)
109 {
110 return false;
111 }
112  
113 return true;
114 }
115 }
116 #endregion Properties
117  
118 #region Public Functions
119 /// <summary>
120 /// Clear History
121 /// </summary>
122 public void ClearHistory()
123 {
124 if (this.historyList != null)
125 {
126 foreach (Command command in historyList)
127 {
128 if (command != null)
129 {
130 command.Dispose();
131 }
132 }
133 }
134 historyList = new List<Command>();
135 nextUndo = -1;
136 }
137  
138 /// <summary>
139 /// Add new command to history.
140 /// Called by client after executing some action.
141 /// </summary>
142 /// <param name="command"></param>
143 public void AddCommandToHistory(Command command)
144 {
145 // Purge history list
146 TrimHistoryList();
147  
148 // Add command and increment undo counter
149 historyList.Add(command);
150  
151 nextUndo++;
152 }
153  
154 /// <summary>
155 /// Undo
156 /// </summary>
157 public void Undo()
158 {
159 if (!CanUndo)
160 {
161 return;
162 }
163  
164 // Get the Command object to be undone
165 Command command = historyList[nextUndo];
166  
167 // Execute the Command object's undo method
168 command.Undo(layers);
169  
170 // Move the pointer up one item
171 nextUndo--;
172 }
173  
174 /// <summary>
175 /// Redo
176 /// </summary>
177 public void Redo()
178 {
179 if (!CanRedo)
180 {
181 return;
182 }
183  
184 // Get the Command object to redo
185 int itemToRedo = nextUndo + 1;
186 Command command = historyList[itemToRedo];
187  
188 // Execute the Command object
189 command.Redo(layers);
190  
191 // Move the undo pointer down one item
192 nextUndo++;
193 }
194 #endregion Public Functions
195  
196 #region Private Functions
197 private void TrimHistoryList()
198 {
199 // We can redo any undone command until we execute a new
200 // command. The new command takes us off in a new direction,
201 // which means we can no longer redo previously undone actions.
202 // So, we purge all undone commands from the history list.*/
203  
204 // Exit if no items in History list
205 if (historyList.Count == 0)
206 {
207 return;
208 }
209  
210 // Exit if NextUndo points to last item on the list
211 if (nextUndo == historyList.Count - 1)
212 {
213 return;
214 }
215  
216 // Purge all items below the NextUndo pointer
217 for (int i = historyList.Count - 1; i > nextUndo; i--)
218 {
219 historyList.RemoveAt(i);
220 }
221 }
222 #endregion
223 }
224 }