TransOperation Class Reference

The base class for all the Transform Operations. This class should provide most of the functionality for all the transform operations such as handling the eored drag events etc. At the end of the day it will transform the selection is some way (depending on the derived class). More...

#include <transop.h>

Inheritance diagram for TransOperation:

UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject OpAlign OpFlipTrans OpMovePathPoint OpPageResize OpPathNudge OpRotateTrans OpScaleTrans OpShearTrans OpSliceTranslate OpSquashTrans OpTranslateTrans List of all members.

Public Member Functions

 TransOperation ()
virtual ~TransOperation ()
 TransOperation destructor.
BOOL DoStartTransOp (BOOL RecordSelTwice, Node *NodeToTransform=NULL, Range *RangeToTransform=NULL)
 This function must be called by all TransOperations. It does the following: Records the current selection status Invalidates the rectangle covered by the selection and its blobs.
virtual void End ()
 Calls DoEndTransOp(), then Operation::End().
virtual Matrix GetCurrentMatrix ()
RangeGetTransformRange ()
virtual void DoWithParam (OpDescriptor *, OpParam *pOpParam)
 Does an immediate version of the transform. This attempts to transform the selection and build all the neccesary Undo information. Derived class only need overide InitTransformImmediate() to set up the specifics of there own transform unless they need to do something not covered by this base class version.
virtual void DragStarted (TransformData *, DragTool *, TransformBoundingData *, DocCoord, Spread *, ClickModifiers, DocCoord ClickOffset=DocCoord(0, 0), Node *NodeToTrans=NULL, DragType dragtype=DRAGTYPE_AUTOSCROLL, BOOL bSolidDrag=FALSE)
 Starts an interactive drag version of the transformation operation.Changes made: pTool is now of type DragTool*, instead of SelectorTool*.
virtual BOOL ShouldPointerBeOffset ()
 Allows the transforms to decide if they want the mouse position to be moved for them to the edge of the selection.
virtual void DragPointerMove (DocCoord, ClickModifiers, Spread *, BOOL bSolidDrag)
 Handles the event of the mouse moving during a drag. This function will try to undraw all the eored data from the screen and start drawing it in again in a new location.
virtual void DragPointerIdle (DocCoord, ClickModifiers, Spread *, BOOL bSolidDrag)
 This function is called during the drag when the mouse is not moving. It makes use of this idle time to draw a few more shapes from the selection to the screen. Thus, if you are tranforming a selection of objects you will see more detail when the mouse stops moving.
virtual void DragFinished (DocCoord, ClickModifiers, Spread *, BOOL, BOOL bSolidDrag)
 Marks the end of the drag. It is at this point that all the transformations should be applied to the selection if everything worked.
virtual BOOL DragKeyPress (KeyPress *pKeyPress, BOOL bSolidDrag)
 Find out if any of the key modifiers are being pressed when the mouse is not moving.
virtual void DragModeChanged (BOOL bSolidDrag)
 Find out if any of the key modifiers are being pressed when the mouse is not moving.
virtual void OnClickWhileDragging (OilCoord PointerPos, ClickType Click, ClickModifiers Mods, BOOL bSolidDrag)
 This virtual function handles clicks with one mouse button while another mouse button is dragging. For example, the user drags with the left mouse button and clicks the right button during the drag.
BOOL DragCopyAction (BOOL bSolidDrag)
BOOL DropCopy (BOOL bSolidDrag)
BOOL SetLeaveCopy ()
virtual void RenderDragBlobs (DocRect ClipRect, Spread *ParentSpread, BOOL bSolidDrag)
 Draws the EORed stuff ("blobs") to the screen during a drag.
BOOL CompleteTransformation ()
 Builds the actual Undo information etc for the transformation as well as actually performing the transformation itself. This should be called by both DragFinished() and DoWithParams().
void ComputeNewBounds ()
 Applies the current transformation matrix to the original bounding box data to compute the new bounds of the objects. It also notes that the bounds may be severely distorted by the transform and so it sorts and recombines the output coordinates to construct a new bounding rectangle.
void SelectNodeAfterDrag (Node *NodeToSelect)
void ClearNodesToSelect ()
virtual BOOL MayChangeNodeBounds () const

Static Public Member Functions

static BOOL DeclarePrefs ()
 Declares any preferences that the class needs to declare.
static BOOL Declare ()
static OpState GetState (String_256 *Description, OpDescriptor *)

Public Attributes

List lstNodesToSelect

Protected Member Functions

DocCoord GetStartPos ()
 Get the raw start position or the magnetically snapped one depending on the state of the magnetic switch in the drag view. This function must be called instead of accessing StartPos directly in any place where the magnetically snapped start position is going to be used. It does not need to be used when magnetic snapping is not an issue. Then, StartPos can simply be read directly.

Protected Attributes

DragToolpSelTool
TransformBoundingData BoundingData
Coord OriginalBounds [4]
DocCoord StartPos
DocCoord MagStartPos
DocCoord RawStartPos
DocCoord RawPos
DocCoord LastRawPos
DocCoord CentreOfTrans
SpreadStartSpread
SpreadCurrentSpread
DocCoord Offset
BOOL MagneticGripPoint
DocCoord BoundingCentre
DocCoord OriginalCentre
Matrix Transform
Matrix OriginalTransform
BOOL RecordTwice
NodeObjectUnderCursor
Rangem_pTransformRange
SelectionStateSelState
BOOL LockAspect
BOOL LeaveCopy
BOOL ScaleLines
BOOL TransFills
BOOL MouseHasMoved
BOOL CanScaleLines
BOOL AbortTransAtEnd
UINT32 StatusHelpID
UINT32 StatusHelpID2
Listm_pSelList
Rangem_pDraggedRange
Spreadm_pDragSpread
BOOL m_bFirstRedraw
BOOL m_bShowDraggedOutlines
MonotonicTime m_timeIdle
BOOL m_bShowOriginalOutlines
BOOL m_bRangeCacheTransformed
BOOL m_bRangeFullyTransformed
Trans2DMatrix m_PrevTransform
DocRect m_AccuracyTestRect

Static Protected Attributes

static INT32 ClickWhileDragFunc

Private Member Functions

virtual void InitTransformImmediate (OpParam *)
 Allows a transformation to set itself up ready for an immediate transform. If your class wants to support immediate transforms it should overide this function or the DoWithParam function. This base class version of the function does nothing.
virtual void InitTransformOnDrag (DocCoord, ClickModifiers)
 Sets up the parameters needed to build the transform matrix at the start of the drag. This base class version of this function does nothing.
virtual void UpdateTransformOnDrag (DocCoord, Spread *, ClickModifiers &)
 This function re-calculates the parameters specific to the transform based on the mouse position. This is only used in interactive drag style transforms.
virtual void ConstrainDrag (DocCoord *)
 Gives the operation the chance to constrain the mouses movement if it is relavent. If it is not, then do not overide this function.
virtual void SetStartBlob (INT32 StartBlob)
 Allows the operations to know how it was started. Some operation do different things depending on if they are going vertically or horizontally and this will allow you to figure that out. Overide this function if you need to deal with this situation (ie the Shear operation). The base class version does nothing. This function is called from the DragStarted() function.
virtual void UpdateTransformBoundingData ()
 Should update the information in the TransformBoundingData object of the class and tell the Selector tool using the DragMove function. This is the base class version of the function that just tells the tool but does not change any of the data. This function is called at the end of the DragPointerMove function. It is possible for your transform to simple change the data in the BoundingData var as it goes and leave this base class version of the function to tell the tool about the changes.
virtual void DragInputChanged (DocCoord, ClickModifiers, Spread *)
 Deals with any input changing during a transform drag. This mostly means the mouse position changing but it is also called when the click modifiers change or potentially any other input.
virtual void DragSolidChanged (DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL bForceRecopy=FALSE)
 Deals with any input changing during a solid transform drag. This mostly means the mouse position changing but it is also called when the click modifiers change or potentially any other input.
virtual BOOL CanChangeSpread ()
 Tell the baseclass functions whether to draw drag feedback only on the start spread or to allow drag rendering to be done on other spreads too.
virtual void BuildMatrix ()
 This function should build the approprate transform matrix based on all the params that are available. This base class version of the function does not build a matrix and should not be called, as a derived class version of it should exist.
BOOL LeaveCopyOfSelection ()
 If the flag LeaveCopy is set (ie we have been instructed to leave a copy of the selection in its original location) then this function is called. It makes a copy of the current selection and places them in the tree.
BOOL DoEndTransOp ()
 This function gets called automatically by End() It Invalidates the rectangle covered by the selection and its blobs Scope: protected.
BOOL DoSmartInvalidate ()
 Invalidate the transform range of nodes but be careful about releasing cache info so that translations can retain cached info if possible.
virtual BOOL GetStatusLineText (String_256 *, Spread *, DocCoord, ClickModifiers)
 get status line hlep for drag op
void FigureStatusText (String_256 *)
 Compute help text for this transform.
BOOL SolidDragTransform (BOOL bForceRecopy=FALSE, BOOL bForceRedraw=TRUE)
 Transform the selection into the drag range.
BOOL SetTransformRange (Range *pTransformRange, Node *pTransformNode)
 Sets the m_pTransformRange member to be a local range created either as a copy of the supplied range or a range created to represent the node or a copy of the selection range.
BOOL TransformOverlapsOriginal ()
 Check whether transform objects overlap originals.

Detailed Description

The base class for all the Transform Operations. This class should provide most of the functionality for all the transform operations such as handling the eored drag events etc. At the end of the day it will transform the selection is some way (depending on the derived class).

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> / Rik
Date:
15/2/94

Definition at line 226 of file transop.h.


Constructor & Destructor Documentation

TransOperation::TransOperation  ) 
 

TransOperation::~TransOperation  )  [virtual]
 

TransOperation destructor.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/2/94

Definition at line 228 of file transop.cpp.

00229 {
00230     if (m_pSelList)
00231     {
00232         m_pSelList->DeleteAll();
00233         delete m_pSelList;
00234         m_pSelList = NULL;
00235     }
00236 
00237     if (m_pDraggedRange)
00238     {
00239         delete m_pDraggedRange;
00240         m_pDraggedRange = NULL;
00241     }
00242 
00243     if (m_pTransformRange)
00244     {
00245         delete m_pTransformRange;
00246         m_pTransformRange = NULL;
00247     }
00248 
00249 }


Member Function Documentation

void TransOperation::BuildMatrix  )  [private, virtual]
 

This function should build the approprate transform matrix based on all the params that are available. This base class version of the function does not build a matrix and should not be called, as a derived class version of it should exist.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/7/94

Reimplemented in OpFlipTrans, OpRotateTrans, OpScaleTrans, OpShearTrans, OpSquashTrans, OpSliceTranslate, and OpTranslateTrans.

Definition at line 1777 of file transop.cpp.

01778 {
01779     ENSURE(FALSE, "Base class version of BuildMatrix() called. A derived class version must exist");
01780     
01781     // Sets the transform matrix to be the identity matrix in case of an emergency.
01782     Transform = Matrix();
01783 }

BOOL TransOperation::CanChangeSpread  )  [private, virtual]
 

Tell the baseclass functions whether to draw drag feedback only on the start spread or to allow drag rendering to be done on other spreads too.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/June/2006
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if this transform allows the drag to be transferred to another spread

Reimplemented in OpSliceTranslate, and OpTranslateTrans.

Definition at line 1757 of file transop.cpp.

01758 {
01759     // Overide this function if you allow your transform to cross spread boundaries
01760     return FALSE;
01761 }

void TransOperation::ClearNodesToSelect  ) 
 

>>> void ClearNodesToSelect ()

Author:
Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/6/96 Purpose Empties the node list and deletes all the items in it.

Definition at line 2537 of file transop.cpp.

02538 {
02539     lstNodesToSelect.DeleteAll();
02540 }

BOOL TransOperation::CompleteTransformation  ) 
 

Builds the actual Undo information etc for the transformation as well as actually performing the transformation itself. This should be called by both DragFinished() and DoWithParams().

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/7/94
Returns:
TRUE if it worked

Definition at line 1930 of file transop.cpp.

01931 {
01932     // Build the appropriate transform object to transform the selection
01933     Trans2DMatrix* Trans; 
01934     ALLOC_WITH_FAIL(Trans, new Trans2DMatrix(Transform), this);  
01935 
01936     // See if the memory allocation worked
01937     if (Trans == NULL)
01938         return FALSE;
01939 
01940     // Ideally we should put the hourglass on here, it will be turned off in the End method
01941     BeginSlowJob();
01942 
01943     // Set the flags in the transform according to the flags set here
01944     Trans->TransFills = TransFills;
01945     Trans->TransLines = ScaleLines && CanScaleLines;
01946     Trans->bHaveTransformedAllCached = TRUE;            // having transformed none we can say all caches have been transformed
01947     Trans->bHaveTransformedAllChildren = TRUE;          // having transformed none we can say all children have been transformed
01948     Trans->bTransformYourChildren = TRUE;               // The transform does not have to transform all its data
01949     m_bRangeCacheTransformed = TRUE;
01950     m_bRangeFullyTransformed = TRUE;
01951 
01952     // if we need to leave a copy of the selection behind, then do it
01953     // We HAVE to do this before we call DoStartTransOp() as it builds a
01954     // run length coding of the selection, which is messed up if we insert
01955     // extra nodes into the tree. 
01956     //
01957     // Markn 31/5/95: Only allow LeaveCopy if select-inside is NOT present
01958     // JustinF: 6/10/96 only do this if transforming the selection, not TransformRange!
01959     if (m_pTransformRange && LeaveCopy && !m_pTransformRange->ContainsSelectInside())
01960     {
01961         if (!LeaveCopyOfSelection())
01962             return FALSE;
01963     }
01964 
01965     // Start the selection operation which records the current selection status and 
01966     // invalidates the rectangle covered by the selection and its blobs. 
01967     BOOL RecordSelectionTwice = (CanChangeSpread()) && (StartSpread!=CurrentSpread);
01968 
01969     // If the Selection only contains a single object then we pass this object as
01970     // a parameter to DoStartTransOp. Otherwise the routine assumes that the 
01971     // entire selection will be transformed.
01972     // JustinF: 7/10/96 only do this if transforming the selection, not TransformRange!
01973     if (SelState==NULL)
01974     {
01975         if (!DoStartTransOp(RecordSelectionTwice, NULL, m_pTransformRange))
01976             return FALSE; 
01977     }
01978 
01979     // Scan the selection, and transform each selected object.
01980     // Karim 29/06/2000 - modified so that the range's PromoteToParent flag is not ruined.
01981     BOOL TransOK = DoTransformNodes(*m_pTransformRange, Trans);
01982     if (!TransOK)
01983         return FALSE;
01984 
01985     // Move the selection to a new spread if it should be
01986     if (RecordSelectionTwice)
01987     {
01988         // Move the selection to a new spread here
01989         if (!DoMoveNodes(*m_pTransformRange, CurrentSpread->FindActiveLayer(), LASTCHILD))
01990             return FALSE;
01991 
01992         Document::GetSelected()->ResetInsertionPosition();
01993     }
01994     
01995     // Change the bounds then ripple them up the tree
01996     //SCANRANGEFORCLASS(Selection, UpdateInkBoundingRect(), NodeRenderableInk);
01997     //Selection->UpdateParentBoundsOfSelection(); 
01998 
01999     m_bRangeCacheTransformed = Trans->bHaveTransformedAllCached;
02000     m_bRangeFullyTransformed = Trans->bHaveTransformedAllChildren;
02001 
02002     // It all worked, so say so.
02003     return TRUE;
02004 }

void TransOperation::ComputeNewBounds  ) 
 

Applies the current transformation matrix to the original bounding box data to compute the new bounds of the objects. It also notes that the bounds may be severely distorted by the transform and so it sorts and recombines the output coordinates to construct a new bounding rectangle.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/9/94

Definition at line 1874 of file transop.cpp.

01875 {
01876     // Transform original bounding coordinates
01877     Coord NewBounds[4];
01878     Transform.transform(NewBounds,OriginalBounds,4);
01879 
01880     // Now recombine the output coords to see where the new bottom-left and top-right coords
01881     // really are...
01882     INT32 lox = NewBounds[0].x;
01883     INT32 loy = NewBounds[0].y;
01884     INT32 hix = NewBounds[0].x;
01885     INT32 hiy = NewBounds[0].y;
01886     UINT32 i;
01887     for(i=1;i!=4;i++)
01888     {
01889         if (NewBounds[i].x < lox) lox=NewBounds[i].x;
01890         if (NewBounds[i].y < loy) loy=NewBounds[i].y;
01891         if (NewBounds[i].x > hix) hix=NewBounds[i].x;
01892         if (NewBounds[i].y > hiy) hiy=NewBounds[i].y;
01893     }
01894 
01895     // Now update the bounds structure...
01896     if (lox!=BoundingData.x || loy!=BoundingData.y)
01897     {
01898         // One or both of x or y have changed so update them and set the changed flag
01899         BoundingData.x=lox;
01900         BoundingData.y=loy;
01901         BoundingData.XYChanged = TRUE;
01902     }
01903 
01904     // Compute width and height
01905     hix = hix-lox;
01906     hiy = hiy-loy;
01907     if (hix!=BoundingData.Width || hiy!=BoundingData.Height)
01908     {
01909         // One or both of w or h have changed so update them and set the changed flag
01910         BoundingData.Width=hix;
01911         BoundingData.Height=hiy;
01912         BoundingData.WHChanged = TRUE;
01913     }
01914 
01915 }

void TransOperation::ConstrainDrag DocCoord PointerPos  )  [private, virtual]
 

Gives the operation the chance to constrain the mouses movement if it is relavent. If it is not, then do not overide this function.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/7/94
Parameters:
PointerPos - The position of the mouse right about now [INPUTS]

Reimplemented in OpRotateTrans, OpScaleTrans, OpShearTrans, OpSliceTranslate, and OpTranslateTrans.

Definition at line 1798 of file transop.cpp.

01799 {
01800     // By default there is no constrain action
01801     // Write you own version of this function if you want your transformation to be constrained
01802 }

BOOL TransOperation::Declare  )  [static]
 

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/7/94
Returns:
TRUE if it worked, FALSE otherwise

Reimplemented in OpFlipTrans, OpRotateTrans, OpScaleTrans, OpShearTrans, OpSquashTrans, OpSliceTranslate, and OpTranslateTrans.

Definition at line 1634 of file transop.cpp.

01635 {
01636     return TRUE;
01637 }

BOOL TransOperation::DeclarePrefs  )  [static]
 

Declares any preferences that the class needs to declare.

Author:
Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/6/96
Returns:
TRUE if it worked, FALSE if it failed

Definition at line 1650 of file transop.cpp.

01651 {
01652     GetApplication()->DeclarePref( _T("Mouse"), _T("ClickWhileDragFunc"), &ClickWhileDragFunc, 0, 3 );
01653 
01654     return TRUE;
01655 }

BOOL TransOperation::DoEndTransOp  )  [private]
 

This function gets called automatically by End() It Invalidates the rectangle covered by the selection and its blobs Scope: protected.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/2/94

Definition at line 366 of file transop.cpp.

00367 {
00368     // If this is a translation and the nodes all managed to transform their cached
00369     // info successfully then we should avoid forcing them to recache now.
00370     // So we must do some cleverer recaching
00371     BOOL bOK = DoSmartInvalidate();
00372     if (!bOK) return FALSE;
00373 
00374     // If we want to record the selection again, then build a new Selection State object
00375     // and record the selection into it.
00376     if (RecordTwice)
00377     {
00378         // Create a SelectionState object
00379         ALLOC_WITH_FAIL(SelState, (new SelectionState()), this); 
00380         if (SelState == NULL)
00381         {
00382             return FALSE; // Failure 
00383         }
00384 
00385         // We have managed to create a SelectionState instance, now lets try and 
00386         // record the current selections 
00387 
00388         BOOL Success; 
00389     
00390         CALL_WITH_FAIL(SelState->Record(), this, Success)
00391 
00392         if (!Success)  // We failed to allocate enough memory to store the selection state
00393         {
00394             // There was insufficient memory to record the selections 
00395             delete SelState;            // Delete the selection state 
00396             SelState = NULL; 
00397             return FALSE; 
00398         }
00399     
00400         // We have successfully managed to create a Selection state, create an action 
00401         // to restore the selections when executed 
00402     }
00403 
00404     // Recorded the current selection state ok
00405     RestoreSelectionsAction* RestoreAct;  
00406     ActionCode ActCode;
00407 
00408     // The SelState should have been created in the DoStartSelectionOp method. 
00409     // maybe it was never called !!!
00410     ERROR2IF(SelState==NULL, FALSE, "We don't have a selection state");
00411 
00412     // Attempt to initialise the action    
00413     ActCode = RestoreSelectionsAction::Init(this,                    
00414                                             &UndoActions,  
00415                                             SelState, 
00416                                             !RecordTwice,   // Toggle
00417                                             TRUE,           // This action does not restore the sels
00418                                                             // restore the selection state but
00419                                                             // its twin will
00420                                             !RecordTwice,   // The SelState is shared
00421                                             FALSE,          // Don't draw the selection blobs
00422                                             FALSE,
00423                                             TRUE,           // End restore                  
00424                                             ( Action**)(&RestoreAct)); 
00425 
00426     // See if it all worked
00427     if (ActCode == AC_FAIL)
00428     {
00429         // We won't be needing this 
00430         delete SelState;
00431         return FALSE;  
00432     }
00433 
00434     // Inform all changed nodes that we have finished
00435     ObjChangeFlags cFlags;
00436     ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this);
00437     ObjChange.SetRetainCachedData(Transform.IsTranslation() && m_bRangeCacheTransformed);   // Same condition in DoSmartInvalidate
00438     BOOL ok = UpdateChangedNodes(&ObjChange);
00439 
00440     // BODGE TEXT - quick (harmless?) fix for bug 'transforming 2 selected text stories => sel blobs incorrect'
00441     // it is actually due to the fact that update change nodes is not called before the sel bounds are recached
00442     SelRange* pSelRange = Camelot.FindSelection();
00443     if (pSelRange != NULL)
00444     {
00445         BOOL bOldValue = pSelRange->SetPromoteToParent(TRUE);
00446 
00447         pSelRange->UpdateBounds();
00448 
00449         // Try to make sure that the spread's pasteboard is big enough to include the transformed 
00450         // objects. This is very quick if the pasteboard is big enough already.
00451         Node *Bob = pSelRange->FindFirst();
00452         if (Bob != NULL)
00453         {
00454             Spread *pSpread = Bob->FindParentSpread();
00455             
00456             DocRect IncludeRect = pSelRange->GetBoundingRect();
00457             pSpread->ExpandPasteboardToInclude(IncludeRect);
00458         }
00459 
00460         pSelRange->SetPromoteToParent(bOldValue);
00461     }
00462 
00463     return ok;
00464 }

BOOL TransOperation::DoSmartInvalidate  )  [private]
 

Invalidate the transform range of nodes but be careful about releasing cache info so that translations can retain cached info if possible.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/12/2004

Definition at line 482 of file transop.cpp.

00483 {
00484     // Issue undoable redraws...
00485     if (m_pTransformRange && !DoInvalidateNodesRegions(*m_pTransformRange, TRUE, FALSE, FALSE, FALSE))
00486         return FALSE;
00487 
00488     // Conditionally update cached info
00489     Node* pNode = m_pTransformRange->FindFirst();
00490     while (pNode)
00491     {
00492         if (pNode->IsBounded())
00493         {
00494             NodeRenderableBounded* pBoundNode = (NodeRenderableBounded*)pNode;
00495 
00496             // If we have transformed all cached data successfully
00497             // And 
00498             //      We are translating (in which case the cached data will remain usable)
00499             //      Or
00500             //      The node was Direct (in which case the cached data comes from outside the tree where it can't have been affected by the transform)
00501             // Then
00502             //      Don't force the recacheing of the data for this node, just its parents
00503             if (m_bRangeCacheTransformed && (Transform.IsTranslation() || pBoundNode->HasCachedDirectBitmap()))
00504                 pBoundNode->ReleaseCached(TRUE, FALSE, FALSE, TRUE);    // Parents and derived data only
00505             else
00506                 pBoundNode->ReleaseCached(TRUE, TRUE, TRUE, TRUE);      // Parents, children, self and derived data
00507         }
00508 
00509         pNode = m_pTransformRange->FindNext(pNode);
00510     }
00511 
00512     return TRUE;
00513 }

BOOL TransOperation::DoStartTransOp BOOL  RecordSelTwice,
Node NodeToTransform = NULL,
Range RangeToTransform = NULL
 

This function must be called by all TransOperations. It does the following: Records the current selection status Invalidates the rectangle covered by the selection and its blobs.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/2/94
Parameters:
RecordSelTwice - TRUE if the selection should be recorded twice (once at [INPUTS] the start of the operation and once at the end). If it is FALSE the selection is only recorded at the start of the operation. This should only be set to TRUE if the selection is different at the end of the operation (This is quite rare)
NodeToTransform: Specifies the object that will be transformed. The default NULL value specifies that the entire selection will be transformed.

RangeToTransform: Specifies the range of objects to use. The default NULL value specifies that the entire selection is the range. At present only used when NodeToTransform is NULL. Used by page resizing to move all the objects on the page regardless of selection. Hence, it does not call the AllowOp if the range is selected as AllowOp errors if no selection on things like NodeBlend and NodeText.

Returns:
TRUE if successful, FALSE if memory ran out (call End)
See also:
TransOperation::End()

Definition at line 282 of file transop.cpp.

00284 {
00285     // Create a SelectionState object
00286     ALLOC_WITH_FAIL(SelState, (new SelectionState()), this); 
00287     if (SelState == NULL)
00288     {
00289         return FALSE; // Failure 
00290     }
00291 
00292     // We have managed to create a SelectionState instance, now lets try and 
00293     // record the current selections 
00294 
00295     BOOL Success;
00296     
00297     CALL_WITH_FAIL(SelState->Record(), this, Success)
00298 
00299     if (!Success)  // We failed to allocate enough memory to store the selection state
00300     {
00301         // There was insufficient memory to record the selections 
00302         delete SelState;            // Delete the selection state 
00303         SelState = NULL; 
00304         return FALSE; 
00305     }
00306     
00307     // We have successfully managed to create a Selection state, create an action 
00308     // to restore the selections when executed 
00309 
00310     // Recorded the current selection state ok
00311     RestoreSelectionsAction* RestoreAct;  
00312     ActionCode ActCode;
00313     RecordTwice = RecordSelTwice;
00314 
00315     // Attempt to initialise the action    
00316     ActCode = RestoreSelectionsAction::Init(this,                    
00317                                             &UndoActions,  
00318                                             SelState, 
00319                                             !RecordTwice,   // # Toggle
00320                                             FALSE,          // This action does not restore the sels
00321                                                             // restore the selection state but
00322                                                             // its twin will
00323                                             !RecordTwice,   // The SelState is shared
00324                                             FALSE,          // Don't draw the selection blobs
00325                                             FALSE,
00326                                             FALSE,          // End restore                  
00327                                             ( Action**)(&RestoreAct)); 
00328 
00329     if (ActCode == AC_FAIL)
00330     {
00331         delete SelState; // We won't be needing this 
00332         return FALSE;  
00333     }
00334 
00335     // Create our local transform range
00336     SetTransformRange(RangeToTransform, NodeToTransform);
00337 
00338     // Ask the range whether it's OK to do the transform...
00339     // Get an ObjChangeParam ready, so we can ask op permission from nodes.
00340     ObjChangeFlags cFlags(FALSE,FALSE,FALSE,FALSE,FALSE,TRUE);  // flag this is a transform
00341     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00342     BOOL bOK = m_pTransformRange->AllowOp(&ObjChange);
00343     if (!bOK)
00344         return FALSE;
00345 
00346     // Invalidate the regions covered by all the selected objects and their blobs 
00347 //  return (DoInvalidateNodesRegions(*m_pTransformRange, TRUE)); 
00348     bOK = DoSmartInvalidate();
00349     return bOK;
00350 }

void TransOperation::DoWithParam OpDescriptor ,
OpParam pOpParam
[virtual]
 

Does an immediate version of the transform. This attempts to transform the selection and build all the neccesary Undo information. Derived class only need overide InitTransformImmediate() to set up the specifics of there own transform unless they need to do something not covered by this base class version.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/7/94
Parameters:
pDescriptor - The operations descriptor [INPUTS] pOpParam - The parameters for this operation

Reimplemented from Operation.

Reimplemented in OpAlign, OpPageResize, and OpMovePathPoint.

Definition at line 562 of file transop.cpp.

00563 {
00564     // Get at my data
00565     TransformData* TransData = (TransformData *)(void *)(pOpParam->Param1);
00566 
00567     // copy across all the relavent bits of data for the transform
00568     CentreOfTrans   = TransData->CentreOfTrans;
00569     LockAspect      = TransData->LockAspect;
00570     LeaveCopy       = TransData->LeaveCopy;
00571     ScaleLines      = TransData->ScaleLines;
00572     TransFills      = TransData->TransFills;
00573 
00574     SetTransformRange(TransData->pRange, NULL);
00575 
00576     // Set spread pointers now to keep CompleteTransformation happy even
00577     // though we don't expect them to be used or changed in Immediate transforms
00578     StartSpread = NULL;
00579     CurrentSpread = StartSpread;
00580 
00581     // Where was this operation started from, and are we interested
00582     SetStartBlob(TransData->StartBlob);
00583 
00584     // Allow the specific transforms to set up anything that they may need to set
00585     InitTransformImmediate(pOpParam);
00586 
00587     // Build the transform matrix
00588     BuildMatrix();
00589 
00590     // Build the undo if there was a selection
00591     if (!CompleteTransformation())
00592         FailAndExecute();
00593 
00594     // mark the selection cache as invalid (bounding rects etc will no longer be correct)
00595     m_pTransformRange->Update();
00596 
00597     // End the operation
00598     End();  
00599 }

BOOL TransOperation::DragCopyAction BOOL  bSolidDrag  ) 
 

These two events have the same effect but that effect is set by a user preference. This function looks at that preference and calls the appropriate function.

Returns:
Errors: None.
See also:
TransOperation::OnClickWhileDragging; TransOperation::DropCopy; TransOperation::SetLeaveCopy;

Definition at line 2360 of file transop.cpp.

02361 {
02362     //Call the function appropriate to the preference assigned to the key pressed.
02363     
02364     if (ClickWhileDragFunc > 1)
02365     {
02366         return DropCopy(bSolidDrag);
02367     }
02368     else
02369     {
02370         return SetLeaveCopy();
02371     }
02372 }

void TransOperation::DragFinished DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread pSpread,
BOOL  Success,
BOOL  bSolidDrag
[virtual]
 

Marks the end of the drag. It is at this point that all the transformations should be applied to the selection if everything worked.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/7/94
Parameters:
PointerPos - The position of the mouse at the end of the drag [INPUTS] ClickMods - the keyboard modifiers in place pSpread - the spread that was under the mouse Worked - TRUE if the drag was completed successfully

Reimplemented from Operation.

Reimplemented in OpSliceTranslate.

Definition at line 1179 of file transop.cpp.

01181 {
01182     // By default assume it will not work
01183     BOOL Worked = FALSE;
01184 
01185     // Deregister our idle event handler. We don't want it to keep on rendering!
01186     GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_HIGH, this);
01187 
01188     // Process raw mouse coordinate according to Offset distances...
01189     if (ShouldPointerBeOffset()) PointerPos.translate(Offset.x,Offset.y);
01190 
01191     // Find out how well the drag went . . .
01192     DragEndType HowEnded;
01193     if (!Success)
01194     {
01195         HowEnded = DT_CANCELLED;
01196     }
01197     else if (MouseHasMoved)
01198     {
01199         HowEnded = (PointerPos == RawStartPos) ? DT_MOVEDTOSAME : DT_MOVEDTODIFF;
01200     }
01201     else
01202     {
01203         HowEnded = DT_DIDNOTMOVE;
01204     }
01205 
01206     // Get rid of the temporary solid drag objects...
01207     DocView* pDocView = GetWorkingDocView();
01208     if (m_pDraggedRange)
01209     {
01210         // If we're not going to transform objects to this position
01211         // then force a redraw to remove them from the view
01212         if (AbortTransAtEnd || !Success)
01213             m_pDraggedRange->ForceRedrawView(pDocView, TRUE);
01214         else
01215         // Bodge to ensure that scaled cached data is fully wiped (because
01216         // the scaled cached data may be bigger than the actual scaled vector data)
01217         if (HowEnded==DT_MOVEDTODIFF && m_bRangeCacheTransformed && !Transform.IsTranslation())
01218             m_pDraggedRange->ForceRedrawView(pDocView, TRUE);
01219 
01220         m_pDraggedRange->DeleteNodes();
01221         delete m_pDraggedRange;
01222         m_pDraggedRange = NULL;
01223     }
01224     m_pTransformRange->SetRenderable(TRUE);
01225 
01226     // Rub all that old EORed stuff out, 'cos we sure don't want it now.
01227     if (!bSolidDrag)
01228         m_pTransformRange->RenderXOROutlinesOff(NULL, CurrentSpread, &Transform);
01229     else
01230     {
01231         if (m_bShowOriginalOutlines)
01232             m_pTransformRange->RenderXOROutlinesOff(NULL, CurrentSpread, &OriginalTransform);
01233 
01234         if (!Success)
01235             m_pTransformRange->ForceRedrawView(pDocView, TRUE, FALSE, TRUE);    // Don't recache objects - they haven't changed
01236     }
01237     pDocView->FlushRedraw();
01238 
01239     // Mike 01/02/95 - Change the range control to include NoneRenderables now
01240     RangeControl TransFlags = m_pTransformRange->GetRangeControlFlags();
01241     TransFlags.IgnoreNoneRenderable=FALSE;
01242 
01243     m_pTransformRange->SetRangeControl(TransFlags);
01244 
01245     // Check to see if the operation was a success and if the tool wants me to continue.
01246     BOOL fToolDragOK = TRUE;
01247 
01248 #ifndef STANDALONE
01249     if (pSelTool != NULL) fToolDragOK = pSelTool->DragFinished(HowEnded);
01250 #endif
01251 
01252     //Graham 30/9/96: This code is a bit of a bodge to fix something before the deadline
01253     //Do we need to change the selection?
01254     if (!lstNodesToSelect.IsEmpty()) 
01255     {
01256         //Yes. So first get rid of the current selection 
01257         NodeRenderableInk::DeselectAll(!bSolidDrag, TRUE);
01258 
01259         //And now we need to go through the list of nodes to select, selecting each one
01260         //in turn.
01261         NodeListItem* pThisItem=((NodeListItem*)lstNodesToSelect.GetHead());
01262 
01263         ERROR3IF(pThisItem==NULL, "TransOp::EndDrag - Node list has no head!");
01264 
01265         while (pThisItem!=NULL)
01266         {
01267             //Select the node
01268             Node* pThisNode=pThisItem->pNode;
01269 
01270             ERROR3IF(pThisNode==NULL, "TransOp::EndDrag - Node list item is empty!");
01271 
01272             pThisNode->SetSelected(TRUE);
01273 
01274             NodeRenderableBounded* pThisBoundedNode=((NodeRenderableBounded*) pThisNode);
01275 
01276             if (pThisBoundedNode)
01277                 DoInvalidateNodeRegion(pThisBoundedNode, TRUE, FALSE);
01278 
01279             //And go on to the next node in the list.
01280             pThisItem=(NodeListItem*) lstNodesToSelect.GetNext(pThisItem);
01281         }
01282 
01283         //And get rid of the items in the list now we've used them
01284         lstNodesToSelect.DeleteAll();
01285     }
01286 
01287 
01288     //Graham: If AbortTransAtEnd is set, we don't want to complete the transformation
01289     if (fToolDragOK && Success && HowEnded!=DT_DIDNOTMOVE && !AbortTransAtEnd)
01290     {
01291         // Try to build all the undo information
01292         Worked = CompleteTransformation();
01293 
01294         if (CanChangeSpread())
01295             Document::SetSelectedViewAndSpread(NULL, NULL, m_pDragSpread);
01296 
01297         // mark the selection cache as invalid (bounding rects etc will no longer be correct)
01298         m_pTransformRange->Update();
01299     }
01300 
01301     // End the drag
01302     EndDrag();
01303 
01304     // Use the SliceHelper function to restore the selection back to how it was if it had been modified...
01305     SliceHelper::RestoreSelection();
01306 
01307     // If there was a problem, fail
01308     if (!Worked)
01309         FailAndExecute();
01310 
01311     // DON'T delete these ranges because they are used inside the End() function
01312     // Rely on ~Transop to get rid of them
01313 /*  // tidy up member vars
01314     if (m_pTransformRange)
01315     {
01316         delete m_pTransformRange;
01317         m_pTransformRange = NULL;
01318     }
01319 
01320     if (m_pDraggedRange)
01321     {
01322         delete m_pDraggedRange;
01323         m_pDraggedRange = NULL;
01324     }
01325 */
01326 
01327     // Preserve some data items we need to use below, after "this" has been deleted...
01328     DragTool* pSelToolCopy = pSelTool;
01329     Spread* pSpreadCopy = CurrentSpread;
01330     // pDocview was gained locally in the code above
01331     
01332     // End the operation (and Delete ourselves!)
01333     End();
01334 
01335     // The following code may run when "this" has been deleted!
01336     // (It has to because we don't want to re-enable blob rendering until End() has done its stuff)
01337     // Be VERY careful here!
01338 
01339     // Now turn selection blobs back on
01340