HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_UndoManager.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_UndoManager.h ( Utility Library, C++)
7  *
8  * COMMENTS:
9  * This is the class that manages undo and redo.
10  * There is one global undo manager, but you can make
11  * your own instance if you want (for example the
12  * modeler could handle its undos separately)
13  *
14  * NOTE: It is not designed to be subclassed. If you
15  * do subclass it, you're going to have to
16  * make the destructor virtual, etc.
17  *
18  * Example usage:
19  *
20  * void f()
21  * {
22  * UT_AutoUndoBlock u("Some undo", ANYLEVEL);
23  *
24  * if (UTwillAcceptUndoAddition())
25  * UTaddToUndoBlock(new MY_UndoSubclass);
26  *
27  * // do stuff
28  * }
29  *
30  * First note that we must surround the UTaddToUndoBlock() code
31  * by creating an undoblock which is accomplished by
32  * UT_AutoUndoBlock. This class begins an undoblock and ends when
33  * it goes out of scope. The ANYLEVEL is additional information
34  * saying that this undoblock can be invoked at any time. If it's
35  * known that this should always be the topmost undoblock (eg.
36  * action is invoked from the UI), then you should indicated this
37  * by TOPLEVEL.
38  *
39  * Second, the call to UTaddToUndoBlock() must be preceded by a
40  * check to UTwillAcceptUndoAddition(). This check ensures that
41  * undos won't be created while performing the undo/redo action
42  * themselves as well as when undos are explicitly disabled.
43  *
44  * Finally, notice that the undo object is created and ownership
45  * is given to UTaddtoUndoBlock() so that UT_UndoManager can free
46  * it when the undo memory limit is reached.
47  */
48 
49 #ifndef __UT_UndoManager__
50 #define __UT_UndoManager__
51 
52 #include "UT_API.h"
53 #include "UT_Array.h"
54 #include "UT_StringHolder.h"
55 #include "UT_ValArray.h"
56 #include <SYS/SYS_Types.h>
57 
58 class UT_Undo;
59 class UT_UndoBlock;
60 struct utClearerStruct;
61 struct utUndoInterestStruct;
62 
64 {
67 };
68 
70 {
71 public:
73  ~UT_UndoManager();
74 
75  static void disableUndoCreation();
76  static void enableUndoCreation();
77 
78  // When calling beginUndoBlock if you can determine that your code
79  // path will only be executed from outside any other undo block (eg
80  // on the mouse-down of a mouse-drag instantiated operation) then
81  // pass in UT_UNDOBLOCK_TOPLEVEL as the blocktype to beginUndoBlock.
82  // Otherwise pass in UT_UNDOBLOCK_GENERIC.
83  int beginUndoBlock(const char *name,
84  UT_UndoBlockType blocktype);
85 
86  // Instead of beginning a new undo block, this will append to the previous
87  // undo block if the given name matches. This only happens if we currently
88  // don't have any undoblocks open. If we do, then we will just use the
89  // current one just like beginUndoBlock(). The returned level must be
90  // passed to a corresponding endUndoBlock() call.
91  int beginLastUndoBlock(const char *name,
92  UT_UndoBlockType blocktype);
93 
94  // The level that's passed in to endUndoBlock should the level that
95  // was returned by the matching call to beginUndoBlock. If the code
96  // that called beginUndoBlock is too far from the call to endUndoBlock
97  // then you can pass in -1 (ie you don't know) but that means that
98  // some of the undo manager error detection won't be able to operate.
99  void endUndoBlock(int level);
100 
101  // This value should always be checked before adding to an undo block.
102  int willAcceptUndoAddition();
103  // This will return a non zero value if we are performing an undo or redo.
104  int performingUndoRedo();
105 
106  // The block level will be > 0 when within an undo block.
107  int blockLevel() const { return myBlockLevel; }
108 
109  // This returns true if any undos are being done, zero if undos
110  // are disabled.
111  int isUndoEnabled();
112 
113  // Add an undo to the current undoblock, taken ownership of the pointer.
114  // You *must* precede with this with a call to willAcceptUndoAddition().
115  // See the top of this file for how to use this.
116  void addToUndoBlock(UT_Undo *undo);
117 
118  // Add an undo to the undo block that last ended. Takes ownership of undo
119  void addToLastUndoBlock(UT_Undo *undo);
120 
121  // Suspend/Resume allowing toplevel undoblocks. All calls to suspend must
122  // be matched with a corresponding call to resume.
123  void suspendTopLevelUndoBlock();
124  void resumeTopLevelUndoBlock();
125 
126  // Use these functions when you want to tell the undo manager
127  // that any undos that are being added (outside your control)
128  // should be ignored. Just frame the code section in question
129  // with disallowUndos() and allowUndos() in that order.
130  void disallowUndos() { disableUndoCreation(); }
131  void allowUndos() { enableUndoCreation(); }
132 
133  // The strict parameter restricts the behaviour to only affect the
134  // top undo block, rather than searching through the stack for the
135  // first block which will have an effect.
136  // The redoable flag determines whether or not the block about to be
137  // undone is added to the redo stack
138  void undo(bool strict = false, bool redoable = true);
139  void redo(bool strict = false);
140 
141  // Get the name of the next undo operation. This will force a prune.
142  const char *getUndoOperationName();
143 
144  // Get the name of the next redo operation. This will force a prune.
145  const char *getRedoOperationName();
146 
147  // Get the list of undo names.
148  // Note that the list contains pointers to within the undoblocks themselves
149  // and will become invalid upon any stack changes.
150  void getUndoNames(UT_StringList &names, bool prune=true);
151 
152  // Get the list of redo names. This will force a prune.
153  // Note that the list contains pointers to within the undoblocks themselves
154  // and will become invalid upon any stack changes.
155  void getRedoNames(UT_StringList &names, bool prune=true);
156 
157  /// Free all invalid undos/redos
158  void pruneInvalidUndos();
159 
160  int64 getMemoryUsage();
161  int64 getMemoryUsageLimit() { return myMemLimit; }
162  void setMemoryUsageLimit(int64 bytes);
163 
164  // clearUndos will wipe away all the undo and redos
165  void clearUndos();
166 
167  // clearUndoFlags is used to clear any flags that have been set
168  // for optimization during undo blocks
169  void clearUndoFlags();
170  void installUndoFlagClearer(void (*function)(void *data),
171  void *data);
172  void removeUndoFlagClearer(void (*function)(void *data),
173  void *data);
174 
175  // Install or clear a callback to be called whenever the undo/redo
176  // stack changes. Currently this is intended for the use of the
177  // undo manager UI, and so there can only be one interest.
178  void setUndoInterest(void (*function)(void *data),
179  void *data);
180 
181  const UT_UndoBlock *getUndoStack() const { return myUndoBlockStack; }
182  const UT_UndoBlock *getRedoStack() const { return myRedoBlockStack; }
183 
184 private:
185  void checkMemoryUsage();
186  void pruneUndoBlockStack();
187  void pruneRedoBlockStack();
188 
189  UT_UndoBlock *myUndoBlockStack;
190  UT_UndoBlock *myRedoBlockStack;
191 
192  int myBlockLevel;
193  int64 myMemLimit;
194  int64 myNetMemory;
195 
197 
198  utUndoInterestStruct *myInterest;
199 
200  struct SuspendItem
201  {
202  exint myId;
203  int myBlockLevel;
204  UT_StringHolder myName;
205  };
206  UT_Array<SuspendItem> mySuspendStack;
207  exint myLastSuspendId;
208 
209  char myBusyFlag;
210  char myEnableBugNotify;
211 };
212 
214 
215 // These following functions are provided for convenience.
216 // By default they affect the global Undo manager, but you
217 // can override that behaviour.
218 UT_API int UTbeginUndoBlock(const char *name,
219  UT_UndoBlockType blocktype,
220  UT_UndoManager *man = 0);
223 UT_API void UTendUndoBlock(int level, UT_UndoManager *man = 0);
225 
226 // Use this name for your undo block if you want it to adopt the name
227 // of the next undo block that gets added.
228 #define UT_UNDOBLOCK_ADOPT_NAME "Multiple Undo Operation"
229 
231 {
232 public:
233  UT_AutoUndoBlock(const char *name, UT_UndoBlockType blocktype)
234  {
235  myStackLevel = UTbeginUndoBlock(name, blocktype);
236  }
238  {
239  UTendUndoBlock(myStackLevel);
240  }
241 
242 private:
243  int myStackLevel;
244 };
245 
246 // Create local instances of this class to disallow undos on construction and
247 // allow them again when it goes out of scope.
249 {
250 public:
252  {
253  UT_UndoManager *undo_manager = UTgetUndoManager();
254  if (undo_manager)
255  undo_manager->disallowUndos();
256  }
257 
259  {
260  UT_UndoManager *undo_manager = UTgetUndoManager();
261  if (undo_manager)
262  undo_manager->allowUndos();
263  }
264 };
265 
266 #endif
UT_API UT_UndoManager * UTgetUndoManager()
GLint level
Definition: glcorearb.h:107
#define UT_API
Definition: UT_API.h:12
int64 getMemoryUsageLimit()
long long int64
Definition: SYS_Types.h:106
UT_API int UTbeginUndoBlock(const char *name, UT_UndoBlockType blocktype, UT_UndoManager *man=0)
UT_API void UTendUndoBlock(int level, UT_UndoManager *man=0)
int64 exint
Definition: SYS_Types.h:115
UT_UndoBlockType
int blockLevel() const
UT_API int UTwillAcceptUndoAddition(UT_UndoManager *man=0)
GLboolean * data
Definition: glcorearb.h:130
UT_AutoUndoBlock(const char *name, UT_UndoBlockType blocktype)
GLuint const GLchar * name
Definition: glcorearb.h:785
UT_API int UTperformingUndoRedo(UT_UndoManager *man=0)
UT_API void UTaddToUndoBlock(UT_Undo *, UT_UndoManager *man=0)
const UT_UndoBlock * getUndoStack() const
const UT_UndoBlock * getRedoStack() const
void prune(TreeT &tree, typename TreeT::ValueType tolerance=zeroVal< typename TreeT::ValueType >(), bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with tiles any nodes whose values are all the same...
Definition: Prune.h:374