Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members

FXUndoList.h
Go to the documentation of this file.
1 /********************************************************************************
2 * *
3 * U n d o / R e d o - a b l e C o m m a n d *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2000,2006 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
21 *********************************************************************************
22 * $Id: FXUndoList.h,v 1.38 2006/01/22 17:58:12 fox Exp $ *
23 ********************************************************************************/
24 #ifndef FXUNDOLIST_H
25 #define FXUNDOLIST_H
26 
27 #ifndef FXOBJECT_H
28 #include "FXObject.h"
29 #endif
30 
31 namespace FX {
32 
33 
34 class FXUndoList;
35 class FXCommandGroup;
36 
37 
38 /**
39 * Base class for undoable commands. Each undo records all the
40 * information necessary to undo as well as redo a given operation.
41 * Since commands are derived from FXObject, subclassed commands can
42 * both send and receive messages (like ID_GETINTVALUE, for example).
43 */
44 class FXAPI FXCommand : public FXObject {
46  friend class FXUndoList;
47  friend class FXCommandGroup;
48 private:
49  FXCommand *next;
50 private:
51  FXCommand(const FXCommand&);
52  FXCommand &operator=(const FXCommand&);
53 protected:
54  FXCommand():next(NULL){}
55 public:
56 
57  /**
58  * Undo this command; this should save the
59  * information for a subsequent redo.
60  */
61  virtual void undo() = 0;
62 
63  /**
64  * Redo this command; this should save the
65  * information for a subsequent undo.
66  */
67  virtual void redo() = 0;
68 
69  /**
70  * Return the size of the information in the undo record.
71  * The undo list may be trimmed to limit memory usage to
72  * a certain limit. The value returned should include
73  * the size of the command record itself as well as any
74  * data linked from it.
75  */
76  virtual FXuint size() const;
77 
78  /**
79  * Name of the undo command to be shown on a button;
80  * for example, "Undo Delete".
81  */
82  virtual FXString undoName() const;
83 
84  /**
85  * Name of the redo command to be shown on a button;
86  * for example, "Redo Delete".
87  */
88  virtual FXString redoName() const;
89 
90  /**
91  * Return TRUE if this command can be merged with previous undo
92  * commands. This is useful to combine e.g. multiple consecutive
93  * single-character text changes into a single block change.
94  * The default implementation returns FALSE.
95  */
96  virtual bool canMerge() const;
97 
98  /**
99  * Called by the undo system to try and merge the new incoming command
100  * with this command; should return TRUE if merging was possible.
101  * The default implementation returns FALSE.
102  */
103  virtual bool mergeWith(FXCommand* command);
104 
105  /// Delete undo command
106  virtual ~FXCommand(){}
107  };
108 
109 
111 /**
112 * Group of undoable commands. A group may comprise multiple
113 * individual actions which together undo (or redo) a larger
114 * operation. Even larger operations may be built by nesting
115 * multiple undo groups.
116 */
117 class FXAPI FXCommandGroup : public FXCommand {
119  friend class FXUndoList;
120 private:
121  FXCommand *undolist;
122  FXCommand *redolist;
124 private:
126  FXCommandGroup &operator=(const FXCommandGroup&);
127 public:
128 
129  /// Construct initially empty undo command group
130  FXCommandGroup():undolist(NULL),redolist(NULL),group(NULL){}
131 
132  /// Return TRUE if empty
133  bool empty(){ return !undolist; }
134 
135  /// Undo whole command group
136  virtual void undo();
137 
138  /// Redo whole command group
139  virtual void redo();
140 
141  /// Return the size of the command group
142  virtual FXuint size() const;
143 
144  /// Delete undo command and sub-commands
145  virtual ~FXCommandGroup();
146  };
147 
148 
149 
150 /**
151 * The Undo List class manages a list of undoable commands.
152 */
153 class FXAPI FXUndoList : public FXCommandGroup {
155 private:
156  FXint undocount; // Number of undo records
157  FXint redocount; // Number of redo records
158  FXint marker; // Marker value
159  FXuint space; // Space taken up by all the undo records
160  bool working; // Currently busy with undo or redo
161 private:
163  FXUndoList &operator=(const FXUndoList&);
164 public:
165  long onCmdUndo(FXObject*,FXSelector,void*);
166  long onUpdUndo(FXObject*,FXSelector,void*);
167  long onCmdRedo(FXObject*,FXSelector,void*);
168  long onUpdRedo(FXObject*,FXSelector,void*);
169  long onCmdClear(FXObject*,FXSelector,void*);
170  long onUpdClear(FXObject*,FXSelector,void*);
171  long onCmdRevert(FXObject*,FXSelector,void*);
172  long onUpdRevert(FXObject*,FXSelector,void*);
173  long onCmdUndoAll(FXObject*,FXSelector,void*);
174  long onCmdRedoAll(FXObject*,FXSelector,void*);
175  long onUpdUndoCount(FXObject*,FXSelector,void*);
176  long onUpdRedoCount(FXObject*,FXSelector,void*);
177 public:
178  enum{
179  ID_CLEAR=FXWindow::ID_LAST,
180  ID_REVERT,
181  ID_UNDO,
182  ID_REDO,
183  ID_UNDO_ALL,
184  ID_REDO_ALL,
185  ID_UNDO_COUNT,
186  ID_REDO_COUNT,
187  ID_LAST
188  };
189 public:
190 
191  /**
192  * Make new empty undo list, initially unmarked.
193  */
194  FXUndoList();
195 
196  /**
197  * Cut the redo list.
198  * This is automatically invoked when a new undo command is added.
199  */
200  void cut();
201 
202  /**
203  * Add new command, executing it if desired. The new command will be merged
204  * with the previous command if merge is TRUE and we're not at a marked position
205  * and the commands are mergeable. Otherwise the new command will be appended
206  * after the last undo command in the currently active undo group.
207  * If the new command is successfully merged, it will be deleted. Furthermore,
208  * all redo commands will be deleted since it is no longer possible to redo
209  * from this point.
210  */
211  void add(FXCommand* command,bool doit=false,bool merge=true);
212 
213  /**
214  * Begin undo command sub-group. This begins a new group of commands that
215  * are treated as a single command. Must eventually be followed by a
216  * matching end() after recording the sub-commands. The new sub-group
217  * will be appended to its parent group's undo list when end() is called.
218  */
219  void begin(FXCommandGroup *command);
220 
221  /**
222  * End undo command sub-group. If the sub-group is still empty, it will
223  * be deleted; otherwise, the sub-group will be added as a new command
224  * into parent group.
225  * A matching begin() must have been called previously.
226  */
227  void end();
228 
229  /**
230  * Abort the current command sub-group being compiled. All commands
231  * already added to the sub-groups undo list will be discarded.
232  * Intermediate command groups will be left intact.
233  */
234  void abort();
235 
236  /**
237  * Undo last command. This will move the command to the redo list.
238  */
239  virtual void undo();
240 
241  /**
242  * Redo next command. This will move the command back to the undo list.
243  */
244  virtual void redo();
245 
246  /// Undo all commands
247  void undoAll();
248 
249  /// Redo all commands
250  void redoAll();
251 
252  /// Revert to marked
253  void revert();
254 
255  /// Can we undo more commands
256  bool canUndo() const;
257 
258  /// Can we redo more commands
259  bool canRedo() const;
260 
261  /// Can revert to marked
262  bool canRevert() const;
263 
264  /**
265  * Return TRUE if currently inside undo or redo operation; this
266  * is useful to avoid generating another undo command while inside
267  * an undo operation.
268  */
269  bool busy() const { return working; }
270 
271  /// Current top level undo command
272  FXCommand* current() const { return undolist; }
273 
274  /**
275  * Return name of the first undo command available; if no
276  * undo command available this will return the empty string.
277  */
278  virtual FXString undoName() const;
279 
280  /**
281  * Return name of the first redo command available; if no
282  * Redo command available this will return the empty string.
283  */
284  virtual FXString redoName() const;
285 
286  /// Number of undo records
287  FXint undoCount() const { return undocount; }
288 
289  /// Number of redo records
290  FXint redoCount() const { return redocount; }
291 
292  /// Size of undo information
293  virtual FXuint size() const;
294 
295  /**
296  * Clear list, and unmark all states.
297  * All undo and redo information will be destroyed.
298  */
299  void clear();
300 
301  /**
302  * Trim undo list down to at most nc commands.
303  * Call this periodically to prevent the undo-list from growing
304  * beyond a certain number of records.
305  */
306  void trimCount(FXint nc);
307 
308  /**
309  * Trim undo list down to at most size sz.
310  * Call this periodically to prevent the undo-list from growing
311  * beyond a certain amount of memory.
312  */
313  void trimSize(FXuint sz);
314 
315  /**
316  * Mark the current state of the undo list, which is initially unmarked.
317  * There can be only one active mark at any time. Call mark() at any
318  * time when you know the document to be "clean"; for example when you
319  * save the document to disk.
320  */
321  void mark();
322 
323  /**
324  * Unmark all states in the undo list.
325  */
326  void unmark();
327 
328  /**
329  * Check if the current state was marked, if the application has returned
330  * to the previously marked state.
331  */
332  bool marked() const;
333  };
334 
335 
336 }
337 
338 #endif
Definition: FXWindow.h:241
unsigned int FXuint
Definition: fxdefs.h:396
FXuint FXSelector
Association key.
Definition: FXObject.h:53
#define FXAPI
Definition: fxdefs.h:122
FXuint group()
Get effective group id.
#define FXDECLARE_ABSTRACT(classname)
Macro to set up abstract class declaration.
Definition: FXObject.h:114
#define NULL
Definition: fxdefs.h:41
Base class for undoable commands.
Definition: FXUndoList.h:44
Definition: FX4Splitter.h:31
int FXint
Definition: fxdefs.h:397
The Undo List class manages a list of undoable commands.
Definition: FXUndoList.h:139
Object is the base class for all objects in FOX; in order to receive messages from the user interface...
Definition: FXObject.h:166
Group of undoable commands.
Definition: FXUndoList.h:110
#define FXDECLARE(classname)
Macro to set up class declaration.
Definition: FXObject.h:92
FXString provides essential string manipulation capabilities.
Definition: FXString.h:33

Copyright © 1997-2005 Jeroen van der Zijp