00001 // $Id: undoop.h 751 2006-03-31 15:43:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 #ifndef INC_UNDOOP 00100 #define INC_UNDOOP 00101 00102 #include "ops.h" 00103 #include "node.h" // for classas and AttachNodeDirection 00104 #include "pathtype.h" 00105 00106 class NodeRenderableInk; 00107 class NodePath; 00108 class Path; 00109 class AttrBrushType; 00110 00111 00112 /******************************************************************************************** 00113 00114 class ObjectItem: public ListItem 00115 00116 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00117 Created: 11/5/95 00118 Purpose: ObjectItems are held in ObjectSets 00119 SeeAlso: ObjectSet 00120 SeeAlso: Node::AppliedAttrSet 00121 00122 ********************************************************************************************/ 00123 00124 class ObjectItem: public ListItem 00125 { 00126 public: 00127 NodeRenderableInk* pObject; 00128 }; 00129 00130 00131 /******************************************************************************************** 00132 00133 > class ObjectSet: public List 00134 00135 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00136 Created: 15/5/95 00137 Purpose: A set of NodeRenderableInk objects 00138 SeeAlso: ObjectItem 00139 00140 ********************************************************************************************/ 00141 00142 class ObjectSet: public List 00143 { 00144 public: 00145 00146 // A function to return a copy of the ObjectSet 00147 ObjectSet* CopySet(); 00148 00149 // A simple function to add attr types to the AppliedAttrSet (Chiecks for duplicates) 00150 virtual BOOL AddToSet(NodeRenderableInk* pObject); 00151 00152 // A function to determine if pObject is in the set 00153 BOOL InSet(NodeRenderableInk* pObject); 00154 00155 ~ObjectSet() { DeleteAll(); }; 00156 00157 }; 00158 00159 00160 00161 /******************************************************************************************** 00162 00163 > class PreDelFactorOutInfoItem: public ListItem 00164 00165 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00166 Created: 31/5/95 00167 Purpose: PreDelFactorOutInfoItems are used by the GetPreDelFactorOutInfo and 00168 DoFactorOutAfterDeletion functions. See these for a description 00169 of its purpose. 00170 00171 SeeAlso: - 00172 00173 ********************************************************************************************/ 00174 00175 class PreDelFactorOutInfoItem: public ListItem 00176 { 00177 public: 00178 NodeRenderableInk* pCompound; 00179 AttrTypeSet AttrTypesToFactorOut; 00180 }; 00181 00182 00183 /******************************************************************************************** 00184 00185 > class UndoableOperation: public Operation 00186 00187 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00188 Created: 9/3/94 00189 Purpose: All Undoable operations should be derived from this class. 00190 SeeAlso: Operation 00191 00192 ********************************************************************************************/ 00193 00194 00195 class UndoableOperation: public Operation 00196 { 00197 CC_DECLARE_DYNCREATE( UndoableOperation ) 00198 00199 public: 00200 // ------------------------------------------------------------------------------------- 00201 // The all new Do functions 00202 00203 // These functions are the operation's high level interface, a shiny veneer protecting 00204 // you from such beasties as system integrity, and attribute optimisation. Each Do 00205 // function performs a 'bit' of an operation and generates the actions neccessary to 00206 // undo/redo the damage it performs. The functions each return a BOOL 00207 // Success/Failure status. 00208 00209 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00210 // Whenever a DO function fails the operation should tidyup 00211 // and then call End(). It should not under any circumstance call any other Do functions 00212 // or create any other actions. 00213 00214 // Do functions which operate on nodes normally come in two flavours. The generally 00215 // more useful flavour takes a range of nodes as its input (usually the range 00216 // of selected nodes). Also provided is a flavour which operates on a single node. 00217 00218 // Some Do functions have out of necessity to create an action for every node in the 00219 // range which is supplied to it. An example of such a function is DoMoveNodes which 00220 // needs to record the old position of every node which moves in the tree. 00221 // Other Do functions like DoInvalidateNodesRegions need only to create a single 00222 // action which stores the nodes it must operate on compactly in a range. If you are 00223 // to perform an action (for want of a better word) on a range of nodes, then you 00224 // would be extremely silly to call the single node flavour for each node in the 00225 // range, (they are very memory greedy). Even if you know that a function has 00226 // currently to create an action for each range member it is far better to call the 00227 // range flavour because it could all change in the future. 00228 00229 // Operation History size integrity 00230 // -------------------------------- 00231 00232 // In Camelot it is important that the size of the operation history accurately reflects 00233 // the amount of memory which has been allocated for undo and redo information. 00234 00235 // Most of the time you are shielded from worrying about such things. However some of the 00236 // lower level do functions require a bit of information to help them to calculate the 00237 // size of the undo/redo information. 00238 00239 // A good example of this is the DoHideNode function which takes in an IncludeSubtreeSize 00240 // flag. This indicates if the size of the subtree being hidden should be considered as 00241 // 'in' the operation history or not. 00242 00243 // DoHideNode is used whenever we need to remove an object from the tree. In this 00244 // circumstance we would set IncludeSubtreeSize = TRUE, because the subtree which has 00245 // been removed, should be considered 'in' the Operation History. 00246 00247 // DoHideNode is also used whenever we move a subtree from one position in the document 00248 // tree to another position in the tree. In this circumstance we set 00249 // IncludeSubtreeSize = FALSE, because the subtree which is being hidden is in the 00250 // document still, not in the operation history. 00251 00252 00253 // ************************************************************************************* 00254 // Low level Do functions 00255 // A Low level Do function is a function which usually gets gets called by higher level 00256 // Do functions. It generally creates a single action. 00257 00258 // ------------------------------------------------------------------------------------- 00259 // Functions for invalidating regions 00260 00261 // The reason these functions require a spread parameter is that very often the node 00262 // that needs invalidating is hidden. 00263 BOOL DoInvalidateNodesRegions(Range NodeRange, 00264 BOOL IncludeBlobs, 00265 BOOL UndoBlobs = FALSE, 00266 BOOL IfBgRedraw = FALSE, 00267 BOOL bForceRecache = TRUE); 00268 00269 BOOL DoInvalidateNodeRegion(NodeRenderableBounded* Node, 00270 BOOL IncludeBlobs, 00271 BOOL UndoBlobs = FALSE, 00272 BOOL IfBgRedraw = FALSE, 00273 BOOL bForceRecache = TRUE); 00274 00275 // Function to invalidate an arbitary region on a spread 00276 BOOL DoInvalidateRegion (Spread *pSpread, const DocRect &InvalidRegion ); 00277 00278 // ------------------------------------------------------------------------------------- 00279 // These functions save a copy of the specified nodes. The copies are restored when we undo. 00280 00281 BOOL DoSaveCopyOfNode(NodeRenderable* Node); 00282 BOOL DoSaveCopyOfNodes(Range NodeRange); 00283 00284 // ------------------------------------------------------------------------------------- 00285 // functions for hiding subtrees 00286 00287 // This function must be used if a pointer to the NodeHidden hiding the NodeToHide is 00288 // required 00289 BOOL DoHideNode(Node* NodeToHide, BOOL IncludeSubtreeSize, NodeHidden** nodeHidden = NULL, BOOL TellSubtree = TRUE); 00290 00291 BOOL DoHideNodes(Range NodeRange, BOOL IncludeSubtreeSize, BOOL TellSubtree = TRUE); 00292 BOOL DoHideComplexRange(Range& RangeToHide); 00293 00294 // ************************************************************************************* 00295 // High level Do functions 00296 00297 // This function inserts a new node onto the active layer of a spread 00298 BOOL DoInsertNewNode(NodeRenderableBounded* NewNode, 00299 Spread *pSpread, 00300 //DocRect Bounds, 00301 BOOL InvalidateRgn, 00302 BOOL ClearSelection = TRUE, 00303 BOOL SelectNewObject = TRUE, 00304 BOOL NormaliseAttributes = TRUE); 00305 00306 // This function inserts a new node attached to ContextNode in the direction specified 00307 00308 BOOL DoInsertNewNode(NodeRenderableBounded* NewNode, 00309 Node* ContextNode, 00310 AttachNodeDirection Direction, 00311 //DocRect Bounds, 00312 BOOL InvalidateRegion, 00313 BOOL ClearSelection = TRUE, 00314 BOOL SelectNewObject = TRUE, 00315 BOOL NormaliseAttributes = TRUE); 00316 00317 // -------------------------------------------------------------------------------------- 00318 // Functions to move a node to another position in the document tree 00319 00320 BOOL DoMoveNode(Node* MoveNode, 00321 Node* Destination, 00322 AttachNodeDirection Direction); 00323 00324 BOOL DoMoveNodes(Range NodeRange, 00325 Node* Destination, 00326 AttachNodeDirection Direction); 00327 00328 // This static BOOL is a bit of a bodge. 00329 // It is set while a node is being moved, so that the undo ops know not 00330 // to call the 'HidingNode' function, which should only be called when 00331 // a node is 'really' being hidden. 00332 static BOOL MovingNode; 00333 00334 // -------------------------------------------------------------------------------------- 00335 // Functions to transform objects 00336 00337 BOOL DoTransformNode(NodeRenderableInk* NodeToTransform, 00338 TransformBase* T); 00339 00340 BOOL DoTransformNodes(Range NodeRange, 00341 TransformBase* T); 00342 00343 // -------------------------------------------------------------------------------------- 00344 00345 BOOL DoMakeShapes(Range NodeRange); 00346 BOOL DoFlattenRange(Range NodeRange); 00347 00348 BOOL DoCopyNodesToClipboard(Range NodeRange); 00349 00350 // -------------------------------------------------------------------------------------- 00351 00352 // Hides all instances of nodes with class NodeClass from the subtree 00353 BOOL DoRemoveAttrTypeFromSubtree(Node* Subtree, CCRuntimeClass* NodeClass, Node* pExceptThis = NULL); 00354 00355 // Functions that manipulate NodePath objects 00356 // Helper function to change selection with undo 00357 BOOL DoChangeSelection(NodePath* ThisNode, INT32 Index, BOOL NewState); 00358 BOOL DoDeletePathSection(NodePath* ThisNode, INT32 Index, INT32 NumElements, BOOL RedrawPath = TRUE); 00359 BOOL DoAlterPathElement(NodePath* ThisNode, 00360 INT32 Index, 00361 DocCoord NewCoord, 00362 PathFlags NewFlags, 00363 PathVerb NewVerb, 00364 BOOL RedrawPath = TRUE); 00365 BOOL DoInsertPathElement( NodePath* ThisPath, 00366 INT32 Index, 00367 DocCoord NewCoord, 00368 PathFlags NewFlags, 00369 PathVerb NewVerb, 00370 BOOL RedrawPath = TRUE); 00371 BOOL DoReversePath (NodePath* ThisPath, BOOL RedrawPath = TRUE); 00372 BOOL DoSmoothNodePath(NodePath* pThisNode, double smoothacc); 00373 BOOL DoMakeNodeFromPath(NodePath* pParentNode, 00374 Path* pParentPath, 00375 AttachNodeDirection Direction, 00376 BOOL CopyAttributes); 00377 00378 00379 00380 // -------------------------------------------------------------------------------------- 00381 // Do functions for attribute optimisation 00382 00383 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00384 // This function must get called prior to a new attribute being applied 00385 BOOL DoLocaliseForAttrChange(NodeRenderableInk* Object, 00386 AttrTypeSet* pAffectedAttrTypes, 00387 ObjectSet* pLocalisedCompounds); 00388 00389 BOOL DoLocaliseForAttrChange(NodeRenderableInk* Object, 00390 CCRuntimeClass* pAffectedAttrType, 00391 ObjectSet* pLocalisedCompounds); 00392 00393 // versions of the function which localise all attributes in a range 00394 BOOL DoLocaliseForAttrChange(Range* pRange, 00395 AttrTypeSet* pAffectedAttrTypes, 00396 BOOL ExcludeTextObjects = FALSE); 00397 00398 BOOL DoLocaliseForAttrChange(Range* pRange, 00399 CCRuntimeClass* pAffectedAttrType); 00400 00401 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00402 // This function must get called after an attribute has been applied 00403 // Useful when applying multiple attributes to a single object 00404 BOOL DoFactorOutAfterAttrChange(NodeRenderableInk* Object, 00405 AttrTypeSet* pAffectedAttrTypes); 00406 00407 // Useful when applying a single attribute to a single object 00408 BOOL DoFactorOutAfterAttrChange(NodeRenderableInk* Object, 00409 CCRuntimeClass* pAffectedAttrType); 00410 00411 // versions of the function which factor out attributes on all nodes in the range 00412 00413 // useful when applying multiple attributes to a range of objects 00414 BOOL DoFactorOutAfterAttrChange(Range* pRange, 00415 AttrTypeSet* pAffectedAttrTypes); 00416 00417 // useful when applying a single attribute to a range of objects 00418 BOOL DoFactorOutAfterAttrChange(Range* pRange, 00419 CCRuntimeClass* pAffectedAttrType); 00420 00421 // versions of the function which factor out attributes on all compounds in the 00422 // pLocalisedCompounds set 00423 00424 // Useful when applying attributes to a set of objects which don't fall into a range 00425 BOOL DoFactorOutAfterAttrChange(ObjectSet* pLocalisedCompounds, 00426 AttrTypeSet* pAffectedAttrTypes); 00427 00428 BOOL DoFactorOutAfterAttrChange(ObjectSet* pLocalisedCompounds, 00429 CCRuntimeClass* pAffectedAttrType); 00430 00431 // These function should be called before deleting all objects in a range. It works 00432 // out the attributes which must be factored out after objects have been deleted. 00433 00434 // This function perhaps belongs in the range cos this is what it operates on. 00435 // However it seems more convenient for it to live here as it is designed 00436 // to be used with the DoFactorOutAfterDeletion function. 00437 00438 // These funs are now defunct 00439 //BOOL GetPreDelFactorOutInfo(Range* pRange, List* pPreDelFactorOutInfoList); 00440 00441 // This function should get called after a range of objects have been deleted ('Hidden') 00442 //BOOL DoFactorOutAfterDeletion(List* pPreDelFactorOutInfoList); 00443 00444 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00445 00446 BOOL DoFactorOutCommonChildAttributes(NodeRenderableInk* CompoundObject, 00447 BOOL Global = FALSE, 00448 AttrTypeSet* pAffectedAttrTypes = NULL); 00449 00450 BOOL DoFactorOutCommonAttributes(NodeRenderableInk* pRootNode, 00451 BOOL bGlobal = FALSE, 00452 AttrTypeSet* pAffectedAttrTypes = NULL); 00453 00454 BOOL DoLocaliseCommonAttributes(NodeRenderableInk* CompoundObject, 00455 BOOL CheckForDuplicates = FALSE, 00456 BOOL Global = FALSE, 00457 AttrTypeSet* pAffectedAttrTypes = NULL); 00458 00459 00460 // -------------------------------------------------------------------------------------- 00461 // Functions for selecting/deselecting nodes (these may not be required in future) 00462 00463 BOOL DoSelectNode(NodeRenderableInk* NodeToSelect, Spread *Parent = NULL); 00464 BOOL DoDeselectNode(NodeRenderableInk* NodeToDeselect, Spread *Parent = NULL); 00465 00466 static BOOL RegisterOpDescriptor( 00467 UINT32 toolID, 00468 UINT32 txID, 00469 CCRuntimeClass* RuntimeClass, 00470 TCHAR* tok, 00471 pfnGetState gs, 00472 UINT32 helpId = 0, 00473 UINT32 bubbleID = 0, 00474 UINT32 resourceID = 0, 00475 UINT32 controlID = 0, 00476 SystemBarType GroupBarID = SYSTEMBAR_ILLEGAL, 00477 BOOL ReceiveMessages = TRUE, 00478 BOOL Smart = FALSE, 00479 BOOL Clean = FALSE, 00480 UINT32 OneOpenInstID =0, 00481 UINT32 AutoStateFlags = 0 00482 ); 00483 00484 00485 00486 UndoableOperation(); 00487 virtual ~UndoableOperation(); 00488 00489 // This virtual function gets called from the EndOp method after the op has successfully ended 00490 // and added to the OperationHistory. Override this function to perform operation merging. Note 00491 // that this function cannot fail (cos it's too scary). 00492 virtual void PerformMergeProcessing() ; 00493 void MergeWithPrevious(); 00494 00495 // -------------------------------------------------------------------------------------- 00496 // Karim MacDonald 19/01/2000 00497 // An override for Operation's UpdateChangedNodes(ObjChangedaram*, Spread*) function, 00498 // as well as a NoStretchUpdateChangedNodes() fn, both required as part of the stretching 00499 // implementation. 00500 virtual BOOL UpdateChangedNodes(ObjChangeParam* pParam, Spread* pSpread = NULL); 00501 virtual BOOL NoStretchUpdateChangedNodes(ObjChangeParam* pParam, Document* pDoc); 00502 00503 // Karim 20/01/2000 00504 // A virtual behaviour-ID function, used by the stretching/extension framework, which 00505 // denotes whether this node might result in the bounds of a named set changing. This 00506 // most often happens when a node changes its bounds, hence the function name. 00507 // 00508 // The rule of thumb is - if your Op might change the bounds of a node, then override 00509 // this function and return TRUE from it. examples: OpGroup - no; OpPaste - yes. 00510 // Do a search for 'MayChangeNodeBounds' for more examples. 00511 virtual BOOL MayChangeNodeBounds() const { return FALSE; } 00512 00513 00514 // -------------------------------------------------------------------------------------- 00515 // Phil 16/02/2005 00516 // 00517 // Functions for applying attributes to nodes 00518 // 00519 public: 00520 virtual BOOL GetStarted() const { return FALSE; } 00521 00522 private: 00523 // This var is a flag that ensures that this warning will only appear once for the lifetime of this op 00524 BOOL WarnInsertObjsOntoLockedLayers; 00525 00526 // DMc 00527 // includes the parent nodes to transform in the given range 00528 Range * IncludeParentTransformNodesInRange(Range * Rng); 00529 }; 00530 00531 #endif