1
2
3
4
5
6 using System;
7 using System.Collections;
8
9 namespace System.Windows
10 {
11 public abstract class EditCommand
12 {
13 public virtual default ~EditCommand();
14 public abstract nothrow void Undo(TextView* textView);
15 public abstract nothrow void Redo(TextView* textView);
16 }
17
18 public class EditCommandList
19 {
20 public nothrow EditCommandList(TextView* textView_) : textView(textView_), currentIndex(0), inGroup(false)
21 {
22 }
23 public nothrow void SetMenuItems(MenuItem* undoMenuItem_, MenuItem* redoMenuItem_)
24 {
25 undoMenuItem = undoMenuItem_;
26 redoMenuItem = redoMenuItem_;
27 UpdateMenuItems();
28 }
29 public nothrow bool CanUndo() const
30 {
31 return currentIndex > 0;
32 }
33 public nothrow bool CanRedo() const
34 {
35 return currentIndex < commands.Count();
36 }
37 public nothrow void UpdateMenuItems()
38 {
39 if (CanUndo())
40 {
41 undoMenuItem->Enable();
42 }
43 else
44 {
45 undoMenuItem->Disable();
46 }
47 if (CanRedo())
48 {
49 redoMenuItem->Enable();
50 }
51 else
52 {
53 redoMenuItem->Disable();
54 }
55 }
56 public nothrow void AddCommand(EditCommand* command)
57 {
58 if (inGroup)
59 {
60 groupCommand->AddCommand(command);
61 }
62 else
63 {
64 if (currentIndex >= commands.Count())
65 {
66 commands.Add(UniquePtr<EditCommand>(command));
67 currentIndex = cast<int>(commands.Count());
68 }
69 else
70 {
71 commands[currentIndex].Reset(command);
72 ++currentIndex;
73 }
74 commands.Resize(currentIndex);
75 UpdateMenuItems();
76 }
77 }
78 public nothrow void Undo()
79 {
80 if (CanUndo())
81 {
82 --currentIndex;
83 EditCommand* command = commands[currentIndex].Get();
84 command->Undo(textView);
85 }
86 UpdateMenuItems();
87 }
88 public nothrow void Redo()
89 {
90 if (CanRedo())
91 {
92 EditCommand* command = commands[currentIndex].Get();
93 command->Redo(textView);
94 ++currentIndex;
95 }
96 UpdateMenuItems();
97 }
98 public nothrow void BeginGroup()
99 {
100 groupCommand.Reset(new GroupCommand());
101 inGroup = true;
102 }
103 public nothrow void EndGroup()
104 {
105 inGroup = false;
106 AddCommand(groupCommand.Release());
107 }
108 private TextView* textView;
109 private int currentIndex;
110 private List<UniquePtr<EditCommand>> commands;
111 private MenuItem* undoMenuItem;
112 private MenuItem* redoMenuItem;
113 private UniquePtr<GroupCommand> groupCommand;
114 private bool inGroup;
115 }
116
117 public class InsertCharCommand : EditCommand
118 {
119 public nothrow InsertCharCommand(int lineIndex_, int columnIndex_, uchar c_, bool removeIndent_) : lineIndex(lineIndex_), columnIndex(columnIndex_), c(c_), removeIndent(removeIndent_)
120 {
121 }
122 public override nothrow void Undo(TextView* textView)
123 {
124 textView->DeleteChar(lineIndex, columnIndex, 0, 0, removeIndent);
125 }
126 public override nothrow void Redo(TextView* textView)
127 {
128 textView->InsertChar(lineIndex, columnIndex, c);
129 }
130 private int lineIndex;
131 private int columnIndex;
132 private uchar c;
133 private bool removeIndent;
134 }
135
136 public class DeleteCharCommand : EditCommand
137 {
138 public nothrow DeleteCharCommand(int lineIndex_, int columnIndex_, uchar c_) : lineIndex(lineIndex_), columnIndex(columnIndex_), c(c_)
139 {
140 }
141 public override nothrow void Undo(TextView* textView)
142 {
143 if (c != '\0')
144 {
145 textView->InsertChar(lineIndex, columnIndex, c);
146 }
147 else
148 {
149 textView->NewLine(lineIndex, columnIndex);
150 }
151 }
152 public override nothrow void Redo(TextView* textView)
153 {
154 textView->DeleteChar(lineIndex, columnIndex, 0, 0, false);
155 }
156 private int lineIndex;
157 private int columnIndex;
158 private uchar c;
159 }
160
161 public class NewLineCommand : EditCommand
162 {
163 public nothrow NewLineCommand(int lineIndex_, int columnIndex_, int indent_, int numSpaces_) :
164 lineIndex(lineIndex_), columnIndex(columnIndex_), indent(indent_), numSpaces(numSpaces_)
165 {
166 }
167 public override nothrow void Undo(TextView* textView)
168 {
169 textView->DeleteChar(lineIndex, columnIndex, indent, numSpaces, false);
170 }
171 public override nothrow void Redo(TextView* textView)
172 {
173 textView->NewLine(lineIndex, columnIndex);
174 }
175 private int lineIndex;
176 private int columnIndex;
177 private int indent;
178 private int numSpaces;
179 }
180
181 public class InsertIntoLineCommand : EditCommand
182 {
183 public nothrow InsertIntoLineCommand(int lineIndex_, int columnIndex_, const ustring& text_) :
184 lineIndex(lineIndex_), columnIndex(columnIndex_), text(text_)
185 {
186 }
187 public override nothrow void Undo(TextView* textView)
188 {
189 textView->RemoveFromLine(lineIndex, columnIndex, text.Length());
190 }
191 public override nothrow void Redo(TextView* textView)
192 {
193 textView->InsertIntoLine(lineIndex, columnIndex, text);
194 }
195 private int lineIndex;
196 private int columnIndex;
197 private ustring text;
198 }
199
200 public class InsertLinesCommand : EditCommand
201 {
202 public nothrow InsertLinesCommand(int lineIndex_, int columnIndex_, const List<ustring>& lines_) :
203 lineIndex(lineIndex_), columnIndex(columnIndex_), lines(lines_)
204 {
205 }
206 public override nothrow void Undo(TextView* textView)
207 {
208 textView->DeleteLines(lineIndex, columnIndex, lines);
209 }
210 public override nothrow void Redo(TextView* textView)
211 {
212 textView->InsertLines(lineIndex, columnIndex, lines);
213 }
214 private int lineIndex;
215 private int columnIndex;
216 private List<ustring> lines;
217 }
218
219 public class RemoveSelectionCommand : EditCommand
220 {
221 public nothrow RemoveSelectionCommand(const Selection& selection_, const SelectionData& selectionData_, bool wholeLine_) :
222 selection(selection_), selectionData(selectionData_), wholeLine(wholeLine_)
223 {
224 }
225 public override nothrow void Undo(TextView* textView)
226 {
227 textView->InsertSelection(selection, selectionData, wholeLine);
228 }
229 public override nothrow void Redo(TextView* textView)
230 {
231 textView->SetSelection(selection);
232 textView->RemoveSelection();
233 }
234 private Selection selection;
235 private SelectionData selectionData;
236 private bool wholeLine;
237 }
238
239 public class TabCommand : EditCommand
240 {
241 public nothrow TabCommand(int lineIndex_, int columnIndex_) : lineIndex(lineIndex_), columnIndex(columnIndex_)
242 {
243 }
244 public override nothrow void Undo(TextView* textView)
245 {
246 textView->Backtab(lineIndex, columnIndex + textView->IndentSize());
247 }
248 public override nothrow void Redo(TextView* textView)
249 {
250 textView->Tab(lineIndex, columnIndex);
251 }
252 private int lineIndex;
253 private int columnIndex;
254 }
255
256 public class BacktabCommand : EditCommand
257 {
258 public nothrow BacktabCommand(int lineIndex_, int columnIndex_, int numSpaces_) : lineIndex(lineIndex_), columnIndex(columnIndex_), numSpaces(numSpaces_)
259 {
260 }
261 public override nothrow void Undo(TextView* textView)
262 {
263 textView->AddSpaces(lineIndex, columnIndex, numSpaces);
264 }
265 public override nothrow void Redo(TextView* textView)
266 {
267 textView->RemoveSpaces(lineIndex, columnIndex, numSpaces);
268 }
269 private int lineIndex;
270 private int columnIndex;
271 private int numSpaces;
272 }
273
274 public class IndentSelectionCommand : EditCommand
275 {
276 public nothrow IndentSelectionCommand(const Selection& selection_) : selection(selection_)
277 {
278 }
279 public override nothrow void Undo(TextView* textView)
280 {
281 textView->SetSelection(selection);
282 textView->UnindentSelection();
283 }
284 public override nothrow void Redo(TextView* textView)
285 {
286 textView->SetSelection(selection);
287 textView->IndentSelection();
288 }
289 private Selection selection;
290 }
291
292 public class UnindentSelectionCommand : EditCommand
293 {
294 public UnindentSelectionCommand(const Selection& selection_) : selection(selection_)
295 {
296 }
297 public override nothrow void Undo(TextView* textView)
298 {
299 textView->SetSelection(selection);
300 textView->IndentSelection();
301 }
302 public override nothrow void Redo(TextView* textView)
303 {
304 textView->SetSelection(selection);
305 textView->UnindentSelection();
306 }
307 private Selection selection;
308 }
309
310 public class GroupCommand : EditCommand
311 {
312 public GroupCommand()
313 {
314 }
315 public nothrow void AddCommand(EditCommand* command)
316 {
317 commands.Add(UniquePtr<EditCommand>(command));
318 }
319 public override nothrow void Undo(TextView* textView)
320 {
321 long n = commands.Count();
322 for (long i = n - 1; i >= 0; --i;)
323 {
324 EditCommand* command = commands[i].Get();
325 command->Undo(textView);
326 }
327 }
328 public override nothrow void Redo(TextView* textView)
329 {
330 long n = commands.Count();
331 for (long i = 0; i < n; ++i;)
332 {
333 EditCommand* command = commands[i].Get();
334 command->Redo(textView);
335 }
336 }
337 private List<UniquePtr<EditCommand>> commands;
338 }
339 }