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

FXUndoList.h

00001 /******************************************************************************** 00002 * * 00003 * U n d o / R e d o - a b l e C o m m a n d * 00004 * * 00005 ********************************************************************************* 00006 * Copyright (C) 2000,2005 by Jeroen van der Zijp. All Rights Reserved. * 00007 ********************************************************************************* 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * 00021 ********************************************************************************* 00022 * $Id: FXUndoList.h,v 1.36 2005/01/26 19:11:41 fox Exp $ * 00023 ********************************************************************************/ 00024 #ifndef FXUNDOLIST_H 00025 #define FXUNDOLIST_H 00026 00027 #ifndef FXOBJECT_H 00028 #include "FXObject.h" 00029 #endif 00030 00031 namespace FX { 00032 00033 00034 class FXUndoList; 00035 class FXCommandGroup; 00036 00037 00038 /** 00039 * Base class for undoable commands. Each undo records all the 00040 * information necessary to undo as well as redo a given operation. 00041 * Since commands are derived from FXObject, subclassed commands can 00042 * both send and receive messages (like ID_GETINTVALUE, for example). 00043 */ 00044 class FXAPI FXCommand : public FXObject { 00045 FXDECLARE_ABSTRACT(FXCommand) 00046 friend class FXUndoList; 00047 friend class FXCommandGroup; 00048 private: 00049 FXCommand *next; 00050 private: 00051 FXCommand(const FXCommand&); 00052 FXCommand &operator=(const FXCommand&); 00053 protected: 00054 FXCommand():next(NULL){} 00055 public: 00056 00057 /** 00058 * Undo this command; this should save the 00059 * information for a subsequent redo. 00060 */ 00061 virtual void undo() = 0; 00062 00063 /** 00064 * Redo this command; this should save the 00065 * information for a subsequent undo. 00066 */ 00067 virtual void redo() = 0; 00068 00069 /** 00070 * Return the size of the information in the undo record. 00071 * The undo list may be trimmed to limit memory usage to 00072 * a certain limit. The value returned should include 00073 * the size of the command record itself as well as any 00074 * data linked from it. 00075 */ 00076 virtual FXuint size() const; 00077 00078 /** 00079 * Name of the undo command to be shown on a button; 00080 * for example, "Undo Delete". 00081 */ 00082 virtual FXString undoName() const; 00083 00084 /** 00085 * Name of the redo command to be shown on a button; 00086 * for example, "Redo Delete". 00087 */ 00088 virtual FXString redoName() const; 00089 00090 /** 00091 * Return TRUE if this command can be merged with previous undo 00092 * commands. This is useful to combine e.g. multiple consecutive 00093 * single-character text changes into a single block change. 00094 * The default implementation returns FALSE. 00095 */ 00096 virtual FXbool canMerge() const; 00097 00098 /** 00099 * Called by the undo system to try and merge the new incoming command 00100 * with this command; should return TRUE if merging was possible. 00101 * The default implementation returns FALSE. 00102 */ 00103 virtual FXbool mergeWith(FXCommand* command); 00104 00105 /// Delete undo command 00106 virtual ~FXCommand(){} 00107 }; 00108 00109 00110 00111 /** 00112 * Group of undoable commands. A group may comprise multiple 00113 * individual actions which together undo (or redo) a larger 00114 * operation. Even larger operations may be built by nesting 00115 * multiple undo groups. 00116 */ 00117 class FXAPI FXCommandGroup : public FXCommand { 00118 FXDECLARE(FXCommandGroup) 00119 friend class FXUndoList; 00120 private: 00121 FXCommand *undolist; 00122 FXCommand *redolist; 00123 FXCommandGroup *group; 00124 private: 00125 FXCommandGroup(const FXCommandGroup&); 00126 FXCommandGroup &operator=(const FXCommandGroup&); 00127 public: 00128 00129 /// Construct initially empty undo command group 00130 FXCommandGroup():undolist(NULL),redolist(NULL),group(NULL){} 00131 00132 /// Return TRUE if empty 00133 FXbool empty(){ return !undolist; } 00134 00135 /// Undo whole command group 00136 virtual void undo(); 00137 00138 /// Redo whole command group 00139 virtual void redo(); 00140 00141 /// Return the size of the command group 00142 virtual FXuint size() const; 00143 00144 /// Delete undo command and sub-commands 00145 virtual ~FXCommandGroup(); 00146 }; 00147 00148 00149 00150 /** 00151 * The Undo List class manages a list of undoable commands. 00152 */ 00153 class FXAPI FXUndoList : public FXCommandGroup { 00154 FXDECLARE(FXUndoList) 00155 private: 00156 FXint undocount; // Number of undo records 00157 FXint redocount; // Number of redo records 00158 FXint marker; // Marker value 00159 FXuint space; // Space taken up by all the undo records 00160 FXbool working; // Currently busy with undo or redo 00161 private: 00162 FXUndoList(const FXUndoList&); 00163 FXUndoList &operator=(const FXUndoList&); 00164 public: 00165 long onCmdUndo(FXObject*,FXSelector,void*); 00166 long onUpdUndo(FXObject*,FXSelector,void*); 00167 long onCmdRedo(FXObject*,FXSelector,void*); 00168 long onUpdRedo(FXObject*,FXSelector,void*); 00169 long onCmdClear(FXObject*,FXSelector,void*); 00170 long onUpdClear(FXObject*,FXSelector,void*); 00171 long onCmdRevert(FXObject*,FXSelector,void*); 00172 long onUpdRevert(FXObject*,FXSelector,void*); 00173 long onCmdUndoAll(FXObject*,FXSelector,void*); 00174 long onCmdRedoAll(FXObject*,FXSelector,void*); 00175 long onUpdUndoCount(FXObject*,FXSelector,void*); 00176 long onUpdRedoCount(FXObject*,FXSelector,void*); 00177 public: 00178 enum{ 00179 ID_CLEAR=FXWindow::ID_LAST, 00180 ID_REVERT, 00181 ID_UNDO, 00182 ID_REDO, 00183 ID_UNDO_ALL, 00184 ID_REDO_ALL, 00185 ID_UNDO_COUNT, 00186 ID_REDO_COUNT, 00187 ID_LAST 00188 }; 00189 public: 00190 00191 /** 00192 * Make new empty undo list, initially unmarked. 00193 */ 00194 FXUndoList(); 00195 00196 /** 00197 * Cut the redo list. 00198 * This is automatically invoked when a new undo command is added. 00199 */ 00200 void cut(); 00201 00202 /** 00203 * Add new command, executing it if desired. The new command will be merged 00204 * with the previous command if merge is TRUE and we're not at a marked position 00205 * and the commands are mergeable. Otherwise the new command will be appended 00206 * after the last undo command in the currently active undo group. 00207 * If the new command is successfully merged, it will be deleted. Furthermore, 00208 * all redo commands will be deleted since it is no longer possible to redo 00209 * from this point. 00210 */ 00211 void add(FXCommand* command,FXbool doit=FALSE,FXbool merge=TRUE); 00212 00213 /** 00214 * Begin undo command sub-group. This begins a new group of commands that 00215 * are treated as a single command. Must eventually be followed by a 00216 * matching end() after recording the sub-commands. The new sub-group 00217 * will be appended to its parent group's undo list when end() is called. 00218 */ 00219 void begin(FXCommandGroup *command); 00220 00221 /** 00222 * End undo command sub-group. If the sub-group is still empty, it will 00223 * be deleted; otherwise, the sub-group will be added as a new command 00224 * into parent group. 00225 * A matching begin() must have been called previously. 00226 */ 00227 void end(); 00228 00229 /** 00230 * Abort the current command sub-group being compiled. All commands 00231 * already added to the sub-groups undo list will be discarded. 00232 * Intermediate command groups will be left intact. 00233 */ 00234 void abort(); 00235 00236 /** 00237 * Undo last command. This will move the command to the redo list. 00238 */ 00239 virtual void undo(); 00240 00241 /** 00242 * Redo next command. This will move the command back to the undo list. 00243 */ 00244 virtual void redo(); 00245 00246 /// Undo all commands 00247 void undoAll(); 00248 00249 /// Redo all commands 00250 void redoAll(); 00251 00252 /// Revert to marked 00253 void revert(); 00254 00255 /// Can we undo more commands 00256 FXbool canUndo() const; 00257 00258 /// Can we redo more commands 00259 FXbool canRedo() const; 00260 00261 /// Can revert to marked 00262 FXbool canRevert() const; 00263 00264 /** 00265 * Return TRUE if currently inside undo or redo operation; this 00266 * is useful to avoid generating another undo command while inside 00267 * an undo operation. 00268 */ 00269 FXbool busy() const { return working; } 00270 00271 /// Current top level undo command 00272 FXCommand* current() const { return undolist; } 00273 00274 /** 00275 * Return name of the first undo command available; if no 00276 * undo command available this will return the empty string. 00277 */ 00278 virtual FXString undoName() const; 00279 00280 /** 00281 * Return name of the first redo command available; if no 00282 * Redo command available this will return the empty string. 00283 */ 00284 virtual FXString redoName() const; 00285 00286 /// Number of undo records 00287 FXint undoCount() const { return undocount; } 00288 00289 /// Number of redo records 00290 FXint redoCount() const { return redocount; } 00291 00292 /// Size of undo information 00293 virtual FXuint size() const; 00294 00295 /** 00296 * Clear list, and unmark all states. 00297 * All undo and redo information will be destroyed. 00298 */ 00299 void clear(); 00300 00301 /** 00302 * Trim undo list down to at most nc commands. 00303 * Call this periodically to prevent the undo-list from growing 00304 * beyond a certain number of records. 00305 */ 00306 void trimCount(FXint nc); 00307 00308 /** 00309 * Trim undo list down to at most size sz. 00310 * Call this periodically to prevent the undo-list from growing 00311 * beyond a certain amount of memory. 00312 */ 00313 void trimSize(FXuint sz); 00314 00315 /** 00316 * Mark the current state of the undo list, which is initially unmarked. 00317 * There can be only one active mark at any time. Call mark() at any 00318 * time when you know the document to be "clean"; for example when you 00319 * save the document to disk. 00320 */ 00321 void mark(); 00322 00323 /** 00324 * Unmark all states in the undo list. 00325 */ 00326 void unmark(); 00327 00328 /** 00329 * Check if the current state was marked, if the application has returned 00330 * to the previously marked state. 00331 */ 00332 FXbool marked() const; 00333 }; 00334 00335 00336 } 00337 00338 #endif

Copyright © 1997-2005 Jeroen van der Zijp