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,2004 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.33 2004/02/08 17:17:34 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   /// Delete undo command
00091   virtual ~FXCommand(){}
00092   };
00093 
00094 
00095 
00096 /**
00097 * Group of undoable commands.  A group may comprise multiple
00098 * individual actions which together undo (or redo) a larger
00099 * operation.  Even larger operations may be built by nesting
00100 * multiple undo groups.
00101 */
00102 class FXAPI FXCommandGroup : public FXCommand {
00103   FXDECLARE(FXCommandGroup)
00104   friend class FXUndoList;
00105 private:
00106   FXCommand      *undolist;
00107   FXCommand      *redolist;
00108   FXCommandGroup *group;
00109 private:
00110   FXCommandGroup(const FXCommandGroup&);
00111   FXCommandGroup &operator=(const FXCommandGroup&);
00112 public:
00113 
00114   /// Construct initially empty undo command group
00115   FXCommandGroup():undolist(NULL),redolist(NULL),group(NULL){}
00116 
00117   /// Return TRUE if empty
00118   FXbool empty(){ return !undolist; }
00119 
00120   /// Undo whole command group
00121   virtual void undo();
00122 
00123   /// Redo whole command group
00124   virtual void redo();
00125 
00126   /// Return the size of the command group
00127   virtual FXuint size() const;
00128 
00129   /// Delete undo command and sub-commands
00130   virtual ~FXCommandGroup();
00131   };
00132 
00133 
00134 
00135 /**
00136 * The Undo List class manages a list of undoable commands.
00137 */
00138 class FXAPI FXUndoList : public FXCommandGroup {
00139   FXDECLARE(FXUndoList)
00140 private:
00141   FXint      undocount;     // Number of undo records
00142   FXint      redocount;     // Number of redo records
00143   FXint      marker;        // Marker value
00144   FXuint     space;         // Space taken up by all the undo records
00145   FXbool     working;       // Currently busy with undo or redo
00146 private:
00147   FXUndoList(const FXUndoList&);
00148   FXUndoList &operator=(const FXUndoList&);
00149 public:
00150   long onCmdUndo(FXObject*,FXSelector,void*);
00151   long onUpdUndo(FXObject*,FXSelector,void*);
00152   long onCmdRedo(FXObject*,FXSelector,void*);
00153   long onUpdRedo(FXObject*,FXSelector,void*);
00154   long onCmdClear(FXObject*,FXSelector,void*);
00155   long onUpdClear(FXObject*,FXSelector,void*);
00156   long onCmdRevert(FXObject*,FXSelector,void*);
00157   long onUpdRevert(FXObject*,FXSelector,void*);
00158   long onCmdUndoAll(FXObject*,FXSelector,void*);
00159   long onCmdRedoAll(FXObject*,FXSelector,void*);
00160   long onUpdUndoCount(FXObject*,FXSelector,void*);
00161   long onUpdRedoCount(FXObject*,FXSelector,void*);
00162 public:
00163   enum{
00164     ID_CLEAR=FXWindow::ID_LAST,
00165     ID_REVERT,
00166     ID_UNDO,
00167     ID_REDO,
00168     ID_UNDO_ALL,
00169     ID_REDO_ALL,
00170     ID_UNDO_COUNT,
00171     ID_REDO_COUNT,
00172     ID_LAST
00173     };
00174 public:
00175 
00176   /**
00177   * Make new empty undo list, initially unmarked.
00178   */
00179   FXUndoList();
00180 
00181   /**
00182   * Cut the redo list.
00183   * This is automatically invoked when a new undo command is added.
00184   */
00185   void cut();
00186 
00187   /**
00188   * Add new command, executing it if desired. The new command
00189   * will be appended after the last undo command.  All redo commands
00190   * will be deleted.
00191   */
00192   void add(FXCommand* command,FXbool doit=FALSE);
00193 
00194   /**
00195   * Begin undo command sub-group. This begins a new group of commands that
00196   * are treated as a single command.  Must eventually be followed by a
00197   * matching end() after recording the sub-commands.  The new sub-group
00198   * will be appended to its parent group's undo list when end() is called.
00199   */
00200   void begin(FXCommandGroup *command);
00201 
00202   /**
00203   * End undo command sub-group.  If the sub-group is still empty, it will
00204   * be deleted; otherwise, the sub-group will be added as a new command
00205   * into parent group.
00206   * A matching begin() must have been called previously.
00207   */
00208   void end();
00209 
00210   /**
00211   * Abort the current command sub-group being compiled.  All commands
00212   * already added to the sub-groups undo list will be discarded.
00213   * Intermediate command groups will be left intact.
00214   */
00215   void abort();
00216 
00217   /**
00218   * Undo last command. This will move the command to the redo list.
00219   */
00220   virtual void undo();
00221 
00222   /**
00223   * Redo next command. This will move the command back to the undo list.
00224   */
00225   virtual void redo();
00226 
00227   /// Undo all commands
00228   void undoAll();
00229 
00230   /// Redo all commands
00231   void redoAll();
00232 
00233   /// Revert to marked
00234   void revert();
00235 
00236   /// Can we undo more commands
00237   FXbool canUndo() const;
00238 
00239   /// Can we redo more commands
00240   FXbool canRedo() const;
00241 
00242   /// Can revert to marked
00243   FXbool canRevert() const;
00244 
00245   /**
00246   * Return TRUE if currently inside undo or redo operation; this
00247   * is useful to avoid generating another undo command while inside
00248   * an undo operation.
00249   */
00250   FXbool busy() const { return working; }
00251 
00252   /// Current top level undo command
00253   FXCommand* current() const { return undolist; }
00254 
00255   /**
00256   * Return name of the first undo command available; if no
00257   * undo command available this will return the empty string.
00258   */
00259   virtual FXString undoName() const;
00260 
00261   /**
00262   * Return name of the first redo command available; if no
00263   * Redo command available this will return the empty string.
00264   */
00265   virtual FXString redoName() const;
00266 
00267   /// Number of undo records
00268   FXint undoCount() const { return undocount; }
00269 
00270   /// Number of redo records
00271   FXint redoCount() const { return redocount; }
00272 
00273   /// Size of undo information
00274   virtual FXuint size() const;
00275 
00276   /**
00277   * Clear list, and unmark all states.
00278   * All undo and redo information will be destroyed.
00279   */
00280   void clear();
00281 
00282   /**
00283   * Trim undo list down to at most nc commands.
00284   * Call this periodically to prevent the undo-list from growing
00285   * beyond a certain number of records.
00286   */
00287   void trimCount(FXint nc);
00288 
00289   /**
00290   * Trim undo list down to at most size sz.
00291   * Call this periodically to prevent the undo-list from growing
00292   * beyond a certain amount of memory.
00293   */
00294   void trimSize(FXuint sz);
00295 
00296   /**
00297   * Mark the current state of the undo list, which is initially unmarked.
00298   * There can be only one active mark at any time.  Call mark() at any
00299   * time when you know the document to be "clean"; for example when you
00300   * save the document to disk.
00301   */
00302   void mark();
00303 
00304   /**
00305   * Unmark all states in the undo list.
00306   */
00307   void unmark();
00308 
00309   /**
00310   * Check if the current state was marked, if the application has returned
00311   * to the previously marked state.
00312   */
00313   FXbool marked() const;
00314   };
00315 
00316 
00317 }
00318 
00319 #endif

Copyright © 1997-2004 Jeroen van der Zijp