ops.h

Go to the documentation of this file.
00001 // $Id: ops.h 877 2006-04-24 17:15:07Z 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     Declaration of the following classes:
00100 
00101     ActionList: Class used by an Operation to store UNDO, REDO, and Smart Duplicate actions
00102     Operation:  Class from which all Camelot operations are derived
00103     Action:     Class from which all operations actions are derived
00104 
00105 */  
00106  
00107  
00108 /*
00109  * */    
00110 
00111 #ifndef INC_OPS
00112 #define INC_OPS         
00113 
00114 #include "listitem.h"   
00115 #include "list.h"
00116 #include "binds.h"
00117 #include "clikmods.h" 
00118 #include "doccoord.h"
00119 #include "docrect.h"
00120 #include "opdesc.h"      
00121 #include "range.h"
00122 //#include "basedoc.h"
00123 #include "selstate.h"
00124 
00125 //#include "bars.h"
00126 
00127 class Document; 
00128 class DocView;
00129 class View;
00130 class OperationHistory;
00131 class Spread;
00132 class Node;
00133 class NodeHidden;
00134 class TransformBase;
00135 class KeyPress;
00136 class Action;
00137 class BaseDocument;
00138 
00139 
00140 /*******************************************************************************************
00141 
00142 < SystemBarType
00143 
00144     Comment:    A number of hidden bars are created by the kernel during startup to group
00145     together OpDescriptors in sensible groups for the user. This enum allows each of those
00146     hidden bars to be uniquely identified.
00147 
00148 enum SystemBarType { SYSTEMBAR_ILLEGAL = 0,
00149                      SYSTEMBAR_FILE,
00150                      SYSTEMBAR_EDIT,
00151                      SYSTEMBAR_ATTRIBUTE,
00152                      SYSTEMBAR_ARRANGE,
00153                      SYSTEMBAR_UTILITIES,
00154                      SYSTEMBAR_WINDOW,
00155                      SYSTEMBAR_VIEW = SYSTEMBAR_WINDOW,
00156                      SYSTEMBAR_HELP,
00157                      SYSTEMBAR_DEBUG
00158                      SYSTEMBAR_FEATHER
00159                     };
00160 
00161     SeeAlso:    SystemBarOp::FindType
00162 
00163 ********************************************************************************************/ 
00164 
00165 enum SystemBarType { SYSTEMBAR_ILLEGAL = 0,
00166                      SYSTEMBAR_FILE,
00167                      SYSTEMBAR_EDIT,
00168                      SYSTEMBAR_ATTRIBUTE,
00169                      SYSTEMBAR_ARRANGE,
00170                      SYSTEMBAR_UTILITIES,
00171                      SYSTEMBAR_WINDOW,
00172                      SYSTEMBAR_VIEW = SYSTEMBAR_WINDOW, // Alias VIEW to WINDOW for now...
00173                      SYSTEMBAR_HELP,
00174                      SYSTEMBAR_ANIMATION,
00175                      SYSTEMBAR_TYPESETTING,
00176                      SYSTEMBAR_DEBUG,
00177                      SYSTEMBAR_FEATHER
00178                     };
00179 
00180 
00181 /********************************************************************************************
00182 
00183 >   class ActionList: public List
00184 
00185     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00186     Created:    6/7/93
00187     Purpose:    An ActionList is a list object which holds actions which can be
00188                 executed. It is used by Operation objects to hold UNDO, REDO and Smart 
00189                 duplicate actions.   
00190                 
00191     SeeAlso:    Operation  
00192     SeeAlso:    Action
00193 
00194 ********************************************************************************************/
00195 
00196 class CCAPI ActionList: public List
00197 {    
00198     CC_DECLARE_MEMDUMP( ActionList ) 
00199 public:     
00200     ActionList(); 
00201     ~ActionList(); 
00202     BOOL ExecuteForwards(BOOL AllButLast); 
00203     BOOL ExecuteBackwards(BOOL AllButLast, BOOL bIgnoreSelectActions = FALSE);
00204 
00205     // This function can be used to search the action list to see if it contains an action
00206     // with a specific runtime class.
00207     Action* FindActionOfClass(CCRuntimeClass* ClassOfActionToFind, Action* LastAction = NULL); 
00208 
00209 }; 
00210   
00211 // The Opflags structure is used by the operation class to hold information about 
00212 // how an operation should behave when it ends. 
00213 struct CCAPI OpFlgsStr
00214 {                            // TRUE when:
00215     BOOL Failed : 1;         // Action could not be created
00216     BOOL ExecuteOnEnd : 1;   // Execute all actions in End
00217     BOOL AllButLast : 1;     // Execute all acts but last one in End
00218     BOOL KeepOnEnd : 1;      // Not deleted in End
00219     BOOL UnwindingActions:1; // Op is being unwound
00220     BOOL HasOwnTimeIndicator:1; // Usually FALSE by default, however when TRUE indicates that
00221                                 // the operation should not use the default hourglass 
00222     BOOL SucceedAndDiscard:1;   // After the operation has finished all undo actions will be discarded
00223     BOOL DeleteOnEnd : 1;       // After the operation has ended it will be deleted
00224     BOOL IgnoreSelectActions : 1;   // Ignore selections when executing (for use when executing undo due to selection changes)
00225                                                         
00226 };
00227 
00228                   
00229 // Current status of operation:-
00230 enum OperationStatus { UNDO, REDO, DO };
00231 
00232 /********************************************************************************************
00233 >   class CUniversalParam
00234 
00235     Author:     Luke_Hart (Xara Group Ltd) <camelotdev@xara.com>
00236     Created:    14/10/05
00237 
00238     Purpose:    Simple class that makes it possible to have parameters that can either be
00239                 a pointer or an INT32 in a 64bit safe manner.
00240 
00241 ********************************************************************************************/
00242 
00243 class CUniversalParam
00244 {
00245 private:
00246     union
00247     {
00248         void           *m_pVal;
00249         INT32           m_lVal;
00250     };
00251 
00252 public:
00253     CUniversalParam() : m_pVal( NULL )
00254     {}
00255     CUniversalParam( void *p ) : m_pVal( p )
00256     {}
00257     CUniversalParam( INT32 l ) : m_lVal( l )
00258     {}
00259 
00260     void *operator =( void *p )
00261     {
00262         return m_pVal = p;
00263     }
00264     INT32 operator =( INT32 l )
00265     {
00266         return m_lVal = l;
00267     }
00268 
00269     operator void *()
00270     {
00271         return m_pVal;
00272     }
00273     operator INT32()
00274     {
00275         return m_lVal;
00276     }
00277 };
00278 
00279 /********************************************************************************************
00280 >   class OpParam
00281 
00282     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00283     Created:    9/6/94
00284 
00285     Purpose:    Operation parameter structure. The meaning of the structure's fields are
00286                 defined by each operation. Note that sensible Operations will derive a
00287                 special OpParam for their own specific needs, so you should use the
00288                 derived class where it is available.
00289 
00290     SeeAlso:    Operation::DoWithParam
00291 
00292 ********************************************************************************************/
00293 
00294 class OpParam : public CCObject
00295 {
00296 CC_DECLARE_DYNAMIC(OpParam)
00297 
00298 public:
00299     OpParam() { Param1 = Param2 = INT32(0); Output = NULL; }
00300     OpParam(CUniversalParam P1, CUniversalParam P2) { Param1 = P1; Param2 = P2; Output = 0; }
00301     OpParam(CUniversalParam P1, CUniversalParam P2, BOOL* Out) { Param1 = P1; Param2 = P2; Output = Out; }
00302     CUniversalParam     Param1;
00303     CUniversalParam     Param2;
00304 
00305     BOOL               *Output; 
00306 };
00307 
00308 /********************************************************************************************
00309 
00310 >   class Operation : public MessageHandler
00311 
00312     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00313     Created:    6/7/93
00314     Purpose:    This abstract class represents an operation which is a single job initiated 
00315                 by the user. You should derive all non undoable operations directly from 
00316                 this base class. 
00317                 
00318     SeeAlso:    OperationHistory
00319     SeeAlso:    UndoableOperation
00320 
00321 ********************************************************************************************/
00322 
00323 class CCAPI Operation : public MessageHandler
00324 {   
00325     CC_DECLARE_DYNCREATE( Operation )   
00326     
00327 public:
00328     virtual void OnClickWhileDragging(OilCoord PointerPos, ClickType Click, ClickModifiers Mods, BOOL bSolidDrag);
00329 
00330     Operation(CCRuntimeClass* MsgHandlerClass = CC_RUNTIME_CLASS(Operation)); 
00331     virtual ~Operation();
00332 
00333     static BOOL Initialise();
00334 
00335     virtual void End(); 
00336 
00337     // Mark H
00338     virtual Matrix GetCurrentMatrix() { return Matrix(); };
00339     
00340     UINT32 GetSize(); 
00341  
00342     static Operation* GetCurrentDragOp();
00343     virtual BOOL SnappingDrag() { return TRUE; }
00344 
00345     // Event handler functions called by DocView/CCamView...
00346     virtual void DragPointerMove( DocCoord PointerPos,
00347                         ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag);
00348     virtual void DragPointerIdle( DocCoord PointerPos,
00349                         ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag);
00350     virtual void DragFinished( DocCoord PointerPos,
00351                        ClickModifiers ClickMods, Spread *pSpread,
00352                        BOOL Success, BOOL bSolidDrag);
00353     virtual BOOL DragKeyPress(KeyPress* pKeyPress, BOOL bSolidDrag);
00354     virtual void DragModeChanged(BOOL bSolidDrag);
00355                        
00356     // Function to translate coord from one spread to another.
00357     DocCoord MakeRelativeToSpread(Spread *Dest, Spread *Src, DocCoord);
00358 
00359     // Function to allow operations to render something during a drag
00360     virtual void RenderDragBlobs(DocRect, Spread*, BOOL bSolidDrag);
00361 
00362     // Function called on idle events if required
00363     virtual BOOL OnIdleEvent();
00364 
00365     // These Fail functions tell the Op what to do when it ends.
00366     void FailAndExecute();
00367     void FailAndExecuteAllButLast();
00368     void FailAndDiscard();
00369     void FailAndExecuteIgnoreSelActions();
00370 
00371     // When called operation will not be undoable 
00372     void SucceedAndDiscard();
00373 
00374     // These two functions execute the appropriate action list.
00375     virtual BOOL Undo();
00376     virtual BOOL Redo();
00377 
00378     // This function asks the operation to Do itself again. Notice that DoSmart 
00379     // can be polymorphic because no smart functions can take params - they 
00380     // all work on the selection.
00381     virtual void DoSmart();
00382     
00383     // This function is the polymorphic one to be used to Do all simple Operations. All subclasses 
00384     // of Operation will implement there own DO function maintaining the same interface as
00385     // below in order for the Do function to work with all simple Operations. (This will be
00386     // particularly useful for implementing Menu Operations!)
00387     virtual void Do(OpDescriptor*);   
00388     
00389     // Same as Do except it allows a parameter to be passed - Yes I know this is a bit yuk
00390     // but at least is saves me changing every Do function in Camelot.
00391     virtual void DoWithParam(OpDescriptor*, OpParam* pOpParam);            
00392 
00393     OpFlgsStr   GetOpFlgs();
00394     BOOL        OpHasFailed() const {return OpFlags.Failed;}
00395     void        DeleteOnEnd();
00396     void        KeepOnEnd() {OpFlags.KeepOnEnd = TRUE;}
00397 
00398     ActionList* GetUndoActionList(); 
00399     ActionList* GetRedoActionList(); 
00400     
00401     OperationStatus OpStatus; // When doing the operation for the first time equals DO 
00402                               // When UNDOING the operation equals UNDO 
00403                               // when REDOING the operation equals REDO
00404 
00405     // Utility methods required by the ALLOC_WITH_FAIL macro
00406     BOOL UserWantsToDeleteUndoOps(); 
00407     void OperationMemoryFailure();
00408 
00409     // Find out which document/(doc)view this operation is working on.
00410     Document *GetWorkingDoc()       { return pOurDoc; }
00411     View     *GetWorkingView()      { return pOurView; }
00412     DocView  *GetWorkingDocView();
00413 
00414     // Retrieve The Operations Name
00415     virtual void GetOpName(String_256*);
00416 
00417     // interogates the current (drag) Operation for statusLine text
00418     virtual BOOL GetStatusLineText(String_256* pText, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods);
00419 
00420     // Call this function from the Operation's Init method to register the operations OpDescriptor
00421     static BOOL RegisterOpDescriptor(
00422                                       UINT32 toolID,       // Module (Tool) Identifier
00423                                       UINT32 txID,         // String Resource ID
00424                                       CCRuntimeClass* RuntimeClass, // The operations runtime class
00425                                       TCHAR* tok,        // pointer to the token string
00426                                       pfnGetState gs,    // pointer to the GetState function
00427                                       UINT32 helpId = 0,     // help identifier 
00428                                       UINT32 bubbleID = 0, // string resource for bubble help
00429                                       UINT32 resourceID = 0,    // resource ID
00430                                       UINT32 controlID = 0, // control ID
00431                                       SystemBarType GroupBarID = SYSTEMBAR_ILLEGAL, // group bar ID
00432                                       BOOL ReceiveMessages = TRUE,  // BODGE
00433                                       BOOL Smart = FALSE,
00434                                       BOOL Clean = TRUE,   
00435                                       OpDescriptor *pVertOpDesc = NULL,
00436                                       UINT32 OneOpenInstID = 0,     
00437                                       UINT32 AutoStateFlags = 0,
00438                                       BOOL fCheckable = FALSE
00439                                       );
00440 
00441     // These functions should be used in conjuction with Node::AllowOp() or Range::AllowOp() to allow
00442     // the op to work when select-inside is present.
00443     // Calling these functions should ensure that parent nodes update themselves when an op is applied to
00444     // their children
00445     virtual BOOL UpdateChangedNodes(ObjChangeParam* pParam,Spread* pSpread = NULL);
00446     virtual BOOL UpdateChangedNode(ObjChangeParam* pParam,Node* pNode);
00447 
00448     // This varient will update all nodes in all the docs in the application
00449     virtual BOOL UpdateAllChangedNodes(ObjChangeParam* pParam);
00450     // This will update all nodes in the given document
00451     virtual BOOL UpdateChangedNodes(ObjChangeParam* pParam,Document* pDoc);
00452 
00453     // Dumps the undo/redo action lists to the debugger
00454     virtual void Dump();
00455 
00456     static BOOL GetQuickRender(Node* pNode);
00457     static void SetQuickRender(BOOL bNewState, Operation* pQROp = NULL);
00458 
00459 protected: 
00460 
00461     // Functions called by subclasses of Operation...
00462     BOOL StartDrag( DragType type, 
00463                     DocRect* MoveBBox = NULL,
00464                     DocCoord* StartPos = NULL,
00465                     BOOL KeepAccuracy = TRUE,
00466                     BOOL bSolidDragSupported = FALSE);
00467     BOOL EndDrag(void);  
00468     
00469     void EndOp(); // The old End() function   
00470 
00471     // Operation flags structure  
00472     OpFlgsStr OpFlags;      
00473 
00474     // Points to the document/view this Operation is associated with when "live".
00475     //
00476     // NB. pOurView is usually NULL as many operations don't care which or many views are
00477     //     associated with the document, but some do - e.g. changing rendering quality,
00478     //     zooming in and out, etc.
00479     Document* pOurDoc;
00480     View*     pOurView;
00481      
00482     // UNDO/REDO lists.         
00483     // Note: At any given time ONE of these lists MUST be empty. This means that there is no 
00484     // need to store flags to indicate if the operation is for UNDO or REDO. If UndoActions
00485     // contains any actions then the operation can be undone, else the operation can be 
00486     // redone. 
00487     
00488     ActionList UndoActions;     
00489     ActionList RedoActions;        
00490      
00491     // Actions for smart duplicate
00492     ActionList SmartActions;          
00493 
00494 public: 
00495     // Somebody might want to invoke an action given an undoable op pointer. At this point, they
00496     // will need access to the action lists. So give them a public access function.
00497     // Only use these if you know what you are doing!
00498     // Should be const but of course then nothing would work!
00499     ActionList * GetUndoActions() { return &UndoActions; }
00500     ActionList * GetRedoActions() { return &RedoActions; }
00501     ActionList * GetSmartActions() { return &SmartActions; }
00502 
00503 private:
00504     
00505     // The string OpName should be defined in a subclass of operation and be returned 
00506     // by the GetName() function. It is not defined for the operation class. 
00507     
00508     // static String OpName; // The name of the operation object    
00509     
00510     // For drag operations CurrentDragOp will be a pointer to the Operation which should 
00511     // receive mouse movement events during the drag. It will ensure that only one
00512     // operation can perform a drag at a time and that keypress events cannot change the
00513     // state of the document while a drag is taking place.    
00514     
00515     static Operation* CurrentDragOp; 
00516 
00517     // The DeleteUndoOpsToMake space flag is set to TRUE after the user responds YES to the
00518     // question "do you want to delete undo operations to make space for the current operation ?". 
00519     // It is required so that the user is not asked the same question more than once in performing 
00520     // the operation (The next time YES will be taken as the default). It will be reset to FALSE
00521     //  when the operation ends. 
00522     BOOL DeleteUndoOpsToMakeSpace;
00523 
00524     
00525     // In the operations End method if pDocToInformOfOpStatus is not NULL then
00526     // If the operation has failed AbortComponent copy is called on the document
00527     // else EndComponentCopy is called. 
00528     BaseDocument* pDocToInformOfOpStatus;   
00529 
00530     // Vars to do with stopping auto-repeat keys during drags
00531     static INT32 CurKeyboardSpeed;
00532     static BOOL ResetKeyboardSpeed;
00533     static BOOL KeyboardRepeatOffDuringDrags;
00534 
00535     static BOOL s_bQuickRender;
00536 
00537 public:
00538     void InformDocComponentsOfOperationsOutcome(BaseDocument* pDoc) { pDocToInformOfOpStatus = pDoc; }; 
00539     
00540 };
00541 
00542 
00543 enum ActionCode { AC_FAIL, AC_OK, AC_NORECORD }; 
00544 
00545 /********************************************************************************************
00546 
00547 >   class Action: public ListItem
00548 
00549     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00550     Created:    6/7/93
00551     Purpose:    This class represents an Action which is an individual job which is executed
00552                 to accomplish an operation. An operation contains lists of actions to 
00553                 perform Undo, Redo and Smart Duplication. 
00554                 
00555     SeeAlso:    Operation
00556 
00557 ********************************************************************************************/
00558 
00559 class CCAPI Action: public ListItem
00560 {        
00561     CC_DECLARE_DYNCREATE( Action ) 
00562 
00563     friend class OperationHistory; 
00564     
00565 public: 
00566 
00567     Action(); 
00568     virtual ~Action();   
00569     virtual void Slaughter(); // A more extreme form of destruction 
00570     virtual ActionCode Execute();          
00571     static ActionCode Init(Operation* pOp, 
00572                            ActionList* pActionList, 
00573                            UINT32 Size, 
00574                            CCRuntimeClass* ActionClass, 
00575                            Action** NewAction); 
00576         
00577     // If IsDiscardableAction returns TRUE then it indicates that it can be deleted after the 
00578     // operation ends. It indicates that the action never does anything and so is dead-wood.                   
00579     virtual BOOL IsADiscardableAction() { return FALSE; }  
00580 
00581     // Find out which document/(doc)view this action is working on.
00582     Document *GetWorkingDoc()       { return pOperation->GetWorkingDoc(); }
00583     View     *GetWorkingView()      { return pOperation->GetWorkingView(); }
00584     DocView  *GetWorkingDocView()   { return pOperation->GetWorkingDocView(); }
00585   
00586     UINT32 GetSize(); 
00587     
00588     // Dumps the action list to the dubugger
00589     virtual void Dump();
00590 
00591     BOOL TransferToOtherOp(Operation* pOtherOp, ActionList* pAddActions, ActionList* pOtherActions);
00592 
00593 protected: 
00594 
00595     Operation* pOperation; // Pointer to the operation to which the action is attached. It 
00596                            // is neccessary to store this because executing an action will 
00597                            // usually cause a new action to be created, and Operation is
00598                            // required as an argument to the new action's Init method.   
00599                            
00600     ActionList* pOppositeActLst; // A pointer to the opposite action list. This is really useful 
00601                            // to know, especially when an Action is used both to Undo and Redo.  
00602                            // If the action is on the UndoActionList then pOppositeActLst 
00603                            // will point to the RedoActionList, and visa versa. 
00604 
00605     UINT32 Size;            // The total size of the action in bytes. It is neccessary to 
00606                            // store this because before the action is deleted the size of the 
00607                            // operation history needs to be reduced by the size of the action.                     
00608                      
00609 
00610     // *** This is what LastDiscardableAction USED to be - see below for it's new friendly
00611     // purpose.
00612     // When an Action fails in the Init function this can be due to either there not being 
00613     // enough system memory, or because there is not enough space in the Operation History for
00614     // the Action. In the later case an instance of the action will exist and 
00615     // LastDiscardable action will be set to point at the action. When Init is called the next 
00616     // time it will be deleted.
00617     
00618 
00619 
00620     //static Action* LastDiscardableAction;  
00621                           
00622 };    
00623 
00624 
00625 /********************************************************************************************
00626 
00627 >   ALLOC_WITH_FAIL(Ptr, AllocExpr, pOp)                                              \
00628 
00629     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00630     Created:    4/8/93
00631     Inputs:     Ptr:       The pointer or handle to the object being allocated
00632                 AllocExpr: The expression to allocate memory (e.g. new Blobby(x,y,z) )
00633                 pOp:       A pointer to the operation for which memory is being allocated.   
00634     Outputs:    -
00635     Returns:    -
00636     Purpose:    This macro should be used whenever you want to allocate any memory in an 
00637                 operation.It initially tries to allocate system memory, if it fails then it 
00638                 prompts the user to see if they want to delete undo operations to try and make
00639                 room. If after deleting undo operations memory still cannot be allocated then 
00640                 FailAndExecute() is called and a NULL Ptr is returned. 
00641     
00642                 The macro is fairly long and may be replaced by a series of functions 
00643                 one for each type of memmory allocation. 
00644     
00645     Errors:     -
00646     SeeAlso:    CALL_WITH_FAIL
00647 
00648 ********************************************************************************************/
00649 
00650 
00651 #define ALLOC_WITH_FAIL(Ptr, AllocExpr, pOp)                                              \
00652 {                                                                                         \
00653     (Ptr) = (AllocExpr);                                                                  \
00654     if ( (Ptr) == NULL && (pOp) != NULL )                                                 \
00655     {                                                                                     \
00656         OperationHistory& OpHist = pOp->GetWorkingDoc()->GetOpHistory();                  \
00657         /* If the operation is unwinding then we can't afford the luxury of asking the */ \
00658         /* user */                                                                        \
00659         if (((pOp)->GetOpFlgs().UnwindingActions) || ((pOp)->UserWantsToDeleteUndoOps())) \
00660         {                                                                                 \
00661             /* The user wants to try deleting undo records to make space for the action*/ \
00662             BOOL NoMoreUndoOpsToDelete = FALSE;                                           \
00663             /* Repeatedly delete undo operations to try and create enough room for the    \
00664              allocation. */                                                               \
00665             do                                                                            \
00666             {                                                                             \
00667                 /* Reduce the size of the operation history by deleting a single undo */  \
00668                 /* operation                                                          */  \
00669                 if  ((OpHist.ReduceSize((OpHist.GetSize()-1), TRUE)) == FALSE)            \
00670                     NoMoreUndoOpsToDelete = TRUE;                                         \
00671                                                                                           \
00672             } while ( (((Ptr) = (AllocExpr))  == NULL)                                    \
00673                     && (!NoMoreUndoOpsToDelete) );                                        \
00674                                                                                           \
00675             if (NoMoreUndoOpsToDelete)                                                    \
00676                 (pOp)->OperationMemoryFailure();                                          \
00677         }                                                                                 \
00678         else                                                                              \
00679         {                                                                                 \
00680             pOp->FailAndExecute();                                                        \
00681         }                                                                                 \
00682     }                                                                                     \
00683 } 
00684 
00685 /********************************************************************************************
00686 
00687 >   CALL_WITH_FAIL(fn, pOp, Success)                                              
00688 
00689     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00690     Created:    4/8/93
00691     Inputs:     fn:        the function to call
00692                 pOp:       A pointer to the operation for which memory is being allocated.   
00693             
00694     Outputs:    Success:   A BOOL variable which is TRUE if the function could be executed
00695                            with a TRUE return value. 
00696     Returns:    -
00697     Purpose:    This MACRO is the same as the ALLOC_WITH_FAIL except that it repeatedly 
00698                 calls a function which tries to allocate memory. The function must
00699                 return a TRUE/FALSE success status. 
00700             
00701     
00702     Errors:     -
00703     SeeAlso:    ALLOC_WITH_FAIL                                      
00704 
00705 ********************************************************************************************/
00706 
00707 
00708 #define CALL_WITH_FAIL(fn,pOp,Success)                                                        \
00709 {                                                                                             \
00710     Success = FALSE;                                                                          \
00711     if ( !(fn) )                                                                              \
00712     {                                                                                         \
00713         if ( (pOp) != NULL )                                                                  \
00714         {                                                                                     \
00715             OperationHistory& OpHist = (pOp)->GetWorkingDoc()->GetOpHistory();                \
00716             if ( ((pOp)->GetOpFlgs().UnwindingActions) || (pOp)->UserWantsToDeleteUndoOps())  \
00717             {                                                                                 \
00718                 /* The user wants to try deleting undo records to make space for the action*/ \
00719                 BOOL NoMoreUndoOpsToDelete = FALSE;                                           \
00720                 /* Repeatedly delete undo operations to try and create enough room for the    \
00721                  allocation. */                                                               \
00722                 do                                                                            \
00723                 {                                                                             \
00724                     /* Reduce the size of the operation history by deleting a single undo */  \
00725                     /* operation                                                          */  \
00726                     if  ((OpHist.ReduceSize((OpHist.GetSize()-1), TRUE)) == FALSE)            \
00727                         NoMoreUndoOpsToDelete = TRUE;                                         \
00728                                                                                               \
00729                 } while ( (!(fn))                                                             \
00730                         && (!NoMoreUndoOpsToDelete) );                                        \
00731                                                                                               \
00732                 if (NoMoreUndoOpsToDelete)                                                    \
00733                 {                                                                             \
00734                     (pOp)->OperationMemoryFailure();                                          \
00735                 }                                                                             \
00736                 else                                                                          \
00737                 {                                                                             \
00738                     Success = TRUE;                                                           \
00739                 }                                                                             \
00740             }                                                                                 \
00741             else                                                                              \
00742             {                                                                                 \
00743                 (pOp)->FailAndExecute();                                                      \
00744             }                                                                                 \
00745         }                                                                                     \
00746     }                                                                                         \
00747     else                                                                                      \
00748     {                                                                                         \
00749         Success = TRUE;                                                                       \
00750     }                                                                                         \
00751 }                                                                                             \
00752 
00753 /********************************************************************************************
00754 
00755 >   class InvalidateRegionAction: public Action
00756 
00757     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00758     Created:    13/9/93
00759     Purpose:    When executed this action will Force a redraw of the bounding rectangles of 
00760                 each node in a range. 
00761     SeeAlso:    -
00762 
00763 ********************************************************************************************/
00764 
00765 class CCAPI InvalidateRegionAction: public Action
00766 {                                
00767     CC_DECLARE_DYNCREATE( InvalidateRegionAction )
00768 
00769 public:
00770     InvalidateRegionAction(); 
00771     virtual ActionCode Execute();   
00772      
00773     static ActionCode Init(Operation* const pOp, 
00774                            ActionList* pActionList,     
00775                            Range nodeRange, // The range on nodes we want to invalidate
00776                            Spread* pSpread, 
00777                            BOOL includeBlobs, 
00778                            Action** NewAction); 
00779 protected:
00780     Range NodeRange; 
00781     BOOL IncludeBlobs:1; 
00782     Spread* pSpread;    // We need to be able to invalidate the region of a hidden node, 
00783                         // so we must store a copy of the spread. 
00784 };
00785  
00786 /********************************************************************************************
00787 
00788 >   class InvalidateRegionIfBgRedrawAction: public InvalidateRegionAction
00789 
00790     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00791     Created:    10/5/95
00792     Purpose:    When executed this action will Force a redraw of the bounding rectangles of 
00793                 each node in a range.
00794                 This version will only invalidate the region if Background Redraw is
00795                 in progress.
00796     SeeAlso:    -
00797 
00798 ********************************************************************************************/
00799 
00800 class InvalidateRegionIfBgRedrawAction: public InvalidateRegionAction
00801 {                                
00802     CC_DECLARE_DYNCREATE( InvalidateRegionIfBgRedrawAction )
00803 
00804 public:
00805     InvalidateRegionIfBgRedrawAction(); 
00806     virtual ActionCode Execute();   
00807 
00808     static ActionCode Init(Operation* const pOp, 
00809                            ActionList* pActionList,     
00810                            Range nodeRange, // The range on nodes we want to invalidate
00811                            Spread* pSpread, 
00812                            BOOL includeBlobs, 
00813                            Action** NewAction); 
00814 };
00815 
00816 /********************************************************************************************
00817 
00818 >   class HideNodeAction: public Action
00819 
00820     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00821     Created:    13/9/93
00822     Purpose:    When executed this action will hide a node. It will
00823                 also generate a ShowNodeAction action adding it to the opposite Action list. 
00824                  
00825     SeeAlso:    ShowNodeAction
00826 
00827 ********************************************************************************************/
00828 
00829 class CCAPI HideNodeAction: public Action
00830 {
00831     CC_DECLARE_DYNCREATE( HideNodeAction )
00832 
00833 public:
00834     HideNodeAction(); 
00835     virtual ActionCode Execute();    
00836     static ActionCode Init(Operation* const pOp, 
00837                            ActionList* pActionList,
00838                            Node* NodeToHide, 
00839                            BOOL IncludeSubtreeSize,     
00840                            Action** NewAction,
00841                            BOOL TellSubtree = TRUE); 
00842 
00843     CCRuntimeClass* GetClassOfAttrNodeToHide() const
00844         { return ClassOfAttributeToHide; }
00845 
00846     void RecordTag(Node* NodeToHide);
00847 
00848 private: 
00849 
00850     // When we generate a HideNodeAction for a non attribute node, we need to simply store
00851     // a pointer to the node, as we can be sure that this node will be around when we come to
00852     // execute this action.
00853 
00854     // However if we are generating a HideNodeAction for an attribute then things are different. 
00855     // During attribute optimisation attribute nodes can get deleted, so storing a pointer to 
00856     // the attribute node is a bad idea. Instead we store a pointer to the attribute's parent (which can't 
00857     // be an attribute, so can't get deleted), and the RuntimeClass of the attribute. We can then
00858     // find the attribute by searching for it.
00859 
00860     Node* node; // node which should be hidden when HideNodeAction is executed. If the node
00861                 // to be hidden is an attribute however then this node will be the attribute's
00862                 // parent (see the notes below).
00863 
00864     CCRuntimeClass* ClassOfAttributeToHide; // If the node being hidden is a NodeAttribute then
00865                                             // node will point to the attribute's parent (see above)
00866                                             // and ClassOfAttributeToHide will be the runtime class
00867                                             // of the attribute which should be hidden. When this
00868                                             // action is executed if ClassOfAttributeToHide is
00869                                             // non NULL then we know that it is an attribute that we
00870                                             // must hide, so we search for it.
00871 
00872     TAG m_nHiddenWixAttrTag;                // If the node being hidden is a Wix attribute then this
00873                                             // holds its tag so it can be properly identified by the
00874                                             // Execute() function.  Wix attributes are not optimised
00875                                             // and also unlike other attributes, more than one of the
00876                                             // same kind can apply to an object.
00877 
00878     // The size of a HideNodeAction is always sizeof(HideNodeAction), however the 
00879     // IncludeSubtreeSize flag is required to pass to the twin ShowNodeAction. 
00880 
00881     BOOL IncludeSubtreeSize:1;  
00882     BOOL TellSubtree:1; 
00883     BOOL m_bEffect:1;
00884 };                                                                                                     
00885 
00886  
00887 /********************************************************************************************
00888 
00889 >   class ShowNodeAction: public Action
00890 
00891     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00892     Created:    13/9/93
00893     Purpose:    When executed this action will show a node. It will also generate a 
00894                 HideNodeAction action adding it to the opposite Action list.
00895                 
00896     SeeAlso:    HideNodeAction
00897 
00898 ********************************************************************************************/
00899 
00900 class CCAPI ShowNodeAction: public Action
00901 {                                
00902     CC_DECLARE_DYNCREATE( ShowNodeAction )
00903 
00904 public:
00905     ShowNodeAction();             
00906     virtual ~ShowNodeAction();  
00907     virtual void Slaughter(); 
00908     virtual ActionCode Execute();    
00909     static ActionCode Init(Operation* const pOp, 
00910                            ActionList* pActionList, 
00911                            NodeHidden* HiddenToShow, 
00912                            BOOL IncludeSubtreeSize,     
00913                            Action** NewAction, 
00914                            BOOL TellSubtree = TRUE); 
00915 private: 
00916     NodeHidden* node; 
00917 
00918     // We need to store an IncludeSubtreeSize flag because when we create the twin
00919     // HideNodeAction it is required as a parameter. 
00920     BOOL IncludeSubtreeSize:1; 
00921     BOOL TellSubtree:1; 
00922 };  
00923 
00924 
00925 
00926 
00927 /********************************************************************************************
00928 
00929 >   class UnApplyAction: public Action
00930 
00931     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00932     Created:    26/07/2005
00933     Purpose:    When executed this action will hide a node. It will
00934                 also generate a ShowNodeAction action adding it to the opposite Action list. 
00935                  
00936     SeeAlso:    ShowNodeAction
00937 
00938 ********************************************************************************************/
00939 
00940 class CCAPI UnApplyAction: public Action
00941 {
00942     CC_DECLARE_DYNCREATE( UnApplyAction )
00943 
00944     friend class OpApplyAttrInteractive;
00945 
00946 public:
00947     UnApplyAction();
00948     ~UnApplyAction();
00949     virtual ActionCode Execute();
00950     static ActionCode Init(Operation* const pOp, 
00951                            ActionList* pActionList,
00952                            Node* pActionNode,
00953                            NodeAttribute* pActionAttribute,
00954                            BOOL IncludeSubtreeSize,
00955                            Action** NewAction,
00956                            BOOL TellSubtree = TRUE); 
00957 
00958 //  CCRuntimeClass* GetClassOfAttrNodeToHide() const
00959 //      { return ClassOfAttributeToHide; }
00960 
00961     void RecordTag(NodeAttribute* pAttr);
00962 
00963 private: 
00964     Node* m_pApplyNode;
00965     NodeAttribute* m_pAttribute;
00966     TAG m_nAttrTag;                         // If the node being hidden is a Wix attribute then this
00967                                             // holds its tag so it can be properly identified by the
00968                                             // Execute() function.  Wix attributes are not optimised
00969                                             // and also unlike other attributes, more than one of the
00970                                             // same kind can apply to an object.
00971 
00972     // The size of a HideNodeAction is always sizeof(HideNodeAction), however the 
00973     // IncludeSubtreeSize flag is required to pass to the twin ShowNodeAction. 
00974 
00975     BOOL IncludeSubtreeSize:1;  
00976     BOOL TellSubtree:1; 
00977 };                                                                                                     
00978 
00979  
00980 
00981 
00982 /********************************************************************************************
00983 
00984 >   class ApplyAction: public Action
00985 
00986     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00987     Created:    26/07/2005
00988     Purpose:    When executed this action will show a node. It will also generate a 
00989                 HideNodeAction action adding it to the opposite Action list.
00990                 
00991     SeeAlso:    HideNodeAction
00992 
00993 ********************************************************************************************/
00994 
00995 class CCAPI ApplyAction: public Action
00996 {                                
00997     CC_DECLARE_DYNCREATE( ApplyAction )
00998 
00999     friend class OpApplyAttrInteractive;
01000 
01001 public:
01002     ApplyAction();             
01003     virtual ~ApplyAction();  
01004     virtual ActionCode Execute();    
01005     static ActionCode Init(Operation* const pOp, 
01006                            ActionList* pActionList, 
01007                            Node* pActionApplyNode,
01008                            NodeAttribute* pActionAttribute,
01009                            BOOL IncludeSubtreeSize,     
01010                            Action** NewAction, 
01011                            BOOL TellSubtree = TRUE); 
01012 private: 
01013     Node* m_pApplyNode;
01014     NodeAttribute* m_pAttribute;
01015 
01016     // We need to store an IncludeSubtreeSize flag because when we create the twin
01017     // HideNodeAction it is required as a parameter. 
01018     BOOL IncludeSubtreeSize:1; 
01019     BOOL TellSubtree:1; 
01020 };  
01021 
01022 
01023 
01024 
01025 /********************************************************************************************
01026 
01027 >   class RestoreSelectionsAction: public Action
01028 
01029     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
01030     Created:    13/9/93
01031     Purpose:    When executed this action will restore the selection state of the document. 
01032                 It will also spawn another identical RestoreSelectionsAction adding and add it to 
01033                 the opposite action list. 
01034             
01035     SeeAlso:    -
01036 
01037 ********************************************************************************************/
01038 
01039 class CCAPI RestoreSelectionsAction: public Action
01040 {                                
01041     CC_DECLARE_DYNCREATE( RestoreSelectionsAction )
01042 
01043 public:
01044     RestoreSelectionsAction(); 
01045     ~RestoreSelectionsAction();  
01046     void Slaughter();
01047     virtual ActionCode Execute();    
01048     static ActionCode Init(Operation* const pOp, 
01049                            ActionList* pActionList,     
01050                            SelectionState* SelState, 
01051                            BOOL Toggle, 
01052                            BOOL ToggleStatus, 
01053                            BOOL SelStateShared,  
01054                            BOOL RenderStartBlobs, 
01055                            BOOL RenderEndBlobs,
01056                            BOOL StartRestore,   
01057                            Action** NewAction);
01058 
01059     SelectionState* GetSelState() { return SelState; };      
01060                           
01061 private:
01062     SelectionState* SelState; //  Selection state which will be restored when the action is 
01063                               //  executed.
01064 
01065     // If toggle is true then the ToggleStatus determines if the selections are restored 
01066     // or not. See Init method if you are confused. 
01067     BOOL toggle:1; 
01068     BOOL toggleStatus:1; 
01069     BOOL SelStateShared:1; // If the SelState is shared by a pair of RestoreSelActions 
01070                          // then the SelState will only be deleted when ToggleStatus = TRUE 
01071     
01072     BOOL RenderStartBlobs:1; 
01073     BOOL RenderEndBlobs:1;
01074 
01075     BOOL StartRestore:1;   // Is this the first restore executed when the operation is undone/redone
01076 };   
01077 
01078 
01079 /********************************************************************************************
01080 
01081 >   class SelectDeselectAction: public Action
01082 
01083     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
01084     Created:    13/9/93
01085     Purpose:    When executed this action will render node's selection blobs (which could remove them)
01086                 and set it's selection state. If the node is currently selected then the 
01087                 node is deselected. If the node is currently deselected it is selected.
01088                 It creates a second SelectDeselectAction for the node and adds it to the 
01089                 opposite action list. 
01090             
01091     SeeAlso:    -
01092 
01093 ********************************************************************************************/
01094 
01095 class CCAPI SelectDeselectAction: public Action
01096 {                                
01097     CC_DECLARE_DYNCREATE( SelectDeselectAction )
01098 
01099 public:
01100     SelectDeselectAction(); 
01101     ~SelectDeselectAction();
01102     virtual ActionCode Execute();    
01103     static ActionCode Init(Operation* const pOp, 
01104                            ActionList* pActionList,     
01105                            Node* SelDeNode,
01106                            Spread* pSpread,
01107                            Action** NewAction); 
01108         
01109     Node* node; // The node which will be selected/deselected 
01110     Spread *Parent;
01111 };   
01112 
01113  
01114 /********************************************************************************************
01115 
01116 >   class TransformNodeAction: public Action
01117 
01118     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
01119     Created:    13/9/93
01120     Purpose:    When executed this action will transform a range of NodeRenderableInk nodes. 
01121                 It also creates another TransformNodeAction to 'undo' the transformation just 
01122                 performed. It adds this action to the opposite action list.   
01123     
01124     SeeAlso:    -
01125 
01126 ********************************************************************************************/
01127 
01128 
01129 class CCAPI TransformNodeAction: public Action
01130 {                                
01131     CC_DECLARE_DYNCREATE( TransformNodeAction )
01132 
01133 public:
01134     TransformNodeAction(); 
01135     ~TransformNodeAction();
01136     void Slaughter();  
01137 
01138     virtual ActionCode Execute();  
01139     static ActionCode Init(Operation* const pOp, 
01140                            ActionList* pActionList, 
01141                            Range NodeRangeIn, 
01142                            TransformBase* Trans,
01143                            List * pNodeList,
01144                            Action** NewAction); 
01145 
01146     // For op merging
01147     void CombineWith(TransformNodeAction* pMatrixTransformAction);
01148     TransformBase* GetTransform(); 
01149     const Range* GetActionRange() const {return &NodeRange;}
01150 
01151 private:
01152         
01153     Range NodeRange;
01154     
01155     // the list of parent-promoted nodes in the first range
01156     List * m_pNodeList;
01157     
01158     TransformBase* pTrans; // The transform to apply to every node in the range 
01159 };   
01160        
01161 #endif
01162 
01163 

Generated on Sat Nov 10 03:46:18 2007 for Camelot by  doxygen 1.4.4