OpLiveEffect Class Reference

Base class for all LiveEffect ops See also:. More...

#include <opliveeffects.h>

Inheritance diagram for OpLiveEffect:

SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject OpApplyFeatherEffect OpApplyLiveEffect OpDeleteAllLiveEffect OpDeleteLiveEffect OpEditLiveEffect OpEffectLock OpEffectRes OpEffectLockAll List of all members.

Public Member Functions

 OpLiveEffect ()
 Constructor.
 ~OpLiveEffect ()
 Destructor.
virtual void Do (OpDescriptor *pOpDesc)
virtual void DoWithParam (OpDescriptor *pOpDesc, OpParam *pOpParam)
ListRangeGetLiveEffectList ()
virtual void DoEndEdit (BOOL bChangingSelection=FALSE, BOOL bBroadcast=TRUE, BOOL bCancelled=FALSE, BOOL bEmpty=FALSE)
BOOL GetPreviewQuality () const
void SetPreviewQuality (BOOL bNew)

Protected Member Functions

ListRangeDoApplyLiveEffect (Range *pSel, String_256 strEffectID, String_64 strDisplayName, double dResolution, IXMLDOMDocumentPtr pEditsList=NULL, BOOL bMakeLocked=FALSE, BOOL bDetectDirectBitmaps=FALSE)
virtual ListRangeDoApplyLockedEffect (Range *pSel, String_256 strEffectID, String_64 strDisplayName, double dResolution, IXMLDOMDocumentPtr pEditsList=NULL, BOOL bDetectDirectBitmaps=FALSE)
BOOL EnsureLiveEffectOriginalBitmaps ()
 Ensure that all NodeBitmapEffects in the current selection have original bitmaps ready and wait for us to pick up.
BOOL GenerateBitmap (NodeBitmapEffect *pBitmapEffect, double dResolution, LPBITMAPINFO *ppInfo, LPBYTE *ppBits, DocRect *prectBounds)
BOOL SetChanged (BOOL bNewState)
BOOL HasChanged ()
 Detect whether any of the LiveEffect nodes created/edited by this operation have actually been changed/do anything useful...
BOOL IsTopOfStack (EffectsStack *pPPStack, INT32 iStackPos)
virtual BOOL DoEffectOp (ListRange *pLevelRange, OpLiveEffectParam *pLEOpParam)
virtual BOOL AllowEmptySelection () const
virtual BOOL CheckEffectOpParam (OpLiveEffectParam *pLEOpParam)
virtual BOOL DoEffectRangeOp (UINT32 idsProgress, Range *pLevel, OpLiveEffectParam *pParam)
virtual BOOL DoEffectNodeOp (NodeEffect *pEffect, OpLiveEffectParam *pParam, NodeBitmapEffect **ppNewEffect)

Protected Attributes

ListRangem_pLERange
BOOL m_bAppliedNewEffects
String_256 m_strEffectID
INT32 m_iStackPos
BOOL m_bPreviewQuality

Private Member Functions

 CC_DECLARE_DYNCREATE (OpLiveEffect)

Static Private Member Functions

static BOOL Init ()
static BOOL UpdateCurrentEditor ()
 Reset the current Op to refer to the new PPStack and tell the running XPE edit that things are changing.
static BOOL DoCopyPPStackToSelection (UndoableOperation *pOp, EffectsStack *pPPStack, Document *pSrcDoc, Document *pDestDoc)
 Copy the specified LiveEffect stack onto the selection Used by Paste Attributes.
static BOOL DoLocaliseLiveEffects (UndoableOperation *pOp, Node *pNode)
 Copy the specified LiveEffect stack onto the selection Used by Paste Attributes.
static BOOL DoLocaliseEffectAttrs (UndoableOperation *pOp, Node *pNode)
 Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup.
static BOOL DoCopyEffectAttr (UndoableOperation *pOp, NodeAttribute *pAttr, Node *pNode)
 Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup.
static NodeDoDeleteAllPostProcessors (UndoableOperation *pOp, NodeRenderableInk *pNode, BOOL bDeleteOldControllers=FALSE, BOOL bDeleteBelowLocked=FALSE)
static BOOL DoDeletePostProcessor (UndoableOperation *pOp, Range *pRange)
static BOOL DoDeletePostProcessor (UndoableOperation *pOp, NodeEffect *pLE, BOOL bMoveEffectAttrs=FALSE)
static ListRangeDoApplyFeatherEffect (UndoableOperation *pOp, Range *pSel, String_256 strEffectID, String_64 strDisplayName, MILLIPOINT FeatherSize, CProfileBiasGain Profile)
static NodeFeatherEffectDoApplyFeatherEffectNode (UndoableOperation *pOp, Node *pSel, String_256 strEffectID, String_64 strDisplayName, MILLIPOINT FeatherSize, CProfileBiasGain Profile)
static BOOL DoCopyEffectsStack (UndoableOperation *pOp, Node *pDestNode, ListRange *pEffectsStack, Document *pSrcDoc, Document *pDestDoc)
 Copy the specified LiveEffect stack onto the selection Used by Paste Attributes and OpCombineShapes.
static NodeBitmapEffectDoApplyLiveEffect (UndoableOperation *pOp, Node *pNode, String_256 strEffectID, String_64 strDisplayName, double dResolution, IXMLDOMDocumentPtr pEditsList=NULL, BOOL bMakeLocked=FALSE)
static BOOL DoCopyAttributes (UndoableOperation *pOp, Node *pSrcNode, Node *pDestNode, BOOL bEffectsOnly, Document *pSrcDoc, Document *pDestDoc)
 Copy the specified LiveEffect stack onto the selection Used by Paste Attributes Assumes that only simple attributes will be copied in simple situations I.e. attrs that aren't optimsed so much.

Detailed Description

Base class for all LiveEffect ops See also:.

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

Definition at line 229 of file opliveeffects.h.


Constructor & Destructor Documentation

OpLiveEffect::OpLiveEffect  ) 
 

Constructor.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
Returns:
Errors: See also:

Definition at line 168 of file opliveeffects.cpp.

00169 {
00170     m_pLERange=NULL;
00171     m_bAppliedNewEffects = FALSE;
00172     m_iStackPos = 0;
00173     m_bPreviewQuality = FALSE;
00174 }

OpLiveEffect::~OpLiveEffect  ) 
 

Destructor.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
Returns:
Errors: See also:

Definition at line 189 of file opliveeffects.cpp.

00190 {
00191     if (m_pLERange)
00192     {
00193         delete m_pLERange;
00194         m_pLERange = NULL;
00195     }
00196 }


Member Function Documentation

virtual BOOL OpLiveEffect::AllowEmptySelection  )  const [inline, protected, virtual]
 

Reimplemented in OpEditLiveEffect.

Definition at line 307 of file opliveeffects.h.

00307 { return FALSE; }

OpLiveEffect::CC_DECLARE_DYNCREATE OpLiveEffect   )  [private]
 

BOOL OpLiveEffect::CheckEffectOpParam OpLiveEffectParam pLEOpParam  )  [protected, virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/06/2005
Parameters:
pLEopParam - pointer to parameter object to check [INPUTS]
- [OUTPUTS]
Returns:
TRUE if Op can continue FALSE otherwise

Reimplemented in OpDeleteAllLiveEffect, and OpEffectLockAll.

Definition at line 2615 of file opliveeffects.cpp.

02616 {
02617     if (pLEOpParam->StackPosition==-1)
02618     {
02619         ERROR3("OpLiveEffect must be given a valid position in the LiveEffects Stack");
02620         return FALSE;
02621     }
02622 
02623 //  ERROR3IF(pLEOpParam->pPPStack==NULL, "Can't find EffectsStack");
02624     if (pLEOpParam->pPPStack==NULL)
02625         return FALSE;
02626 
02627     return TRUE;
02628 }

void OpLiveEffect::Do OpDescriptor pOpDesc  )  [virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/06/2005
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Reimplemented from Operation.

Definition at line 2464 of file opliveeffects.cpp.

02465 {
02466 //  ERROR3("Why are you doing this? You need params, boy, params!");
02467     DoWithParam(pOpDesc, NULL);
02468 }

ListRange * OpLiveEffect::DoApplyFeatherEffect UndoableOperation pOp,
Range pSel,
String_256  strEffectID,
String_64  strDisplayName,
MILLIPOINT  FeatherSize,
CProfileBiasGain  Profile
[static, private]
 

Definition at line 585 of file opliveeffects.cpp.

00591 {
00592     ENSURE(pSel, "DoApplyFeatherEffect not given a useful range");
00593     ENSURE(strEffectID!=String(""), "DoApplyFeatherEffect given blank effect name string");
00594 
00595     ListRange* pLERange = new ListRange();
00596     ENSURE(pLERange, "DoApplyEffect can't create a ListRange");
00597     if (pLERange==NULL)
00598         return NULL;
00599 
00600     Node* pNode = pSel->FindFirst();
00601     BOOL bOK = TRUE;
00602     while (pNode && bOK)
00603     {
00604         NodeFeatherEffect* pEffect = DoApplyFeatherEffectNode(pOp, pNode, strEffectID, strDisplayName, FeatherSize, Profile);
00605         if (pEffect)
00606         {
00607             pLERange->AddNode(pEffect);
00608 
00609             // Make sure the attributes are optimised correctly
00610             bOK = pOp->DoFactorOutCommonChildAttributes(pEffect);
00611         }
00612         else
00613             bOK = FALSE;
00614 
00615         pNode = pSel->FindNext(pNode);
00616     }
00617 
00618     if (pLERange->FindFirst()==NULL || bOK==FALSE)
00619     {
00620         // Don't let an empty list of LiveEffect nodes hang around
00621         delete pLERange;
00622         pLERange = NULL;
00623     }
00624 
00625     return pLERange;
00626 }

NodeFeatherEffect * OpLiveEffect::DoApplyFeatherEffectNode UndoableOperation pOp,
Node pSel,
String_256  strEffectID,
String_64  strDisplayName,
MILLIPOINT  FeatherSize,
CProfileBiasGain  Profile
[static, private]
 

Definition at line 650 of file opliveeffects.cpp.

00656 {
00657     ENSURE(pNode, "DoApplyFeatherEffectNode not given a useful node");
00658     ENSURE(strEffectID!=String(""), "DoApplyFeatherEffectNode given blank effect name string");
00659 
00660     BOOL bSelectInside = pNode->IsSelected() || pNode->IsParentOfSelected();
00661 
00662     // create a new NodeLiveEffect, which we will shortly insert into the tree;
00663     // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong.
00664     NodeFeatherEffect* pBmpFXNode = NULL;
00665     ALLOC_WITH_FAIL(pBmpFXNode, new NodeFeatherEffect, pOp);
00666     if (pBmpFXNode == NULL)
00667         return NULL;
00668 
00669     // put an action to hide the NodeClipViewController onto the undo action-list,
00670     // so that if the user presses undo then it will be hidden.
00671     pBmpFXNode->SetPostProcessorID(strEffectID);
00672     pBmpFXNode->SetDisplayName(strDisplayName);
00673     pBmpFXNode->m_FeatherSize = FeatherSize;
00674     pBmpFXNode->m_Profile = Profile;
00675 
00676     HideNodeAction* pUndoHideNodeAction = NULL;
00677     ActionCode ac = HideNodeAction::Init(pOp,
00678                                         pOp->GetUndoActions(),
00679                                         pBmpFXNode,
00680                                         FALSE,      // don't include subtree size
00681                                         (Action**)&pUndoHideNodeAction,
00682                                         FALSE);     // don't tell subtree when undone
00683     if (ac == AC_FAIL)
00684     {
00685         delete pBmpFXNode;
00686         return NULL;
00687     }
00688 
00689     // right! we've got our node, we've got our action - lets stick it in the tree
00690     // (at a position just next to the last node which will go in the group).
00691     pBmpFXNode->AttachNode(pNode, NEXT);
00692 
00693     // Move the node below the newly inserted LiveEffect
00694     BOOL bOK = pOp->DoMoveNode(pNode, pBmpFXNode, FIRSTCHILD);
00695     if (!bOK)
00696         return NULL;
00697 
00698     // Deselect the node and select the live effect instead
00699     ((NodeRenderable*)pNode)->DeSelect(FALSE);
00700     pBmpFXNode->Select(FALSE);
00701 
00702 // Set the OpPersmission flags in the newly inserted node
00703 // Otherwise the tree scanner in UpdateChangedNodes won't go below this node
00704 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE);  // ReplaceNode & RegenerateNode
00705 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, pOp);
00706 pBmpFXNode->AllowOp(&ObjChange);
00707 
00708     return pBmpFXNode;
00709 }

ListRange * OpLiveEffect::DoApplyLiveEffect Range pSel,
String_256  strEffectID,
String_64  strDisplayName,
double  dResolution,
IXMLDOMDocumentPtr  pEditsList = NULL,
BOOL  bMakeLocked = FALSE,
BOOL  bDetectDirectBitmaps = FALSE
[protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/09/2004
Parameters:
pSel - pointer to range of nodes to insert LiveEffects above [INPUTS] strDispayName - The display name of the effect we're going to apply
pNewSel - pointer to new range of LiveEffect nodes [OUTPUTS]
  • NULL if no new live effects added
Returns:

Errors: See also:

Definition at line 365 of file opliveeffects.cpp.

00366 {
00367     ENSURE(pSel, "DoApplyLiveEffect not given a useful range");
00368     ENSURE(strEffectID!=String(""), "DoApplyLiveEffect given blank effect name string");
00369 
00370     ListRange* pLERange = new ListRange();
00371     ENSURE(pLERange, "DoApplyEffect can't create a ListRange");
00372     if (pLERange==NULL)
00373         return NULL;
00374 
00375     Node* pNode = pSel->FindFirst();
00376     while (pNode)
00377     {
00378         // create a new NodeLiveEffect, which we will shortly insert into the tree;
00379         // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong.
00380         NodeBitmapEffect* pBmpFXNode = NULL;
00381         pBmpFXNode = DoApplyLiveEffect(this, pNode, strEffectID, strDisplayName, dResolution, pEditsList, bMakeLocked);
00382 
00383         if (pBmpFXNode)
00384         {
00385             // If the node we're applying to can supply DirectBitmaps and we can accept them
00386             // Then change res to be "automatic"
00387             if (bDetectDirectBitmaps &&
00388                 pNode->IsAnObject() &&
00389                 ((NodeRenderableInk*)pNode)->CanSupplyDirectBitmap() &&
00390                 dResolution != 0
00391                 )
00392             {
00393                 // Child node can supply a DirectBitmap so it would be better if we were in
00394                 // "Automatic" mode.
00395                 pBmpFXNode->SetPixelsPerInch(0);            // Set "Automatic"
00396 
00397                 // We can only test EnableDirectCapture after we have set the res to automatic
00398                 // Otherwise it may return FALSE because the stored res (dResolution) may not match that
00399                 // of the DirectBitmap child.
00400                 // If it fails, then reset resolution back to what was specified.
00401                 if (!pBmpFXNode->EnableDirectCapture())
00402                     pBmpFXNode->SetPixelsPerInch(dResolution);
00403             }
00404 
00405             // Deselect the node and select the live effect instead
00406             // TODO: Really?
00407             ((NodeRenderable*)pNode)->DeSelect(FALSE);
00408             pBmpFXNode->Select(FALSE);
00409 
00410             pLERange->AddNode(pBmpFXNode);
00411 
00412             // Make sure the attributes are optimised correctly
00413             BOOL ok = DoFactorOutCommonChildAttributes(pBmpFXNode);
00414             if (!ok)
00415                 pBmpFXNode = NULL;
00416         }
00417 
00418         if (!pBmpFXNode)
00419         {
00420             if (pLERange->FindFirst()==NULL)
00421             {
00422                 // Don't let an empty list of LiveEffect nodes hang around
00423                 delete pLERange;
00424                 pLERange = NULL;
00425             }
00426             return pLERange;
00427         }
00428 
00429         pNode = pSel->FindNext(pNode);
00430     }
00431 
00432     if (pLERange->FindFirst()==NULL)
00433     {
00434         // Don't let an empty list of LiveEffect nodes hang around
00435         delete pLERange;
00436         pLERange = NULL;
00437     }
00438 
00439     return pLERange;
00440 }

NodeBitmapEffect * OpLiveEffect::DoApplyLiveEffect UndoableOperation pOp,
Node pNode,
String_256  strEffectID,
String_64  strDisplayName,
double  dResolution,
IXMLDOMDocumentPtr  pEditsList = NULL,
BOOL  bMakeLocked = FALSE
[static, private]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/02/2005
Parameters:
pOp - Op to add undo info to [INPUTS] pNode - pointer to node to insert LiveEffects above strEffectID - Unique identifier for Op strDispayName - The display name of the effect we're going to apply pEditsList - pointer to optional list of edit params for this effect
- [OUTPUTS]
Returns:
TRUE if worked OK

Errors: See also:

Definition at line 469 of file opliveeffects.cpp.

00476 {
00477     ERROR2IF(pOp==NULL, NULL, "Missing Op pointer");
00478     ERROR2IF(pNode==NULL, NULL, "Missing Node pointer");
00479     ERROR2IF(strEffectID==String(""), NULL, "DoApplyLiveEffect given blank effect name string");
00480     ERROR2IF(strDisplayName==String(""), NULL, "DoApplyLiveEffect given blank display name string");
00481 
00482     BOOL bSelectInside = pNode->IsSelected() || pNode->IsParentOfSelected();
00483 
00484     // Possible solution to issue of Bitmap with Feather attr under DirectBitmap effects
00485     // Detect that state, delete the feather attr, apply a feather effect with the same values
00486     //pNode = ApplyDirectFeatherBodge(pNode);
00487 
00488     // create a new NodeLiveEffect, which we will shortly insert into the tree;
00489     // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong.
00490     NodeBitmapEffect* pBmpFXNode = NULL;
00491     if (bMakeLocked)
00492     {
00493         ALLOC_WITH_FAIL(pBmpFXNode, new NodeLockedEffect, pOp);
00494     }
00495     else
00496     {
00497         ALLOC_WITH_FAIL(pBmpFXNode, new NodeLiveEffect, pOp);
00498     }
00499     if (pBmpFXNode==NULL)
00500         return NULL;
00501 
00502     // Get details from XPE so that displayname gets translated into
00503     // locale language if not already
00504     BOOL bDestructive = FALSE;
00505     XPEHost::GetEffectDetails(strEffectID, &strDisplayName, &bDestructive);
00506     ERROR3IF(bDestructive, "DoApplyLiveEffect asked to apply destructive effect!!!");
00507     if (bDestructive)
00508         return NULL;
00509 
00510     // Set effect params
00511     pBmpFXNode->SetPostProcessorID(strEffectID);
00512     pBmpFXNode->SetDisplayName(strDisplayName);
00513     pBmpFXNode->SetPixelsPerInch(dResolution);
00514     if (pEditsList)
00515     {
00516         pBmpFXNode->SetEditList(pEditsList);
00517     }
00518     else if (!pBmpFXNode->SetDefaultEditList())
00519     {
00520         return NULL;
00521     }
00522 
00523     if (pBmpFXNode->IsLockedEffect())
00524         ((NodeLockedEffect*)pBmpFXNode)->SetLockPermanence(bDestructive);
00525 
00526     // put an action to hide the NodeLiveEffect onto the undo action-list,
00527     // so that if the user presses undo then it will be hidden.
00528     HideNodeAction* pUndoHideNodeAction = NULL;
00529     ActionCode ac = HideNodeAction::Init(pOp,
00530                                         pOp->GetUndoActionList(),
00531                                         pBmpFXNode,
00532                                         FALSE,      // don't include subtree size
00533                                         (Action**)&pUndoHideNodeAction,
00534                                         FALSE);     // don't tell subtree when undone
00535     if (ac == AC_FAIL)
00536         return NULL;
00537 
00538     // right! we've got our node, we've got our action - lets stick it in the tree
00539     // (at a position just next to the last node which will go in the group).
00540     pBmpFXNode->AttachNode(pNode, NEXT);
00541 
00542     // Move the node below the newly inserted LiveEffect
00543     BOOL ok = pOp->DoMoveNode(pNode, pBmpFXNode, FIRSTCHILD);
00544     if (!ok)
00545         return NULL;
00546 
00547 // Set the OpPersmission flags in the newly inserted node
00548 // Otherwise the tree scanner in UpdateChangedNodes won't go below this node
00549 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE);  // ReplaceNode & RegenerateNode
00550 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, pOp);
00551 pBmpFXNode->AllowOp(&ObjChange);
00552 
00553     // Deselect the node and select the live effect instead
00554     // TODO: Really?
00555 //  ((NodeRenderable*)pNode)->DeSelect(FALSE);
00556 //  pBmpFXNode->Select(FALSE);
00557 
00558     return pBmpFXNode;
00559 }

ListRange * OpLiveEffect::DoApplyLockedEffect Range pSel,
String_256  strEffectID,
String_64  strDisplayName,
double  dResolution,
IXMLDOMDocumentPtr  pEditsList = NULL,
BOOL  bDetectDirectBitmaps = FALSE
[protected, virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/09/2004
Parameters:
pSel - pointer to range of nodes to insert LiveEffects above [INPUTS] strDispayName - The display name of the effect we're going to apply
pNewSel - pointer to new range of LiveEffect nodes [OUTPUTS]
  • NULL if no new live effects added
Returns:

Errors: See also:

Definition at line 737 of file opliveeffects.cpp.

00743 {
00744     ENSURE(pSel, "DoApplyLockedEffect not given a useful range");
00745     ENSURE(strEffectID!=String(""), "DoApplyLockedEffect given blank effect name string");
00746 
00747     ListRange* pLERange = new ListRange();
00748     ENSURE(pLERange, "DoApplyEffect can't create a ListRange");
00749     if (pLERange==NULL)
00750         return NULL;
00751 
00752     // we need to insert the controller node at the position of the highest
00753     // selected node in the z-order, ie last in the selection, so find it.
00754     Node* pFirstNode = pSel->FindFirst();
00755     Node* pNode = pFirstNode;
00756     Node* pLastNode = NULL;
00757     while (pNode != NULL)
00758     {
00759         pLastNode = pNode;
00760         pNode = pSel->FindNext(pLastNode);
00761     }   // loop terminates with pNode == NULL, pLastNode == last-node-in-sel.
00762 
00763     // create a new NodeClipViewController, which we will shortly insert into the tree;
00764     // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong.
00765     NodeLockedEffect* pBmpFXNode = NULL;
00766     ALLOC_WITH_FAIL(pBmpFXNode, new NodeLockedEffect, this);
00767     BOOL ok = (pBmpFXNode != NULL);
00768 
00769     if (ok)
00770     {
00771         // Get details from XPE so that displayname gets translated into
00772         // locale language if not already and destructive state is updated
00773         // for the current machine (shouldn't really change, though)
00774         BOOL bDestructive = TRUE;
00775         XPEHost::GetEffectDetails(strEffectID, &strDisplayName, &bDestructive);
00776 
00777         pBmpFXNode->SetPostProcessorID(strEffectID);
00778         pBmpFXNode->SetDisplayName(strDisplayName);
00779         pBmpFXNode->SetPixelsPerInch(dResolution);
00780         if (pEditsList)
00781         {
00782             pBmpFXNode->SetEditList(pEditsList);
00783         }
00784         else if (!pBmpFXNode->SetDefaultEditList())
00785         {
00786             delete pBmpFXNode;
00787 
00788             // Don't let an empty list of LiveEffect nodes hang around
00789             delete pLERange;
00790             pLERange = NULL;
00791             return pLERange;
00792         }
00793         pBmpFXNode->SetLockPermanence(bDestructive);
00794 
00795         // put an action to hide the NodeClipViewController onto the undo action-list,
00796         // so that if the user presses undo then it will be hidden.
00797         HideNodeAction* pUndoHideNodeAction = NULL;
00798         ActionCode ac = HideNodeAction::Init(this,
00799                                             &UndoActions,
00800                                             pBmpFXNode,
00801                                             FALSE,      // don't include subtree size
00802                                             (Action**)&pUndoHideNodeAction,
00803                                             FALSE);     // don't tell subtree when undone
00804         if (ac == AC_FAIL)
00805         {
00806             delete pBmpFXNode;
00807 
00808             // Don't let an empty list of LiveEffect nodes hang around
00809             delete pLERange;
00810             pLERange = NULL;
00811             return pLERange;
00812         }
00813         else
00814         {
00815             // right! we've got our node, we've got our action - lets stick it in the tree
00816             // (at a position just next to the last node which will go in the group).
00817             pBmpFXNode->AttachNode(pLastNode, NEXT);
00818             pLERange->AddNode(pBmpFXNode);
00819         }
00820     }
00821 
00822     // move each item from the selection into our ClipView group,
00823     // remembering to deselect them as we go.
00824     // TODO:
00825     //  sneaky suspicion I should be putting this in a Do fn in UndoableOperation...
00826     if (ok)
00827     {
00828         pNode = pSel->FindNext(pFirstNode);             // the node we're moving now.
00829 
00830 //      if (pFirstNode->IsAnObject())
00831 //          ok = DoLocaliseCommonAttributes((NodeRenderableInk*)pFirstNode);
00832 
00833         ok = DoMoveNode(pFirstNode, pBmpFXNode, FIRSTCHILD);
00834         if (ok)
00835             ((NodeRenderable*)pFirstNode)->DeSelect(FALSE, TRUE);
00836     }
00837 
00838     Node* pNextNode     = NULL;                         // the next node to move.
00839     Node* pAnchorNode   = pFirstNode;                   // the node we've just moved.
00840     while (ok && pNode != NULL)
00841     {
00842         // get the next node to move.
00843         pNextNode = pSel->FindNext(pNode);
00844 
00845         // now move the current node next to the anchor and deselect it.
00846 //      if (pNode->IsAnObject())
00847 //          ok = DoLocaliseCommonAttributes((NodeRenderableInk*)pNode);
00848 
00849         ok = DoMoveNode(pNode, pAnchorNode, NEXT);
00850         if (ok)
00851             ((NodeRenderable*)pNode)->DeSelect(FALSE, TRUE);
00852 
00853         // get the new anchor node and the next node to move.
00854         pAnchorNode = pNode;
00855         pNode = pNextNode;
00856     }
00857 
00858     // If we're applied to a single node and that node can supply DirectBitmaps and we can accept them
00859     // Then change res to be same as child node
00860     NodeRenderableInk* pInkNode = pBmpFXNode->GetInkNodeFromController();
00861     if (bDetectDirectBitmaps &&
00862         pInkNode &&
00863         pInkNode->CanSupplyDirectBitmap()
00864         )
00865     {
00866         // Child node can supply a DirectBitmap so it would be better if we had same resolution
00867         // as the child node...
00868         double dDirectRes = 0;
00869         pInkNode->GetDirectBitmap(NULL, NULL, NULL, NULL, NULL, &dDirectRes);
00870         if (dDirectRes!=0)
00871         {
00872             pBmpFXNode->SetPixelsPerInch(dDirectRes);           // Set res
00873 
00874             // We can only test EnableDirectCapture after we have set the res correctly
00875             // Otherwise it may return FALSE because the stored res (dResolution) may not match that
00876             // of the DirectBitmap child.
00877             // If it fails, then reset resolution back to what was specified.
00878             if (!pBmpFXNode->EnableDirectCapture())
00879                 pBmpFXNode->SetPixelsPerInch(dResolution);
00880         }
00881     }
00882 
00883     if (ok)
00884     {
00885         // select the new destructive effect, but don't draw any blobs yet.
00886         pBmpFXNode->Select(FALSE);
00887 
00888         // factor out any common attributes.
00889         DoFactorOutCommonChildAttributes(pBmpFXNode);
00890 
00891 // Set the OpPersmission flags in the newly inserted node
00892 // Otherwise the tree scanner in UpdateChangedNodes won't go below this node
00893 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE);  // ReplaceNode & RegenerateNode
00894 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, this);
00895 pBmpFXNode->AllowOp(&ObjChange);
00896     }
00897 
00898     if (pLERange->FindFirst()==NULL)
00899     {
00900         // Don't let an empty list of LiveEffect nodes hang around
00901         delete pLERange;
00902         pLERange = NULL;
00903     }
00904 
00905     return pLERange;
00906 }

BOOL OpLiveEffect::DoCopyAttributes UndoableOperation pOp,
Node pSrcNode,
Node pDestNode,
BOOL  bEffectsOnly,
Document pSrcDoc,
Document pDestDoc
[static, private]
 

Copy the specified LiveEffect stack onto the selection Used by Paste Attributes Assumes that only simple attributes will be copied in simple situations I.e. attrs that aren't optimsed so much.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/03/2005
Parameters:
pOp - POinter to Op to add undo records to [INPUTS] pSrcNode - Node containing attrs to copy pDestNode - Node to copy attrs into bEffectsOnly - TRUE if should only copy Effect Attrs Doc ptrs to allow component data to be copied
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 1692 of file opliveeffects.cpp.

01693 {
01694     if (!pDestNode->IsBounded() || !pSrcNode->IsBounded())
01695         return TRUE;
01696 
01697     ((NodeRenderableBounded*)pDestNode)->InvalidateBoundingRect();
01698     DocRect NodeBounds = ((NodeRenderableBounded*)pDestNode)->GetBoundingRect(TRUE);
01699     Node* pNode = pSrcNode->FindFirstChild();
01700     while (pNode)
01701     {
01702         if (pNode->IsAnAttribute())
01703         {
01704             NodeAttribute* pAttr = (NodeAttribute*)pNode;
01705             if (!bEffectsOnly || pAttr->IsEffectAttribute())
01706             {
01707                 if (pAttr->CanBeAppliedToObject())
01708                 {
01709                     NodeAttribute* pAttrCopy = NULL;
01710                     pAttr->NodeCopy((Node **)(&pAttrCopy));
01711 
01712                     if (pAttrCopy->IsAFillAttr())
01713                     {
01714                         // Set the bounds of the attribute. (Why is this wrong here?)
01715                         ((AttrFillGeometry*)pAttrCopy)->SetBoundingRect(((NodeRenderableBounded*)pSrcNode)->GetBoundingRect());
01716 
01717                         // I'm not sure if this is neccessary but Will does it when making an attribute
01718                         // current.
01719                         if (pAttrCopy->IsAFractalFill())
01720                         {
01721                             // The attr, should always use the default DPI for fractals.
01722                             ((AttrFillGeometry*)pAttrCopy)->SetFractalDPI(AttrFillGeometry::FractalDPI);
01723                         }
01724                     }
01725 
01726                     pAttrCopy->TransformToNewBounds(NodeBounds); 
01727                     pAttrCopy->AttachNode(pDestNode, LASTCHILD);
01728                     pAttrCopy->LinkToGeometry(pDestNode);
01729 
01730                     if (pAttrCopy->IsAFillAttr())
01731                     {
01732                         // Now the Attribute is in the tree, we need to tell the fill
01733                         // attribute to check that it's control points are valid.
01734                         // Unless the fill we transformed above, this will usually 
01735                         // involve the fill 'centring' itself within the bounds of its
01736                         // parent.
01737                         ((AttrFillGeometry*)pAttrCopy)->AttributeChanged();
01738                     }
01739 
01740                     // Inform all DocComponents in the destination doc that a copy is about to take place
01741                     BOOL ok;
01742                     CALL_WITH_FAIL((pDestDoc->StartComponentCopy()), pOp, ok)
01743                     if (ok)
01744                     {
01745                         if (!pAttrCopy->CopyComponentData(pSrcDoc, pDestDoc))
01746                         {
01747                             pDestDoc->AbortComponentCopy(); // Cancel all data which has been copied
01748                             ok = FALSE; // stop what were doing
01749                         }
01750 
01751                         if (ok)
01752                             ok = pDestDoc->EndComponentCopy();
01753                     }
01754 
01755                     // Remove similar nodes in this level
01756                     Node* pCurrent = pDestNode->FindFirstChild();
01757                     Node* pNext;
01758                     CCRuntimeClass* pAttrType = pAttrCopy->GetAttributeType();
01759                     while (pCurrent)
01760                     {
01761                         pNext =  pCurrent->FindNext();
01762                         // Determine if the Current node is to be hidden
01763                         if (pCurrent!=pAttrCopy && pCurrent->IsKindOf(CC_RUNTIME_CLASS(NodeAttribute)))
01764                         {
01765                             { 
01766                                 if (((NodeAttribute*)pCurrent)->GetAttributeType() == pAttrType)
01767                                 {
01768                                     pCurrent->CascadeDelete();
01769                                     delete pCurrent;
01770                                 }
01771                             }
01772                         }
01773                         pCurrent = pNext;
01774                     }
01775                 }
01776             }
01777         }
01778 
01779         pNode = pNode->FindNext();
01780     }
01781 
01782     return TRUE;
01783 }

BOOL OpLiveEffect::DoCopyEffectAttr UndoableOperation pOp,
NodeAttribute pAttr,
Node pNode
[static, private]
 

Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/03/2005
Parameters:
pOp - pointer to op [INPUTS] pAttr - pointer to effect attribute to copy pNode - pointer to node whose children should get copies of the attribute
[OUTPUTS] 
Returns:
TRUE if it worked

Errors: See also:

Definition at line 1969 of file opliveeffects.cpp.

01970 {
01971     Node* pChildNode = pNode->FindFirstChild();
01972     while (pChildNode)
01973     {
01974         if (pChildNode->IsAnObject())
01975         {
01976             NodeRenderableInk* pInkNode = (NodeRenderableInk*)pChildNode;
01977             if (pInkNode->IsValidEffectAttr(pAttr))
01978             {
01979                 NodeAttribute* pExistingAttr = pInkNode->FindAppliedAttribute(pAttr->GetRuntimeClass());
01980                 if (pExistingAttr==NULL || pExistingAttr->FindParent()!=pInkNode)
01981                 {
01982                     // We can copy our effect attr to pInkNode as an effect attr
01983                     // Make a copy of this LiveEffect
01984                     NodeAttribute* pCopyAttr = NULL;
01985                     BOOL bOK = FALSE;
01986                     CALL_WITH_FAIL(pCopyAttr = (NodeAttribute*)pAttr->SimpleCopy(), pOp, bOK);  
01987                     if (!bOK) return FALSE; // No room to take a copy of the node
01988 
01989 //                  pOp->DoInsertNewNode(pCopyAttr, pInkNode, LASTCHILD, FALSE, FALSE, FALSE, FALSE);
01990 
01991                     // Create a hide node action to hide the node when we undo 
01992                     pCopyAttr->AttachNode(pInkNode, LASTCHILD);
01993                     HideNodeAction* UndoHideNodeAction;
01994                     if (HideNodeAction::Init(pOp, pOp->GetUndoActions(), pCopyAttr, TRUE, (Action**)(&UndoHideNodeAction))
01995                             == AC_FAIL)
01996                     {
01997                         pCopyAttr->CascadeDelete();
01998                         delete pCopyAttr;
01999                         return FALSE;
02000                     }
02001                 }
02002             }
02003             else
02004             {
02005                 NodeAttribute* pExistingAttr = pInkNode->FindAppliedAttribute(pAttr->GetRuntimeClass());
02006                 if (pExistingAttr==NULL || pExistingAttr->FindParent()!=pInkNode)
02007                 {
02008                     // We can copy our effect attrs to pInkNode as a normal attr
02009                     NodeAttribute* pCopyAttr = NULL;
02010                     BOOL bOK = FALSE;
02011                     CALL_WITH_FAIL(pCopyAttr = (NodeAttribute*)pAttr->SimpleCopy(), pOp, bOK);  
02012                     if (!bOK) return FALSE; // No room to take a copy of the node
02013 
02014 //                  pOp->DoInsertNewNode(pCopyAttr, pInkNode, FIRSTCHILD, FALSE, FALSE, FALSE, FALSE);
02015 
02016                     // Create a hide node action to hide the node when we undo 
02017                     pCopyAttr->AttachNode(pInkNode, FIRSTCHILD);
02018                     HideNodeAction* UndoHideNodeAction;
02019                     if (HideNodeAction::Init(pOp, pOp->GetUndoActions(), pCopyAttr, TRUE, (Action**)(&UndoHideNodeAction))
02020                             == AC_FAIL)
02021                     {
02022                         pCopyAttr->CascadeDelete();
02023                         delete pCopyAttr;
02024                         return FALSE;
02025                     }
02026 
02027 //                  if (UndoHideNodeAction)
02028 //                      UndoHideNodeAction->DontPanic();
02029 
02030                     // Remove any deeper attributes of the same type to make a consistent structure
02031                     pOp->DoRemoveAttrTypeFromSubtree(pInkNode, pAttr->GetRuntimeClass(), pCopyAttr);
02032                 }
02033             }
02034         }
02035 
02036         pChildNode = pChildNode->FindNext();
02037     }
02038 
02039     return TRUE;
02040 }

BOOL OpLiveEffect::DoCopyEffectsStack UndoableOperation pOp,
Node pDestNode,
ListRange pEffectsStack,
Document pSrcDoc,
Document pDestDoc
[static, private]
 

Copy the specified LiveEffect stack onto the selection Used by Paste Attributes and OpCombineShapes.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/02/2005
Parameters:
pOp - pointer to Op [INPUTS] pPPStack - pointer to EffectsStack to copy
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 1530 of file opliveeffects.cpp.

01531 {
01532     ERROR2IF(pOp==NULL, FALSE, "No Op given to DoCopyEffectsStack\n");
01533     ERROR2IF(pEffectsStack==NULL || pEffectsStack->IsEmpty(), FALSE, "No stack/empty stack given to DoCopyEffectsStack\n");
01534     ERROR2IF(pDestNode==NULL, FALSE, "No destination node given to DoCopyEffectsStack\n");
01535 
01536     //-----------------------------------------------------------------------------
01537     // Remove all current LiveEffects on the selection
01538     //
01539     if (pDestNode->IsAnObject() && !pDestNode->NeedsParent(pDestNode->FindParent()))
01540         pDestNode = DoDeleteAllPostProcessors(pOp, (NodeRenderableInk*)pDestNode, FALSE, TRUE); // TRUE means delete all effects in stack, even those below pDestNode
01541 
01542     //-----------------------------------------------------------------------------
01543     // Apply new LiveEffects from the specified stack
01544     //
01545     BOOL bWasSelected = pDestNode->IsSelected() || pDestNode->IsParentOfSelected();
01546     Node* pSelectNode = pDestNode;
01547     if (pDestNode->IsNodeRenderableClass())
01548         ((NodeRenderable*)pDestNode)->DeSelect(FALSE, TRUE);
01549 
01550     Node* pTopNode = pDestNode;
01551 
01552     NodeEffect* pEffect = (NodeEffect*)pEffectsStack->FindFirst();
01553     while (pEffect)
01554     {
01555         // Test for legacy effect special cases first
01556         // Shadow -------------------------------------------------------------
01557         if (pEffect->IsAShadowController())
01558         {
01559             if (pTopNode->NeedsParent(pTopNode->FindParent()))
01560             {
01561                 if (pTopNode->IsAShadow())
01562                 {
01563                     // TODO: Copy shadow properties here?
01564                 }
01565             }
01566             else
01567             {
01568                 NodeShadowController* pController = (NodeShadowController*)pEffect;
01569 
01570                 NodeShadowParam param(pController->GetShadowType(),
01571                                         pController->GetFloorShadowAngle(),
01572                                         pController->GetFloorShadowHeight(),
01573                                         pController->GetOffsetX(),
01574                                         pController->GetOffsetY(),
01575                                         pController->GetPenumbraWidth(),
01576                                         pController->GetShadow()->GetDarkness(),
01577                                         pController->GetWallShadowScale(),
01578                                         pController->GetGlowWidth(),
01579                                         pController->GetShadow()->GetBiasGain(),
01580                                         TRUE);
01581                 param.strOpUnique = pEffect->GetPostProcessorID();
01582                 param.StackPosition = STACKPOS_INSERT_TOP;
01583                 pTopNode = OpApplyShadow::DoApplyShadow(pOp, pTopNode, &param, FALSE);
01584     //          BOOL ok = pOp->DoFactorOutCommonChildAttributes(pShadControl);
01585                 if (pTopNode == NULL)
01586                 {
01587                     pOp->FailAndExecute();
01588                     return FALSE;
01589                 }
01590 
01591                 // Copy attributes applied to Shadow node
01592                 NodeShadow* pShadow = pController->GetShadow();
01593                 NodeShadow* pNewShadow = NULL;
01594                 if (pTopNode->IsAShadowController())
01595                     pNewShadow = ((NodeShadowController*)pTopNode)->GetShadow();
01596                 ERROR3IF(pShadow==NULL || pNewShadow==NULL, "ShadowController doesn't seem to have a shadow");
01597                 if (pShadow && pNewShadow)
01598                 {
01599                     DoCopyAttributes(pOp, pShadow, pNewShadow, FALSE, pSrcDoc, pDestDoc);
01600                 }
01601 
01602                 delete param.pPPStack;
01603             }
01604         }
01605         // Feather -----------------------------------------------------------------
01606         else if (pEffect->IsFeatherEffect())
01607         {
01608             NodeFeatherEffect* pFeather = (NodeFeatherEffect*)pEffect;
01609             String_64 strDisplayName;
01610             XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strDisplayName);
01611             pTopNode = DoApplyFeatherEffectNode(pOp, pTopNode, pEffect->GetPostProcessorID(), strDisplayName, pFeather->GetFeatherSize(), pFeather->GetProfile());
01612             if (pTopNode == NULL)
01613             {
01614                 pOp->FailAndExecute();
01615                 return FALSE;
01616             }
01617         }
01618         // LiveEffects -------------------------------------------------------------
01619         else if (pEffect->IsBitmapEffect())
01620         {
01621             if (pEffect->IsLockedEffect() && ((NodeLockedEffect*)pEffect)->CanBeUnlocked())
01622             {
01623                 String_64 strDisplayName;
01624                 XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strDisplayName);
01625                 pTopNode = DoApplyLiveEffect(pOp, pTopNode, pEffect->GetPostProcessorID(), strDisplayName, ((NodeBitmapEffect*)pEffect)->GetPixelsPerInchValue(), ((NodeBitmapEffect*)pEffect)->GetEditList(), TRUE);   // MakeLocked
01626                 if (pTopNode == NULL)
01627                 {
01628                     pOp->FailAndExecute();
01629                     return FALSE;
01630                 }
01631             }
01632             else if (!pEffect->IsLockedEffect())
01633             {
01634                 String_64 strDisplayName;
01635                 XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strDisplayName);
01636                 pTopNode = DoApplyLiveEffect(pOp, pTopNode, pEffect->GetPostProcessorID(), strDisplayName, ((NodeBitmapEffect*)pEffect)->GetPixelsPerInchValue(), ((NodeBitmapEffect*)pEffect)->GetEditList(), FALSE);
01637                 if (pTopNode == NULL)
01638                 {
01639                     pOp->FailAndExecute();
01640                     return FALSE;
01641                 }
01642             }
01643             if (pTopNode->IsEffect() && ((NodeEffect*)pTopNode)->IsLockedEffect())
01644             {
01645                 // Don't allow anything to be selected inside a Locked effect!
01646                 pSelectNode = pTopNode;
01647             }
01648         }
01649 
01650         // Copy effect attributes that might be applied to this level
01651         if (pTopNode)
01652         {
01653             DoCopyAttributes(pOp, pEffect, pTopNode, TRUE, pSrcDoc, pDestDoc);
01654         }
01655 
01656         // ----------------------------------------------------------------------
01657         pEffect = (NodeEffect*)pEffectsStack->FindNext(pEffect);
01658     }
01659 
01660     if (pSelectNode && bWasSelected && pSelectNode->IsNodeRenderableClass())
01661     {
01662         ((NodeRenderable*)pSelectNode)->Select(FALSE);
01663     }
01664 
01665     return TRUE;
01666 }

BOOL OpLiveEffect::DoCopyPPStackToSelection UndoableOperation pOp,
EffectsStack pPPStack,
Document pSrcDoc,
Document pDestDoc
[static, private]
 

Copy the specified LiveEffect stack onto the selection Used by Paste Attributes.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/10/2004
Parameters:
pPPStack - pointer to EffectsStack to copy [INPUTS]
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 1464 of file opliveeffects.cpp.

01465 {
01466     ERROR2IF(pPPStack==NULL || pPPStack->IsEmpty(), FALSE, "No stack/empty stack given to DoCopyPPStackToSelection\n");
01467 
01468     SelRange* pRange = GetApplication()->FindSelection();
01469     ERROR2IF(pRange==NULL, FALSE, "Can't find SelRange\n");
01470 
01471     if (pPPStack==NULL)
01472         return TRUE;            // That was easy!
01473 
01474     // Convert the pPPStack into a simple ListRange for DoCopyEffectsStack
01475     ListRange EffectsStack;
01476     INT32 l = 0;
01477     PPStackLevel* pLevel = pPPStack->GetLevel(l);
01478     while (pLevel)
01479     {
01480         ERROR3IF(pLevel->pPPNode==NULL, "PPStack has a badly formed level in it");
01481 
01482         if (pLevel->pPPNode->CanBeUnlocked())
01483             EffectsStack.AddNode(pLevel->pPPNode);
01484 
01485         pLevel = pPPStack->GetLevel(++l);
01486     }
01487 
01488     pOp->DoInvalidateNodesRegions(*pRange, TRUE, FALSE);
01489 
01490     // Now loop through the selection
01491     if (!EffectsStack.IsEmpty())
01492     {
01493         Node* pNode = pRange->FindFirst();
01494         Node* pNextNode = NULL;
01495         while (pNode)
01496         {
01497             pNextNode = pRange->FindNext(pNode);
01498 
01499             DoCopyEffectsStack(pOp, pNode, &EffectsStack, pSrcDoc, pDestDoc);
01500 
01501             pNode = pNextNode;
01502         }
01503     }
01504 
01505     pOp->DoInvalidateNodesRegions(*pRange, TRUE, FALSE);
01506 
01507     return TRUE;
01508 }

Node * OpLiveEffect::DoDeleteAllPostProcessors UndoableOperation pOp,
NodeRenderableInk pNode,
BOOL  bDeleteOldControllers = FALSE,
BOOL  bDeleteBelowLocked = FALSE
[static, private]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/11/2004
Parameters:
pOp - Operation to add undo actions to [INPUTS] pNode - Selected node (note, not parent of selected)
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 2060 of file opliveeffects.cpp.

02061 {
02062     BOOL bOK = TRUE;
02063 
02064     // First, find pointer to child node to be moved into place as the LiveEffects stack is deleted
02065     Node* pNewBaseNode = pNode;
02066     if (pNode->IsEffect())
02067     {
02068         ENSURE(((NodeEffect*)pNode)->IsLockedEffect(), "Only destructive LiveEffects should be selectable");
02069         // Find the first ink node that's a child of this LiveEffect
02070         if (bDeleteBelowLocked)
02071         {
02072             // Locked effects can have several children - GetInkNodeFC only returns non-NULL
02073             // when there is a single node below the locked effect
02074             if (((NodeEffect*)pNewBaseNode)->GetInkNodeFromController()==NULL)
02075                 pNewBaseNode = pNewBaseNode->FindFirstChild();
02076             else
02077             {
02078                 Node* pChild = pNewBaseNode;
02079                 while (pChild && pChild->IsEffect())
02080                 {
02081                     pChild = ((NodeEffect*)pChild)->GetInkNodeFromController();
02082 
02083                     if (pChild)
02084                         pNewBaseNode = pChild;
02085                 }
02086             }
02087         }
02088     }
02089 
02090     Node* pHighestLE = NULL;
02091     Node* pEffectScanBase = NULL;
02092 
02093 /*  // [Phil, 22/08/2005] There must be a better way to arrange the following logic!
02094     //
02095     // Push common attributes down into the nodes we're going to retain
02096     Node* pAncestor = pChild->FindParent();
02097     if (pAncestor && !pAncestor->IsAnObject())
02098         pAncestor = NULL;
02099     if (pAncestor)
02100     {
02101         bOK = pOp->DoLocaliseCommonAttributes((NodeRenderableInk*)pAncestor, FALSE, TRUE);
02102         if (!bOK) return FALSE;
02103     }
02104 
02105     // If there are old style controller nodes applied to the object before any effects
02106     // Then get rid of them...
02107     if (bDeleteOldControllers)
02108     {
02109         while (pAncestor && pAncestor->IsController() && !pAncestor->IsEffect())
02110         {
02111             pHighestLE = pAncestor;
02112             pAncestor = pAncestor->FindParent();
02113         }
02114     }
02115     else
02116     {
02117         // Move the BaseNode pointer above the old controllers that we are not deleting
02118         while (pAncestor && pAncestor->IsController() && !pAncestor->IsEffect())
02119         {
02120             pNewBaseNode = pAncestor;
02121             pAncestor = pAncestor->FindParent();
02122         }
02123     }
02124 
02125     // Delete all LiveEffects from pChild upwards
02126     while (pAncestor && pAncestor->IsEffect())
02127     {
02128         pHighestLE = pAncestor;
02129         pAncestor = pAncestor->FindParent();
02130     }
02131 */
02132     // ------------------------------------------------------------------
02133     // Deal with old style controllers
02134     {
02135         Node* pAncestor = pNewBaseNode->FindParent();
02136         Node* pHighestOldController = NULL;
02137         pEffectScanBase = pNewBaseNode;
02138         while (pAncestor && pAncestor->IsController() && !pAncestor->IsEffect())
02139         {
02140             pHighestOldController = pAncestor;
02141             pAncestor = pAncestor->FindParent();
02142         }
02143 
02144         if (pHighestOldController)
02145         {
02146             if (bDeleteOldControllers)
02147                 pEffectScanBase = pHighestOldController;    // Leave base node pointer alone and tell scanner to start above the old controllers
02148             else
02149             {
02150                 pEffectScanBase = pHighestOldController;    // Tell scanner to start above the old controllers
02151                 pNewBaseNode = pHighestOldController;       // but Reset base node pointer to refer to it so we leave it in the tree
02152             }
02153         }
02154     }
02155 
02156     // ------------------------------------------------------------------
02157     // Find highest Effect above the base node
02158     {
02159         Node* pAncestor = pEffectScanBase->FindParent();
02160         while (pAncestor && pAncestor->IsEffect())
02161         {
02162             pHighestLE = pAncestor;
02163             pAncestor = pAncestor->FindParent();
02164         }
02165     }
02166 
02167     // ------------------------------------------------------------------
02168     // Push common attributes down into the nodes we're going to retain (the base node)
02169     {
02170         Node* pAncestor = pNewBaseNode->FindParent();
02171         if (pAncestor && pAncestor->IsAnObject())
02172         {
02173             bOK = pOp->DoLocaliseCommonAttributes((NodeRenderableInk*)pAncestor, FALSE, TRUE);
02174             if (!bOK) return NULL;
02175         }
02176     }
02177 
02178     // ------------------------------------------------------------------
02179     // If we have found Effects above the selected node (then we can
02180     // get rid of them)
02181     if (pHighestLE)
02182     {
02183         // Loop around all the children of the LiveEffect moving them up
02184         // (but note that only Destructive effects can have multiple children...)
02185         // (Er, but note again that effect attributes can be left in the tree...)
02186         Node* pInsertNode = pHighestLE;
02187         Node* pNextChild = NULL;
02188         Node* pChild = pNewBaseNode;
02189         while (pChild)
02190         {
02191             pNextChild = pChild->FindNext();                                // Find next child before we move it!
02192 
02193             if (pChild->IsAnObject())
02194             {
02195                 // Only move pChild if it's not linked to the PostProcessor above it!
02196                 // (Otherwise leave it in place so it gets hidden along with the PostPros)
02197                 if (!((NodeRenderableInk*)pChild)->NeedsParent(pChild->FindParent()))   // Controlled?
02198                 {
02199                     bOK = pOp->DoMoveNode(pChild, pInsertNode, NEXT);
02200                     if (!bOK) return NULL;
02201 
02202                     ((NodeRenderableInk*)pChild)->Select(FALSE);
02203 
02204                     if (pChild->IsAnObject())
02205                         pOp->DoFactorOutCommonAttributes((NodeRenderableInk*)pChild);
02206 
02207                     pInsertNode = pChild;
02208                 }
02209             }
02210 
02211             pChild = (NodeRenderableInk*)pNextChild;
02212         }
02213 
02214         // Now that all the children are moved outside all the LE nodes
02215         // we can delete all the LE nodes (by hiding the root node and thus
02216         // hiding the entire stack at one go!)
02217         if (pHighestLE->IsRenderable())
02218             ((NodeRenderable*)pHighestLE)->DeSelect(FALSE);
02219         bOK = pOp->DoHideNode(pHighestLE, FALSE, NULL, FALSE);
02220     }
02221 
02222     return pNewBaseNode;
02223 }

BOOL OpLiveEffect::DoDeletePostProcessor UndoableOperation pOp,
NodeEffect pLE,
BOOL  bMoveEffectAttrs = FALSE
[static, private]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/04/2005
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 2284 of file opliveeffects.cpp.

02285 {
02286     BOOL ok = FALSE;
02287 
02288     // We should have a decent list of LiveEffect nodes...
02289     ERROR2IF(pLE==NULL, FALSE, "DoDeletePostProcessor given NULL node");
02290 
02291     // Go through all the LiveEffects, move their children up to be siblings and then
02292     // "delete" the LiveEffect nodes by hiding them.
02293     //
02294     BOOL bSelected = pLE->IsSelected();
02295 
02296     pOp->DoLocaliseCommonAttributes(pLE);
02297 
02298     // Loop around all the children of the LiveEffect moving them up
02299     // (but note that only Destructive effects can have multiple children...)
02300     // (Er, but note again that effect attributes can be left in the tree...)
02301     Node* pInsertNode = pLE;
02302     Node* pNextChild = NULL;
02303     Node* pParent = pLE->FindParent();
02304     NodeEffect* pParentEffect = NULL;
02305     if (pParent && pParent->IsEffect())
02306         pParentEffect = (NodeEffect*)pLE->FindParent();
02307     NodeRenderableInk* pChild = (NodeRenderableInk*)pLE->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk));
02308 
02309     while (pChild)
02310     {
02311         pNextChild = pChild->FindNext();                            // Find next child before we move it!
02312 
02313         if (pChild->IsAnObject())
02314         {
02315             // Only move pChild if it's not linked to the PostProcessor above it!
02316             // (Otherwise leave it in place so it gets hidden along with the PostPros)
02317             if (!((NodeRenderableInk*)pChild)->NeedsParent(pChild->FindParent()))   // Controlled?
02318             {
02319                 pOp->DoMoveNode(pChild, pInsertNode, NEXT);
02320                 if (bSelected)
02321                     pChild->Select(FALSE);
02322                 if (pChild->IsAnObject())
02323                     pOp->DoFactorOutCommonAttributes((NodeRenderableInk*)pChild);
02324 
02325                 pInsertNode = pChild;
02326             }
02327         }
02328 
02329         if (bMoveEffectAttrs && pParentEffect && pChild->IsAnAttribute() && ((NodeAttribute*)pChild)->IsEffectAttribute())
02330         {
02331             if (pParentEffect->IsValidEffectAttr((NodeAttribute*)pChild))
02332             {
02333                 pOp->DoMoveNode(pChild, pInsertNode, NEXT);
02334                 pInsertNode = pChild;
02335             }
02336         }
02337 
02338         pChild = (NodeRenderableInk*)pNextChild;
02339     }
02340 
02341     pLE->ReleaseCached(TRUE, FALSE, FALSE, FALSE);
02342     if (bSelected)
02343         pLE->DeSelect(FALSE);
02344     pOp->DoHideNode(pLE, FALSE, NULL, FALSE);
02345 
02346     return TRUE;
02347 }

BOOL OpLiveEffect::DoDeletePostProcessor UndoableOperation pOp,
Range pRange
[static, private]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/11/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 2242 of file opliveeffects.cpp.

02243 {
02244     BOOL ok = FALSE;
02245 
02246     // We should have a decent list of LiveEffect nodes...
02247     ERROR2IF(pRange==NULL, FALSE, "DoDeletePostProcessor given an empty range");
02248 
02249     // Go through all the LiveEffects, move their children up to be siblings and then
02250     // "delete" the LiveEffect nodes by hiding them.
02251     //
02252     Node* pNode = pRange->FindFirst();
02253     while (pNode)
02254     {
02255         if (pNode->IsEffect())
02256         {
02257             NodeEffect* pLE = (NodeEffect*)pNode;
02258             DoDeletePostProcessor(pOp, pLE);
02259         }
02260 
02261         pNode = pRange->FindNext(pNode);
02262     }
02263 
02264     return TRUE;
02265 }

virtual BOOL OpLiveEffect::DoEffectNodeOp NodeEffect pEffect,
OpLiveEffectParam pParam,
NodeBitmapEffect **  ppNewEffect
[inline, protected, virtual]
 

Reimplemented in OpEffectRes, and OpEffectLock.

Definition at line 310 of file opliveeffects.h.

00310 {*ppNewEffect = NULL; return FALSE;}

virtual BOOL OpLiveEffect::DoEffectOp ListRange pLevelRange,
OpLiveEffectParam pLEOpParam
[inline, protected, virtual]
 

Reimplemented in OpEditLiveEffect, OpDeleteLiveEffect, OpDeleteAllLiveEffect, OpEffectRes, OpEffectLock, and OpEffectLockAll.

Definition at line 306 of file opliveeffects.h.

00306 { return TRUE; }

BOOL OpLiveEffect::DoEffectRangeOp UINT32  idsProgress,
Range pRange,
OpLiveEffectParam pParam
[protected, virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/06/2005
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 2366 of file opliveeffects.cpp.

02367 {
02368     BOOL ok = FALSE;
02369     Progress progress(idsProgress, pRange->Count(), FALSE);
02370 
02371     // We should have a decent list of LiveEffect nodes...
02372     ERROR2IF(pRange==NULL, FALSE, "DoEffectRangeOp given an empty range");
02373 
02374     // Go through all the LiveEffects, move their children up to be siblings and then
02375     // "delete" the LiveEffect nodes by hiding them.
02376     //
02377     INT32 iCount = 0;
02378     INT32 iChanges = 0;
02379     Node* pNode = pRange->FindFirst();
02380     while (pNode && progress.Update(iCount, TRUE) && !OpHasFailed())
02381     {
02382         if (pNode->IsEffect())
02383         {
02384             // --------------------------------------------
02385             // This is the core of this function,
02386             // Call overridden specialist function to perform
02387             // the Op on this node alone
02388             NodeEffect* pLE = (NodeEffect*)pNode;
02389             NodeBitmapEffect* pNewEffect = NULL;
02390             BOOL bChanged = DoEffectNodeOp(pLE, pParam, &pNewEffect);
02391             // --------------------------------------------
02392 
02393             if (bChanged)
02394             {
02395                 iChanges++;
02396 
02397                 // Invalidate the region we just changed
02398                 // (Rely on DoEffectNodeop to have released the cache if it thinks it needs to
02399                 if (!DoInvalidateNodeRegion(pNewEffect, TRUE, FALSE, FALSE, FALSE))
02400                 {
02401                     FailAndExecute();
02402                     End();
02403                     return FALSE;
02404                 }
02405 
02406                 // Update the view inside our progress indication so the user gets
02407                 // better idea of where we are...
02408                 DocView* pDocView = GetWorkingDocView();
02409                 if (pDocView)
02410                 {
02411                     // Update just the working view immediately
02412                     pDocView->FlushRedraw();
02413                     GetApplication()->ServiceRendering();
02414                 }
02415             }
02416         }
02417 
02418         iCount++;
02419         pNode = pRange->FindNext(pNode);
02420     }
02421 
02422     // If we aborted with nodes remaining to be done
02423     // Then abort the whole Operation!
02424     if (pNode)
02425     {
02426         FailAndExecute();
02427         End();
02428         return FALSE;
02429     }
02430 
02431 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE);
02432 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this);
02433 ok = UpdateChangedNodes(&ObjChange);
02434 
02435     // If we didn't change anything then don't add this op to the undo history
02436     if (iChanges==0)
02437     {
02438         SucceedAndDiscard();
02439         End();
02440         return FALSE;
02441     }
02442 
02443     End();
02444     return FALSE;           // We don't need any of the normal tidy up to occur
02445 }

void OpLiveEffect::DoEndEdit BOOL  bChangingSelection = FALSE,
BOOL  bBroadcast = TRUE,
BOOL  bCancelled = FALSE,
BOOL  bEmpty = FALSE
[virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/09/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 1356 of file opliveeffects.cpp.

01357 {
01358     BOOL ok = FALSE;
01359     BOOL bRecache = FALSE;
01360 
01361     // If the are no changes in any of the LiveEffect nodes as a result of this edit
01362     // And we only just created new LiveEffects in this Op
01363     // Then remove them from the tree because they are redundant
01364     if (bCancelled || (m_bAppliedNewEffects && (!HasChanged() || bEmpty)))
01365     {
01366         if (bChangingSelection)
01367             FailAndExecuteIgnoreSelActions();
01368         else
01369             FailAndExecute();
01370         // Tell the selrange that things have changed!
01371         GetApplication()->FindSelection()->Update();
01372         End();
01373         return;
01374     }
01375 
01376     // If we were editing but we are told that the edit has resulted in a NULL effect
01377     // Then we can remove the effect to keep things neat and tidy
01378     if (bEmpty && !m_bAppliedNewEffects && m_pLERange!=NULL)
01379     {
01380         BOOL bOK = DoDeletePostProcessor(this, m_pLERange);
01381         if (!bOK)
01382         {
01383             FailAndExecute();
01384             // Tell the selrange that things have changed!
01385             GetApplication()->FindSelection()->Update();
01386             End();
01387             return;
01388         }
01389     }
01390 
01391     // We have finished with the range of edited nodes now so we should delete it
01392     // to reduce memory usage while this object sits on the undo/redo lists
01393     if (m_pLERange)
01394     {
01395         delete m_pLERange;
01396         m_pLERange = NULL;
01397     }
01398 
01399     // Check whether XPE's state machine ended up in the correct state
01400     if (GetPreviewQuality())
01401     {
01402         ERROR3("We would expect XPE to have ended with at least one non-preview bitmap!");
01403         SetPreviewQuality(FALSE);
01404         bRecache = TRUE;
01405     }
01406 
01407     Tool* pTool = Tool::GetCurrent();
01408 
01409     // Update the LiveEffect Tool's permanent status
01410     if (pTool->GetID()==TOOLID_LIVEEFFECT)
01411     {
01412         ((LiveEffectsTool*)pTool)->SetCurrentEffectID(m_strEffectID);
01413         ((LiveEffectsTool*)pTool)->SetCurrentStackPos(m_iStackPos);
01414     }
01415 
01416     // render blobs off for tools which don't automatically redraw their blobs.
01417     Spread* pSpread = Document::GetSelectedSpread();
01418 
01419     // invalidate the (new) region bounding the selection.
01420     if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, bRecache))
01421     {
01422         End();
01423         return;
01424     }
01425 
01426     // render blobs back on if the current tool doesn't automatically redraw its blobs.
01427     if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
01428         pTool->RenderToolBlobs(pSpread, NULL);
01429 
01430 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE);
01431 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this);
01432 ok = UpdateChangedNodes(&ObjChange);
01433 
01434     if (bBroadcast)
01435     {
01436         BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::EFFECTSTACKCHANGED));
01437     }
01438 
01439     // Tell the selrange that things have changed!
01440     GetApplication()->FindSelection()->Update();
01441 
01442     End();
01443 }

BOOL OpLiveEffect::DoLocaliseEffectAttrs UndoableOperation pOp,
Node pNode
[static, private]
 

Copy the Effect attributes from the specified node down to lower nodes, remaining effect attrs where possible but becoming normal attrs if that's not possible Used by ungroup.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/03/2005
Parameters:
pOp - pointer to op [INPUTS] pNode -
[OUTPUTS] 
Returns:
TRUE if it worked

Errors: See also:

Definition at line 1901 of file opliveeffects.cpp.

01902 {
01903     // From top of stack
01904     // find effect attr
01905     // Copy it down to children of specified node
01906     //   If node can cope with effect attr
01907     //   Then copy as effect attr
01908     //   Else
01909     //     If object already has that type of attr
01910     //     Then do nothing
01911     //     Else copy attribute into place and delete attrs in subtree
01912 
01913     ListRange* pPPStack = EffectsStack::GetEffectsStackFromNode(pNode, FALSE, TRUE, TRUE);
01914     if (pPPStack)
01915     {
01916         Node* pEffectNode = pPPStack->FindLast();
01917         while (pEffectNode)
01918         {
01919             NodeAttribute* pAttr = NodeAttribute::FindFirstAppliedAttr(pEffectNode);
01920             while (pAttr && pAttr->IsEffectAttribute() && pAttr->FindParent()==pEffectNode)
01921             {
01922                 if (!pAttr->HasEquivalentDefaultValue(TRUE))            // Only copy attr if it doesn't look like the default
01923                     DoCopyEffectAttr(pOp, pAttr, pNode);
01924 
01925                 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr);
01926             }
01927 
01928             pEffectNode = pPPStack->FindPrev(pEffectNode);
01929         }
01930     }
01931 
01932     // Finally, do the same thing for the node itself...
01933     NodeAttribute* pAttr = NodeAttribute::FindFirstAppliedAttr(pNode);
01934     while (pAttr && pAttr->IsEffectAttribute() && pAttr->FindParent()==pNode)
01935     {
01936         if (!pAttr->HasEquivalentDefaultValue(TRUE))                    // Only copy attr if it doesn't look like the default
01937             DoCopyEffectAttr(pOp, pAttr, pNode);
01938 
01939         pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr);
01940     }
01941 
01942     delete pPPStack;
01943 
01944     return TRUE;
01945 }

BOOL OpLiveEffect::DoLocaliseLiveEffects UndoableOperation pOp,
Node pNode
[static, private]
 

Copy the specified LiveEffect stack onto the selection Used by Paste Attributes.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/10/2004
Parameters:
pPPStack - pointer to EffectsStack to copy [INPUTS]
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 1803 of file opliveeffects.cpp.

01804 {
01805     ListRange* pPPStack = EffectsStack::GetEffectsStackFromNode(pNode, FALSE, TRUE, TRUE);
01806     if (pPPStack==NULL)
01807         return TRUE;
01808 
01809     NodeRenderableInk* pChild = pNode->FindFirstChildInk();
01810     while (pChild)
01811     {
01812         NodeRenderableInk* pNextChild = pChild->FindNextInk();
01813 
01814         // Don't localise into "controlled" nodes
01815         if (pChild->GetParentController()==NULL)
01816         {
01817             NodeRenderableInk* pInsertContext = pChild;
01818             NodeBitmapEffect* pLENode = (NodeBitmapEffect*)pPPStack->FindFirst();
01819             ERROR2IF(!pLENode->CanBeUnlocked(), FALSE, "Can't localise Destructive effects");
01820             while (pLENode)
01821             {
01822                 // Make a copy of this LiveEffect
01823                 NodeBitmapEffect* pCopy = NULL;
01824                 BOOL bOK = FALSE;
01825                 CALL_WITH_FAIL(pCopy = (NodeBitmapEffect*)pLENode->SimpleCopy(), pOp, bOK);
01826                 if (!bOK) return FALSE; // No room to take a copy of the node
01827 
01828                 // Can't insert directly as parent because of restrictions with HiddenNode
01829                 // So insert as sibling and then move context node into sibling
01830                 bOK = pOp->DoInsertNewNode(pCopy, pInsertContext, NEXT, TRUE, FALSE, FALSE, FALSE);
01831                 if (!bOK) return FALSE;
01832 
01833                 bOK = pOp->DoMoveNode(pInsertContext, pCopy, FIRSTCHILD);
01834                 if (!bOK) return FALSE;
01835 
01836                 pInsertContext = pCopy;
01837 
01838                 // Copy any necessary children of the LiveEffect
01839                 // This could be much more developed, possibly using a virtual function
01840                 // on the node that's just been copied to copy it's necessary parts
01841                 // or ComplexCopy
01842                 // But this works well enough for now (NodeShadowControllers and NodeShadows)
01843                 Node* pNode = pLENode->FindFirstChild();
01844                 AttachNodeDirection dir = FIRSTCHILD;
01845                 while (pNode)
01846                 {
01847                     if (pNode->NeedsParent(pNode->FindParent()) && pNode->IsBounded())
01848                     {
01849                         // Make a copy of this "Needed" node
01850                         NodeRenderableBounded* pCopy = NULL;
01851                         BOOL bOK = FALSE;
01852                         CALL_WITH_FAIL(pNode->NodeCopy((Node**)&pCopy), pOp, bOK);      // Copy node and subtree
01853                         if (!bOK) return FALSE; // No room to take a copy of the node
01854 
01855                         bOK = pOp->DoInsertNewNode(pCopy, pInsertContext, dir, TRUE, FALSE, FALSE, FALSE);
01856                         if (!bOK) return FALSE;
01857                     }
01858 
01859                     pNode = pNode->FindNext();
01860                 }
01861 
01862                 pLENode = (NodeBitmapEffect*)pPPStack->FindNext(pLENode);
01863             }
01864         }
01865 
01866         pChild = pNextChild;
01867     }
01868 
01869     delete pPPStack;
01870 
01871     //-----------------------------------------------------------------------------
01872     // Remove all current LiveEffects on the selection
01873     //
01874     if (pNode->IsAnObject())
01875         return (OpLiveEffect::DoDeleteAllPostProcessors(pOp, (NodeRenderableInk*)pNode)!=NULL);
01876     else
01877         return TRUE;
01878 }

void OpLiveEffect::DoWithParam OpDescriptor pOpDesc,
OpParam pOpParam
[virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/06/2005
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Reimplemented from Operation.

Reimplemented in OpApplyLiveEffect, and OpApplyFeatherEffect.

Definition at line 2487 of file opliveeffects.cpp.

02488 {
02489     BOOL ok = FALSE;
02490 
02491     OpLiveEffectParam* pLEOpParam = NULL;
02492     if (pOpParam && pOpParam->IsKindOf(CC_RUNTIME_CLASS(OpLiveEffectParam)))
02493         pLEOpParam = (OpLiveEffectParam*) pOpParam;
02494 
02495     if (!CheckEffectOpParam(pLEOpParam))
02496     {
02497         End();
02498         return;
02499     }
02500 
02501     // Remember some details for later on when the Op ends successfully (?)
02502     if (pLEOpParam)
02503     {
02504         m_strEffectID = pLEOpParam->strOpUnique;
02505         m_iStackPos = pLEOpParam->StackPosition;
02506     }
02507 
02508     // obtain the current selection.
02509     Range Sel(*(GetApplication()->FindSelection()));
02510     RangeControl rc = Sel.GetRangeControlFlags();
02511     rc.PromoteToParent = TRUE;
02512     Sel.Range::SetRangeControl(rc);
02513 
02514     if (!AllowEmptySelection() && Sel.FindFirst()==NULL)
02515     {
02516         End();
02517         return;
02518     }
02519 
02520     // render blobs off for tools which don't automatically redraw their blobs.
02521     Tool* pTool = Tool::GetCurrent();
02522     Spread* pSpread = Document::GetSelectedSpread();
02523     if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
02524         pTool->RenderToolBlobs(pSpread, NULL);
02525 
02526     // record the current selection state and if required, render off any selection blobs.
02527     if (!DoStartSelOp(FALSE, FALSE))
02528     {
02529         End();
02530         return;
02531     }
02532 
02533 // Ask the range whether it's OK to do the transform...
02534 // Get an ObjChangeParam ready, so we can ask op permission from nodes.
02535 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE);  // ReplaceNode & RegenerateNode
02536 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, this);
02537 BOOL bOK = Sel.AllowOp(&ObjChange);
02538 if (!bOK)
02539 {
02540     End();
02541     return;
02542 }
02543 
02544     // invalidate the region bounding the selection.
02545     if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE, FALSE))
02546     {
02547         End();
02548         return;
02549     }
02550 
02551     // Get a list of the LiveEffects we will be working on
02552     ListRange* pLERange = NULL;
02553     if (pLEOpParam && pLEOpParam->pPPStack)
02554     {
02555         pLERange = pLEOpParam->pPPStack->GetLevelRange(&pLEOpParam->StackPosition); // We don't own the returned range
02556         // Make a local copy in case the original dies during selection processing
02557         if (pLERange)
02558             pLERange = new ListRange(pLERange);
02559     }
02560     m_bAppliedNewEffects = FALSE;
02561 
02562     // -------------------------------------------------------------------
02563     // Call virtual function of derived Ops to do the specialised function
02564     BOOL bEndNormally = DoEffectOp(pLERange, pLEOpParam);
02565     // -------------------------------------------------------------------
02566 
02567     if (pLERange)
02568     {
02569         delete pLERange;
02570         pLERange = NULL;
02571     }
02572 
02573     if (bEndNormally)
02574     {
02575         // invalidate the (new) region bounding the selection.
02576         if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, FALSE))
02577         {
02578             End();
02579             return;
02580         }
02581 
02582         // render blobs back on if the current tool doesn't automatically redraw its blobs.
02583         if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
02584             pTool->RenderToolBlobs(pSpread, NULL);
02585 
02586 ObjChangeFlags cFlags(NULL, TRUE, NULL, NULL, NULL, NULL, NULL, TRUE);
02587 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this);
02588 BOOL ok = UpdateChangedNodes(&ObjChange);
02589 
02590         BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::EFFECTSTACKCHANGED)); 
02591 
02592         // Tell the selrange that things have changed!
02593         GetApplication()->FindSelection()->Update();
02594 
02595         End();
02596     }
02597 }

BOOL OpLiveEffect::EnsureLiveEffectOriginalBitmaps  )  [protected]
 

Ensure that all NodeBitmapEffects in the current selection have original bitmaps ready and wait for us to pick up.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/09/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 949 of file opliveeffects.cpp.

00950 {
00951     if (m_pLERange==NULL)
00952         return TRUE;
00953 
00954     BOOL bRenderingNeeded = FALSE;
00955     DocView* pDocView = DocView::GetSelected();
00956 
00957     bRenderingNeeded = FALSE;
00958     Node* pNode = m_pLERange->FindFirst();
00959     while (pNode)
00960     {
00961         ENSURE(pNode->IsBitmapEffect(), "LiveEffects list contains non-LiveEffect in EnsureLiveEffectOriginalBitmaps");
00962         NodeBitmapEffect* pLE = (NodeBitmapEffect*)pNode;
00963         if (!pLE->GetOriginalBitmap(NULL, NULL, NULL) && pLE->CanGenerateBitmap())
00964         {
00965             // We need to forcibly render this node to get its original
00966             // bitmap set up
00967             //
00968             // Version2 Bitmap Generation
00969             //
00970             // Grab bitmap without using on screen rendering
00971             // This is more efficient than rendering the whole tree and 
00972             // allows parameters to be controlled independently from screen view
00973             //
00974             // Ideally:
00975             // Start a render into a RenderRegion
00976             // Don't allow the RenderRegion to grab bitmap of its own - NOT DONE
00977             // Don't allow the RenderRegion to blit captures into it's own bitmap - NOT DONE
00978             // Ensure only the effect and it's children are rendered - DONE!
00979             // Just let the effect rendering functions create their capture bitmap - DONE!
00980 
00981             // Create a new GRenderDIB region
00982             // Most of the parameters here are immaterial because we are not really
00983             // interested in the results of the rendered region - just the capture
00984             pLE->ReleaseCached(TRUE, FALSE);                            // We will change so tell parents to uncache
00985 
00986             // Bodge? Ensure that locked effects will render their children
00987             // because they don't respond to ReleaseCached...
00988             if (pLE->IsLockedEffect())
00989                 pLE->SetProcessedBitmap(NULL, NULL, DocRect(), 0, 0, 0, 0);
00990 
00991             View* pView = View::GetCurrent();
00992             Spread* pSpread = Document::GetSelectedSpread();
00993             Matrix Mat = pView->ConstructScaledRenderingMatrix(pSpread, 1.0);
00994             FIXED16 Scale;
00995             Mat.Decompose(&Scale);
00996             double dpi = 0.0;   // use screen dpi (ie PIXELS_PER_INCH)
00997             GRenderDIB* pNewGRR = new GRenderDIB(pLE->GetBoundingRect(), Mat, Scale, 32, dpi);
00998             ERROR2IF(pNewGRR == NULL, FALSE, "Failed to create a GRenderDIB!");
00999 
01000             // State flags + pixel width calculations
01001             if (!pNewGRR->AttachDevice(pView, NULL, pSpread))       // view and spread from previous RR rather than Current - nb in create bitmap copy case
01002             {
01003                 ERROR3("Cannot attach devices");
01004                 
01005                 delete pNewGRR;
01006                 pNewGRR = NULL;
01007                 
01008                 return FALSE;
01009             }
01010 
01011             pNewGRR->m_DoCompression = FALSE;
01012             pNewGRR->InitDevice();
01013             pNewGRR->InitAttributes();
01014             pNewGRR->SetLineAttributes();
01015             pNewGRR->SetFillAttributes();
01016             pNewGRR->SetBackmostChangedNode(pSpread);       // Don't allow any cached 24BPP bitmaps to be used!
01017 
01018             // NB following call gets GRendRegion to create the bitmap into which GDraw will render
01019             BOOL Started = pNewGRR->StartRender();
01020 
01021             if (Started)
01022             {
01023                 // Setup attribute state outside this subtree
01024                 CCAttrMap* pAttrMap = new CCAttrMap;
01025                 if (pAttrMap!=NULL)
01026                 {
01027                     pLE->FindAppliedAttributes(pAttrMap, 5000, NULL, FALSE, FALSE);
01028                     pAttrMap->Render(pNewGRR);
01029                     delete pAttrMap;
01030                 }
01031 
01032                 // This is the important bit - force top quality rendering
01033                 // so that effects capture is done properly regardless of 
01034                 // the current document/view quality
01035                 pNewGRR->RRQuality.SetQuality(QUALITY_MAX);
01036                 pNewGRR->SetQualityLevel();
01037 
01038                 pNewGRR->SetImmediateRender(TRUE);
01039 
01040                 pNewGRR->RenderTree(pLE, FALSE, FALSE);
01041                 pNewGRR->StopRender();
01042 
01043             }
01044 
01045             // Sanity check
01046             // We really should have generated an original bitmap by now!
01047             ERROR2IF(!pLE->GetOriginalBitmap(NULL, NULL, NULL), FALSE, "EnsureLiveEffectOriginalBitmaps failed to generate an original bitmap");
01048 
01049             delete pNewGRR;
01050             pNewGRR = NULL;
01051         }
01052 
01053         pNode = m_pLERange->FindNext(pNode);
01054     }
01055 
01056     return TRUE;
01057 }

BOOL OpLiveEffect::GenerateBitmap NodeBitmapEffect pBitmapEffect,
double  dResolution,
LPBITMAPINFO ppInfo,
LPBYTE ppBits,
DocRect prectBounds
[protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/06/2005
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 1080 of file opliveeffects.cpp.

01085 {
01086     // We need to forcibly render this node to get its original
01087     // bitmap set up
01088     //
01089     // Version2 Bitmap Generation
01090     //
01091     // Grab bitmap without using on screen rendering
01092     // This is more efficient than rendering the whole tree and 
01093     // allows parameters to be controlled independently from screen view
01094     //
01095     // Ideally:
01096     // Start a render into a RenderRegion
01097     // Don't allow the RenderRegion to grab bitmap of its own - NOT DONE
01098     // Don't allow the RenderRegion to blit captures into it's own bitmap - NOT DONE
01099     // Ensure only the effect and it's children are rendered - DONE!
01100     // Just let the effect rendering functions create their capture bitmap - DONE!
01101 
01102     // Create a new GRenderDIB region
01103     // Most of the parameters here are immaterial because we are not really
01104     // interested in the results of the rendered region - just the capture
01105     View* pView = View::GetCurrent();
01106     Spread* pSpread = Document::GetSelectedSpread();
01107     Matrix Mat = pView->ConstructScaledRenderingMatrix(pSpread, 1.0);
01108     FIXED16 Scale;
01109     Mat.Decompose(&Scale);
01110     GRenderDIB* pNewGRR = new GRenderDIB(pBitmapEffect->GetBoundingRect(), Mat, Scale, 32, dResolution);
01111     ERROR2IF(pNewGRR == NULL, FALSE, "Failed to create a GRenderDIB!");
01112 
01113     // State flags + pixel width calculations
01114     if (!pNewGRR->AttachDevice(pView, NULL, pSpread))       // view and spread from previous RR rather than Current - nb in create bitmap copy case
01115     {
01116         ERROR3("Cannot attach devices");
01117         
01118         delete pNewGRR;
01119         pNewGRR = NULL;
01120         
01121         *ppInfo = NULL;
01122         *ppBits = NULL;
01123 
01124         *prectBounds = DocRect();
01125 
01126         return FALSE;
01127     }
01128 
01129     pNewGRR->m_DoCompression = TRUE;            // We do want transparency
01130     pNewGRR->InitDevice();
01131     pNewGRR->InitAttributes();
01132     pNewGRR->SetLineAttributes();
01133     pNewGRR->SetFillAttributes();
01134 
01135     // NB following call gets GRendRegion to create the bitmap into which GDraw will render
01136     BOOL Started = pNewGRR->StartRender();
01137 
01138     if (Started)
01139     {
01140         // Setup attribute state outside this subtree
01141         CCAttrMap* pAttrMap = new CCAttrMap;
01142         if (pAttrMap!=NULL)
01143         {
01144             pBitmapEffect->FindAppliedAttributes(pAttrMap, 5000, NULL, FALSE, FALSE);
01145             pAttrMap->Render(pNewGRR);
01146             delete pAttrMap;
01147         }
01148 
01149         // This is the important bit - force top quality rendering
01150         // so that effects capture is done properly regardless of 
01151         // the current document/view quality
01152         pNewGRR->RRQuality.SetQuality(QUALITY_MAX);
01153         pNewGRR->SetQualityLevel();
01154 
01155         pNewGRR->RenderTree(pBitmapEffect, FALSE, FALSE);
01156         pNewGRR->StopRender();
01157     }
01158 
01159     *prectBounds = pNewGRR->GetClipRect();          // Get pixel-aligned rect
01160     pNewGRR->GetBitmapPointers(ppInfo, ppBits);     // Get the bitmap data out of the region, converting T channel
01161     pNewGRR->SetBitmapPointers(NULL, NULL);         // We own the bitmap now, it will not be deallocated by
01162                                                     // the following renderegion deleteion
01163     delete pNewGRR;
01164     pNewGRR = NULL;
01165 
01166     return TRUE;
01167 }

ListRange* OpLiveEffect::GetLiveEffectList  )  [inline]
 

Definition at line 275 of file opliveeffects.h.

00275 {return m_pLERange;}

BOOL OpLiveEffect::GetPreviewQuality  )  const [inline]
 

Definition at line 280 of file opliveeffects.h.

00280 {return m_bPreviewQuality;}

BOOL OpLiveEffect::HasChanged  )  [protected]
 

Detect whether any of the LiveEffect nodes created/edited by this operation have actually been changed/do anything useful...

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/09/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:
TRUE if any of the nodes in the liveeffects list have changed since this operation started FALSE otherwise

Errors: See also:

Definition at line 1225 of file opliveeffects.cpp.

01226 {
01227     if (m_pLERange==NULL)
01228         return FALSE;
01229 
01230     Node* pNode = m_pLERange->FindFirst();
01231     while (pNode)
01232     {
01233         ENSURE(pNode->IsBitmapEffect(), "LiveEffects list contains non-LiveEffect in EnsureLiveEffectOriginalBitmaps");
01234         NodeBitmapEffect* pLE = (NodeBitmapEffect*)pNode;
01235 
01236         if (pLE->HasChanged())
01237             return TRUE;
01238 
01239         pNode = m_pLERange->FindNext(pNode);
01240     }
01241 
01242     return FALSE;
01243 }

BOOL OpLiveEffect::Init void   )  [static, private]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Reimplemented from SimpleCCObject.

Definition at line 214 of file opliveeffects.cpp.

00215 {
00216     BOOL bOK = TRUE;
00217     // Use an ParamOpDescriptor to allow OpApplyLiveEffect to receive extra information
00218     // about the menu item that invoked it...
00219     ParamOpDescriptor* pOD = NULL;
00220     pOD = new ParamOpDescriptor(OPTOKEN_APPLY_LIVEEFFECT,
00221                                 CC_RUNTIME_CLASS(OpApplyLiveEffect),
00222                                 OpApplyLiveEffect::GetParamState);
00223     bOK = bOK && (pOD!=NULL);
00224 
00225     pOD = new ParamOpDescriptor(OPTOKEN_EDIT_LIVEEFFECT,
00226                                 CC_RUNTIME_CLASS(OpEditLiveEffect),
00227                                 OpEditLiveEffect::GetParamState);
00228     bOK = bOK && (pOD!=NULL);
00229 
00230     pOD = new ParamOpDescriptor(OPTOKEN_EDIT_LEGACYEFFECT,
00231                                 CC_RUNTIME_CLASS(OpEditLegacyEffect),
00232                                 OpEditLegacyEffect::GetParamState);
00233     bOK = bOK && (pOD!=NULL);
00234 
00235 #ifdef FEATHER_EFFECT
00236     pOD = new ParamOpDescriptor(OPTOKEN_APPLY_FEATHEREFFECT,
00237                                 CC_RUNTIME_CLASS(OpApplyFeatherEffect),
00238                                 OpApplyFeatherEffect::GetParamState);
00239     bOK = bOK && (pOD!=NULL);
00240 #endif
00241 
00242 /*  bOK = bOK && RegisterOpDescriptor(0,                                // Tool ID
00243                                     _R(IDS_EDIT_LIVEEFFECT),                // String resource ID
00244                                     CC_RUNTIME_CLASS(OpEditLiveEffect), // Runtime class
00245                                     OPTOKEN_EDIT_LIVEEFFECT,            // Token string
00246                                     OpEditLiveEffect::GetState,     // GetState function
00247                                     0,                              // Help ID
00248                                     _R(IDBBL_EDIT_LIVEEFFECT),          // Bubble ID
00249                                     0,                              // Resource ID
00250                                     0,                              // Control ID
00251                                     SYSTEMBAR_ILLEGAL,              // Bar ID
00252                                     TRUE,                           // Receive system messages
00253                                     FALSE,                          // Smart duplicate operation
00254                                     FALSE,                          // Clean operation
00255                                     0,                              // No vertical counterpart
00256                                     GREY_WHEN_NO_CURRENT_DOC |
00257                                     DONT_GREY_WHEN_SELECT_INSIDE);  // automatic state checking.
00258 */
00259     bOK = bOK && RegisterOpDescriptor(0,                                // Tool ID
00260                                     _R(IDS_DELETE_LIVEEFFECT),              // String resource ID
00261                                     CC_RUNTIME_CLASS(OpDeleteLiveEffect),   // Runtime class
00262                                     OPTOKEN_DELETE_LIVEEFFECT,          // Token string
00263                                     OpDeleteLiveEffect::GetState,       // GetState function
00264                                     0,                              // Help ID
00265                                     _R(IDBBL_DELETE_LIVEEFFECT),            // Bubble ID
00266                                     0,                              // Resource ID
00267                                     0,                              // Control ID
00268                                     SYSTEMBAR_ILLEGAL,              // Bar ID
00269                                     TRUE,                           // Receive system messages
00270                                     FALSE,                          // Smart duplicate operation
00271                                     FALSE,                          // Clean operation
00272                                     0,                              // No vertical counterpart
00273                                     GREY_WHEN_NO_CURRENT_DOC |
00274                                     DONT_GREY_WHEN_SELECT_INSIDE);  // automatic state checking.
00275 
00276     bOK = bOK && RegisterOpDescriptor(0,                                // Tool ID
00277                                     _R(IDS_DELETEALL_LIVEEFFECT),               // String resource ID
00278                                     CC_RUNTIME_CLASS(OpDeleteAllLiveEffect),    // Runtime class
00279                                     OPTOKEN_DELETEALL_LIVEEFFECT,           // Token string
00280                                     OpDeleteAllLiveEffect::GetState,        // GetState function
00281                                     0,                              // Help ID
00282                                     _R(IDBBL_DELETEALL_LIVEEFFECT),         // Bubble ID
00283                                     0,                              // Resource ID
00284                                     0,                              // Control ID
00285                                     SYSTEMBAR_ILLEGAL,              // Bar ID
00286                                     TRUE,                           // Receive system messages
00287                                     FALSE,                          // Smart duplicate operation
00288                                     FALSE,                          // Clean operation
00289                                     0,                              // No vertical counterpart
00290                                     GREY_WHEN_NO_CURRENT_DOC |
00291                                     DONT_GREY_WHEN_SELECT_INSIDE);  // automatic state checking.
00292 
00293     bOK = bOK && RegisterOpDescriptor(0,                                // Tool ID
00294                                     _R(IDS_CHANGE_EFFECT_RES),              // String resource ID
00295                                     CC_RUNTIME_CLASS(OpEffectRes),  // Runtime class
00296                                     OPTOKEN_CHANGE_EFFECT_RES,          // Token string
00297                                     OpEffectRes::GetState,      // GetState function
00298                                     0,                              // Help ID
00299                                     _R(IDBBL_CHANGE_EFFECT_RES),            // Bubble ID
00300                                     0,                              // Resource ID
00301                                     0,                              // Control ID
00302                                     SYSTEMBAR_ILLEGAL,              // Bar ID
00303                                     TRUE,                           // Receive system messages
00304                                     FALSE,                          // Smart duplicate operation
00305                                     FALSE,                          // Clean operation
00306                                     0,                              // No vertical counterpart
00307                                     GREY_WHEN_NO_CURRENT_DOC |
00308                                     DONT_GREY_WHEN_SELECT_INSIDE);  // automatic state checking.
00309 
00310     bOK = bOK && RegisterOpDescriptor(0,                                // Tool ID
00311                                     _R(IDS_CHANGE_EFFECT_LOCK),             // String resource ID
00312                                     CC_RUNTIME_CLASS(OpEffectLock), // Runtime class
00313                                     OPTOKEN_CHANGE_EFFECT_LOCK,         // Token string
00314                                     OpEffectLock::GetState,     // GetState function
00315                                     0,                              // Help ID
00316                                     _R(IDBBL_CHANGE_EFFECT_LOCK),           // Bubble ID
00317                                     0,                              // Resource ID
00318                                     0,                              // Control ID
00319                                     SYSTEMBAR_ILLEGAL,              // Bar ID
00320                                     TRUE,                           // Receive system messages
00321                                     FALSE,                          // Smart duplicate operation
00322                                     FALSE,                          // Clean operation
00323                                     0,                              // No vertical counterpart
00324                                     GREY_WHEN_NO_CURRENT_DOC |
00325                                     DONT_GREY_WHEN_SELECT_INSIDE);  // automatic state checking.
00326 
00327     bOK = bOK && RegisterOpDescriptor(0,                                // Tool ID
00328                                     _R(IDS_CHANGE_EFFECT_LOCKALL),              // String resource ID
00329                                     CC_RUNTIME_CLASS(OpEffectLockAll),  // Runtime class
00330                                     OPTOKEN_CHANGE_EFFECT_LOCKALL,          // Token string
00331                                     OpEffectLockAll::GetState,      // GetState function
00332                                     0,                              // Help ID
00333                                     _R(IDBBL_CHANGE_EFFECT_LOCKALL),            // Bubble ID
00334                                     0,                              // Resource ID
00335                                     0,                              // Control ID
00336                                     SYSTEMBAR_ILLEGAL,              // Bar ID
00337                                     TRUE,                           // Receive system messages
00338                                     FALSE,                          // Smart duplicate operation
00339                                     FALSE,                          // Clean operation
00340                                     0,                              // No vertical counterpart
00341                                     GREY_WHEN_NO_CURRENT_DOC |
00342                                     DONT_GREY_WHEN_SELECT_INSIDE);  // automatic state checking.
00343 
00344     return bOK;
00345 }

BOOL OpLiveEffect::IsTopOfStack EffectsStack pPPStack,
INT32  iStackPos
[protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/10/2004
Parameters:
iStackPos - position in LiveEffect stack to find nodes [INPUTS] 0 means first stack pos above selection
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 926 of file opliveeffects.cpp.

00927 {
00928     return (iStackPos>=(INT32)pPPStack->GetCount());
00929 }

BOOL OpLiveEffect::SetChanged BOOL  bNewState  )  [protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/09/2004
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 1186 of file opliveeffects.cpp.

01187 {
01188     if (m_pLERange==NULL)
01189         return TRUE;
01190 
01191     Node* pNode = m_pLERange->FindFirst();
01192     while (pNode)
01193     {
01194         ENSURE(pNode->IsBitmapEffect(), "LiveEffects list contains non-LiveEffect in EnsureLiveEffectOriginalBitmaps");
01195         NodeBitmapEffect* pLE = (NodeBitmapEffect*)pNode;
01196 
01197         pLE->SetChanged(bNewState);
01198 
01199         pNode = m_pLERange->FindNext(pNode);
01200     }
01201 
01202     return TRUE;
01203 }

void OpLiveEffect::SetPreviewQuality BOOL  bNew  )  [inline]
 

Definition at line 281 of file opliveeffects.h.

00281 {m_bPreviewQuality = bNew;}

BOOL OpLiveEffect::UpdateCurrentEditor  )  [static, private]
 

Reset the current Op to refer to the new PPStack and tell the running XPE edit that things are changing.

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

Definition at line 1258 of file opliveeffects.cpp.

01259 {
01260     OpLiveEffect* pCurrentOp = XPEHost::GetCurrentLEOp();
01261 
01262     // If we haven't got a list of editors yet then get one
01263     if (pCurrentOp==NULL)
01264         return FALSE;
01265 
01266     // TODO: May need to force a redraw if the current op is in preview mode at the moment
01267     ENSURE(pCurrentOp->GetPreviewQuality()==FALSE, "We can't leave the bitmaps in the tree in preview mode!");
01268 
01269     // Read the current op's details...
01270     String_256 strEffectID = pCurrentOp->m_strEffectID;
01271     INT32 iStackPos = pCurrentOp->m_iStackPos;
01272 
01273     // Stop the current Op and commit all of its changes
01274     // Disconnect it from the XPE system so that, just for the moment at least, other routines
01275     // think that there's no running edit session
01276     pCurrentOp->DoEndEdit(TRUE, TRUE);              // Sends ScreenChangeMsg - and thus releases pPPStack
01277     XPEHost::SetCurrentLEOp(NULL);                  // Tells UpdateCurrentEditor not to try to update dying editor
01278 
01279     // Reset pPPStack in LiveEffectTool to reset the Tool after the ScreenChangeMsg sent above
01280     // (prevent idle handler looping forever calling this function)
01281     EffectsStack* pPPStack = EffectsStack::GetEffectsStackFromSelection();
01282 
01283     // Try to find the same effect in the new stack
01284     // If found then invoke a new Op to use the running editor on that effect
01285     BOOL bOK = pPPStack->FindBestProcessor(&strEffectID, &iStackPos);
01286 
01287     // Decide which sort of Operation we need to use instead...
01288     OpDescriptor* pOp = NULL;
01289     if (bOK)
01290     {
01291         // We found the right sort of Effect in the stack so we'll just edit that
01292         pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_EDIT_LIVEEFFECT);
01293     }
01294     else
01295     {
01296         // We didn't find the right sort of effect so we'll apply a brand new one!
01297         // At the top of the stack
01298         pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_APPLY_LIVEEFFECT);
01299         iStackPos = STACKPOS_INSERT_TOP;
01300     }
01301 
01302     // Start a new Op but tell it to use the existing edit session instead of making a new one
01303     if (pOp)
01304     {
01305         OpLiveEffectParam Param;
01306         Param.strOpUnique = strEffectID;
01307         Param.StackPosition = iStackPos;
01308         Param.pPPStack = pPPStack;
01309         Param.bReUseEditor = TRUE;              // This is the important param!
01310         BOOL bValid = XPEHost::GetEffectDetails(strEffectID, &Param.strMenuText, &Param.bIsDestructive);
01311 
01312         String_256 strDummy;
01313         if (bValid && pOp->GetOpsState(&strDummy).Greyed==FALSE)
01314         {
01315             pOp->Invoke(&Param);
01316 
01317             // Reset the Tool's current stack pointer now so that it doesn't need
01318             // to be updated under idle events with the consequent call to this function
01319             // and infinite loop...
01320             Tool* pTool = Tool::GetCurrent();
01321             if (pTool->GetID()==TOOLID_LIVEEFFECT)
01322                 ((LiveEffectsTool*)pTool)->UpdatePPStack(FALSE);
01323 
01324             // If that successfully set up a new editor op then we're fine to carry on
01325             if (XPEHost::GetCurrentLEOp()!=NULL)
01326             {
01327                 delete pPPStack;
01328                 return TRUE;
01329             }
01330         }
01331     }
01332 
01333     // If we get here then we must have failed in some way so close down the running editor
01334     XPEHost::EndEditLiveEffect();
01335     delete pPPStack;
01336     return FALSE;
01337 }


Member Data Documentation

BOOL OpLiveEffect::m_bAppliedNewEffects [protected]
 

Definition at line 314 of file opliveeffects.h.

BOOL OpLiveEffect::m_bPreviewQuality [protected]
 

Definition at line 317 of file opliveeffects.h.

INT32 OpLiveEffect::m_iStackPos [protected]
 

Definition at line 316 of file opliveeffects.h.

ListRange* OpLiveEffect::m_pLERange [protected]
 

Definition at line 313 of file opliveeffects.h.

String_256 OpLiveEffect::m_strEffectID [protected]
 

Definition at line 315 of file opliveeffects.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:58:23 2007 for Camelot by  doxygen 1.4.4