HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  bool isTopLevelUndoSuspended() const;
126 
127  // Use these functions when you want to tell the undo manager
128  // that any undos that are being added (outside your control)
129  // should be ignored. Just frame the code section in question
130  // with disallowUndos() and allowUndos() in that order.
131  void disallowUndos() { disableUndoCreation(); }
132  void allowUndos() { enableUndoCreation(); }
133 
134  // The strict parameter restricts the behaviour to only affect the
135  // top undo block, rather than searching through the stack for the
136  // first block which will have an effect.
137  // The redoable flag determines whether or not the block about to be
138  // undone is added to the redo stack
139  void undo(bool strict = false, bool redoable = true);
140  void redo(bool strict = false);
141 
142  // Get the name of the next undo operation. This will force a prune.
143  const char *getUndoOperationName();
144 
145  // Get the name of the next redo operation. This will force a prune.
146  const char *getRedoOperationName();
147 
148  // Get the list of undo names.
149  // Note that the list contains pointers to within the undoblocks themselves
150  // and will become invalid upon any stack changes.
151  void getUndoNames(UT_StringList &names, bool prune=true);
152 
153  // Get the list of redo names. This will force a prune.
154  // Note that the list contains pointers to within the undoblocks themselves
155  // and will become invalid upon any stack changes.
156  void getRedoNames(UT_StringList &names, bool prune=true);
157 
158  /// Free all invalid undos/redos
159  void pruneInvalidUndos();
160 
161  int64 getMemoryUsage();
162  int64 getMemoryUsageLimit() { return myMemLimit; }
163  void setMemoryUsageLimit(int64 bytes);
164 
165  // clearUndos will wipe away all the undo and redos
166  void clearUndos();
167 
168  // clearUndoFlags is used to clear any flags that have been set
169  // for optimization during undo blocks
170  void clearUndoFlags();
171  void installUndoFlagClearer(void (*function)(void *data),
172  void *data);
173  void removeUndoFlagClearer(void (*function)(void *data),
174  void *data);
175 
176  // Install or clear a callback to be called whenever the undo/redo
177  // stack changes. Currently this is intended for the use of the
178  // undo manager UI, and so there can only be one interest.
179  void setUndoInterest(void (*function)(void *data),
180  void *data);
181 
182  const UT_UndoBlock *getUndoStack() const { return myUndoBlockStack; }
183  const UT_UndoBlock *getRedoStack() const { return myRedoBlockStack; }
184 
185 private:
186  void checkMemoryUsage();
187  void pruneUndoBlockStack();
188  void pruneRedoBlockStack();
189 
190  UT_UndoBlock *myUndoBlockStack;
191  UT_UndoBlock *myRedoBlockStack;
192 
193  int myBlockLevel;
194  int64 myMemLimit;
195  int64 myNetMemory;
196 
198 
199  utUndoInterestStruct *myInterest;
200 
201  struct SuspendItem
202  {
203  exint myId;
204  int myBlockLevel;
205  UT_StringHolder myName;
206  };
207  UT_Array<SuspendItem> mySuspendStack;
208  exint myLastSuspendId;
209 
210  char myBusyFlag;
211  char myEnableBugNotify;
212 };
213 
215 
216 // These following functions are provided for convenience.
217 // By default they affect the global Undo manager, but you
218 // can override that behaviour.
219 UT_API int UTbeginUndoBlock(const char *name,
220  UT_UndoBlockType blocktype,
221  UT_UndoManager *man = 0);
224 UT_API void UTendUndoBlock(int level, UT_UndoManager *man = 0);
226 
227 // Use this name for your undo block if you want it to adopt the name
228 // of the next undo block that gets added.
229 #define UT_UNDOBLOCK_ADOPT_NAME "Multiple Undo Operation"
230 
232 {
233 public:
234  UT_AutoUndoBlock(const char *name, UT_UndoBlockType blocktype)
235  {
236  myStackLevel = UTbeginUndoBlock(name, blocktype);
237  }
239  {
240  UTendUndoBlock(myStackLevel);
241  }
242 
243 private:
244  int myStackLevel;
245 };
246 
247 // Create local instances of this class to disallow undos on construction and
248 // allow them again when it goes out of scope.
250 {
251 public:
253  {
254  UT_UndoManager *undo_manager = UTgetUndoManager();
255  if (undo_manager)
256  undo_manager->disallowUndos();
257  }
258 
260  {
261  UT_UndoManager *undo_manager = UTgetUndoManager();
262  if (undo_manager)
263  undo_manager->allowUndos();
264  }
265 };
266 
267 #endif
UT_API UT_UndoManager * UTgetUndoManager()
GLint level
Definition: glcorearb.h:107
#define UT_API
Definition: UT_API.h:13
int64 getMemoryUsageLimit()
long long int64
Definition: SYS_Types.h:107
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:116
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:361