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_NonCopyable.h"
55 #include "UT_StringHolder.h"
56 #include "UT_ValArray.h"
57 #include <SYS/SYS_Compiler.h>
58 #include <SYS/SYS_Types.h>
59 
60 class UT_Undo;
61 class UT_UndoBlock;
62 struct utClearerStruct;
63 struct utUndoInterestStruct;
64 
66 {
69 };
70 
72 {
73 public:
75  ~UT_UndoManager();
76 
78 
79  static void disableUndoCreation();
80  static void enableUndoCreation();
81 
82  // When calling beginUndoBlock if you can determine that your code
83  // path will only be executed from outside any other undo block (eg
84  // on the mouse-down of a mouse-drag instantiated operation) then
85  // pass in UT_UNDOBLOCK_TOPLEVEL as the blocktype to beginUndoBlock.
86  // Otherwise pass in UT_UNDOBLOCK_GENERIC.
87  int beginUndoBlock(const char *name,
88  UT_UndoBlockType blocktype);
89 
90  // Instead of beginning a new undo block, this will append to the previous
91  // undo block if the given name matches. This only happens if we currently
92  // don't have any undoblocks open. If we do, then we will just use the
93  // current one just like beginUndoBlock(). The returned level must be
94  // passed to a corresponding endUndoBlock() call.
95  int beginLastUndoBlock(const char *name,
96  UT_UndoBlockType blocktype);
97 
98  // The level that's passed in to endUndoBlock should the level that
99  // was returned by the matching call to beginUndoBlock. If the code
100  // that called beginUndoBlock is too far from the call to endUndoBlock
101  // then you can pass in -1 (ie you don't know) but that means that
102  // some of the undo manager error detection won't be able to operate.
103  void endUndoBlock(int level);
104 
105  // This value should always be checked before adding to an undo block.
106  int willAcceptUndoAddition();
107  // This will return a non zero value if we are performing an undo or redo.
108  int performingUndoRedo();
109 
110  // The block level will be > 0 when within an undo block.
111  int blockLevel() const { return myBlockLevel; }
112 
113  // This returns true if any undos are being done, zero if undos
114  // are disabled.
115  int isUndoEnabled();
116 
117  // Add an undo to the current undoblock, taken ownership of the pointer.
118  // You *must* precede with this with a call to willAcceptUndoAddition().
119  // See the top of this file for how to use this.
120  void addToUndoBlock(UT_Undo *undo);
121 
122  // Add an undo to the undo block that last ended. Takes ownership of undo
123  void addToLastUndoBlock(UT_Undo *undo);
124 
125  // Suspend/Resume allowing toplevel undoblocks. All calls to suspend must
126  // be matched with a corresponding call to resume.
127  void suspendTopLevelUndoBlock();
128  void resumeTopLevelUndoBlock();
129  bool isTopLevelUndoSuspended() const;
130 
131  // Use these functions when you want to tell the undo manager
132  // that any undos that are being added (outside your control)
133  // should be ignored. Just frame the code section in question
134  // with disallowUndos() and allowUndos() in that order.
135  void disallowUndos() { disableUndoCreation(); }
136  void allowUndos() { enableUndoCreation(); }
137 
138  // The strict parameter restricts the behaviour to only affect the
139  // top undo block, rather than searching through the stack for the
140  // first block which will have an effect.
141  // The redoable flag determines whether or not the block about to be
142  // undone is added to the redo stack
143  void undo(bool strict = false, bool redoable = true);
144  void redo(bool strict = false);
145 
146  // Get the name of the next undo operation. This will force a prune.
147  const char *getUndoOperationName();
148 
149  // Get the name of the next redo operation. This will force a prune.
150  const char *getRedoOperationName();
151 
152  // Get the list of undo names.
153  // Note that the list contains pointers to within the undoblocks themselves
154  // and will become invalid upon any stack changes.
155  void getUndoNames(UT_StringList &names, bool prune=true);
156 
157  // Get the list of redo names. This will force a prune.
158  // Note that the list contains pointers to within the undoblocks themselves
159  // and will become invalid upon any stack changes.
160  void getRedoNames(UT_StringList &names, bool prune=true);
161 
162  /// Free all invalid undos/redos
163  void pruneInvalidUndos();
164 
165  int64 getMemoryUsage();
166  int64 getMemoryUsageLimit() { return myMemLimit; }
167  void setMemoryUsageLimit(int64 bytes);
168 
169  // clearUndos will wipe away all the undo and redos
170  void clearUndos();
171 
172  // clearUndoFlags is used to clear any flags that have been set
173  // for optimization during undo blocks
174  void clearUndoFlags();
175  void installUndoFlagClearer(void (*function)(void *data),
176  void *data);
177  void removeUndoFlagClearer(void (*function)(void *data),
178  void *data);
179 
180  // Install or clear a callback to be called whenever the undo/redo
181  // stack changes. Currently this is intended for the use of the
182  // undo manager UI, and so there can only be one interest.
183  void setUndoInterest(void (*function)(void *data),
184  void *data);
185 
186  const UT_UndoBlock *getUndoStack() const { return myUndoBlockStack; }
187  const UT_UndoBlock *getRedoStack() const { return myRedoBlockStack; }
188 
189 private:
190  void checkMemoryUsage();
191  void pruneUndoBlockStack();
192  void pruneRedoBlockStack();
193 
194  UT_UndoBlock *myUndoBlockStack;
195  UT_UndoBlock *myRedoBlockStack;
196 
197  int myBlockLevel;
198  int64 myMemLimit;
199  int64 myNetMemory;
200 
202 
203  utUndoInterestStruct *myInterest;
204 
205  struct SuspendItem
206  {
207  exint myId;
208  int myBlockLevel;
209  UT_StringHolder myName;
210  };
211  UT_Array<SuspendItem> mySuspendStack;
212  exint myLastSuspendId;
213 
214  char myBusyFlag;
215  char myEnableBugNotify;
216 };
217 
219 
220 // These following functions are provided for convenience.
221 // By default they affect the global Undo manager, but you
222 // can override that behaviour.
223 UT_API int UTbeginUndoBlock(const char *name,
224  UT_UndoBlockType blocktype,
225  UT_UndoManager *man = 0);
228 UT_API void UTendUndoBlock(int level, UT_UndoManager *man = 0);
230 
231 // Use this name for your undo block if you want it to adopt the name
232 // of the next undo block that gets added.
233 #define UT_UNDOBLOCK_ADOPT_NAME "Multiple Undo Operation"
234 
236 {
237 public:
238  UT_AutoUndoBlock(const char *name, UT_UndoBlockType blocktype)
239  {
240  myStackLevel = UTbeginUndoBlock(name, blocktype);
241  }
243  {
244  UTendUndoBlock(myStackLevel);
245  }
246 
247 private:
248  int myStackLevel;
249 };
250 
251 // Create local instances of this class to disallow undos on construction and
252 // allow them again when it goes out of scope.
254 {
255 public:
257  {
258  UT_UndoManager *undo_manager = UTgetUndoManager();
259  if (undo_manager)
260  undo_manager->disallowUndos();
261  }
262 
264  {
265  UT_UndoManager *undo_manager = UTgetUndoManager();
266  if (undo_manager)
267  undo_manager->allowUndos();
268  }
269 };
270 
271 #endif
int64 exint
Definition: SYS_Types.h:125
UT_API UT_UndoManager * UTgetUndoManager()
GLint level
Definition: glcorearb.h:108
#define UT_API
Definition: UT_API.h:14
int64 getMemoryUsageLimit()
UT_API int UTbeginUndoBlock(const char *name, UT_UndoBlockType blocktype, UT_UndoManager *man=0)
UT_API void UTendUndoBlock(int level, UT_UndoManager *man=0)
UT_UndoBlockType
int blockLevel() const
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
UT_API int UTwillAcceptUndoAddition(UT_UndoManager *man=0)
long long int64
Definition: SYS_Types.h:116
#define SYS_NO_DISCARD_RESULT
Definition: SYS_Compiler.h:93
UT_AutoUndoBlock(const char *name, UT_UndoBlockType blocktype)
GLuint const GLchar * name
Definition: glcorearb.h:786
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:335
Definition: format.h:895
Definition: format.h:2459