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