OpApplyClipView Class Reference

Operation to apply ClipView to the selection. See also:. More...

#include <opclip.h>

Inheritance diagram for OpApplyClipView:

SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 OpApplyClipView ()
 Constructor.
 ~OpApplyClipView ()
 Destructor.
virtual void GetOpName (String_256 *pstrOpName)
virtual void Do (OpDescriptor *pOpDesc)
virtual BOOL MayChangeNodeBounds () const

Static Public Member Functions

static BOOL Init ()
static OpState GetState (String_256 *pstrDescription, OpDescriptor *pOpDesc)

Private Member Functions

 CC_DECLARE_DYNCREATE (OpApplyClipView)

Detailed Description

Operation to apply ClipView to the selection. See also:.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01 February 2000

Definition at line 120 of file opclip.h.


Constructor & Destructor Documentation

OpApplyClipView::OpApplyClipView  ) 
 

Constructor.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01 February 2000
Returns:
Errors: See also:

Definition at line 132 of file opclip.cpp.

00133 {
00134     // empty.
00135 }

OpApplyClipView::~OpApplyClipView  ) 
 

Destructor.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01 February 2000
Returns:
Errors: See also:

Definition at line 150 of file opclip.cpp.

00151 {
00152     // empty.
00153 }


Member Function Documentation

OpApplyClipView::CC_DECLARE_DYNCREATE OpApplyClipView   )  [private]
 

void OpApplyClipView::Do OpDescriptor pOpDesc  )  [virtual]
 

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01 February 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Reimplemented from Operation.

Definition at line 288 of file opclip.cpp.

00289 {
00290     // obtain the current selection.
00291     Range Sel(*(GetApplication()->FindSelection()));
00292     RangeControl rc = Sel.GetRangeControlFlags();
00293     rc.PromoteToParent = TRUE;
00294     Sel.Range::SetRangeControl(rc);
00295 
00296     // check that at least two nodes are selected.
00297     Node* pNode = NULL;
00298     Node* pFirstNode = Sel.FindFirst();
00299     if (pFirstNode != NULL)
00300         pNode = Sel.FindNext(pFirstNode);
00301         
00302     if (pFirstNode == NULL || pNode == NULL)
00303     {
00304         ERROR3("OpApplyClipView invoked with less than two selected nodes. This should never occur.");
00305         End();
00306         return;
00307     }
00308 
00309     // render blobs off for tools which don't automatically redraw their blobs.
00310     Tool* pTool = Tool::GetCurrent();
00311     Spread* pSpread = Document::GetSelectedSpread();
00312     if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
00313         pTool->RenderToolBlobs(pSpread, NULL);
00314 
00315     // record the current selection state and if required, render off any selection blobs.
00316     if (!DoStartSelOp(FALSE, FALSE))
00317     {
00318         End();
00319         return;
00320     }
00321 
00322     // invalidate the region bounding the selection.
00323     // the commented code doesn't do the job properly (doesn't tackle undo)
00324     // though it should - I get the feeling I'm not using it correctly.
00325     // so we'll just have to invalidate the selection node by node.
00326 //  if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE))
00327 //  {
00328 //      End();
00329 //      return;
00330 //  }
00331     Node* pSelNode = Sel.FindFirst();
00332     while (pSelNode != NULL)
00333     {
00334         if (pSelNode->IsAnObject())
00335         {
00336             if (!DoInvalidateNodeRegion((NodeRenderableInk*)pSelNode, TRUE))
00337             {
00338                 End();
00339                 return;
00340             }
00341         }
00342         pSelNode = Sel.FindNext(pSelNode);
00343     }
00344 
00345     // we need to insert the controller node at the position of the highest
00346     // selected node in the z-order, ie last in the selection, so find it.
00347     Node* pLastNode = NULL;
00348     while (pNode != NULL)
00349     {
00350         pLastNode = pNode;
00351         pNode = Sel.FindNext(pLastNode);
00352     }   // loop terminates with pNode == NULL, pLastNode == last-node-in-sel.
00353 
00354     // create a new NodeClipViewController, which we will shortly insert into the tree;
00355     // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong.
00356     NodeClipViewController* pClipViewController = NULL;
00357     ALLOC_WITH_FAIL(pClipViewController, new NodeClipViewController, this);
00358     BOOL ok = (pClipViewController != NULL);
00359 
00360     // put an action to hide the NodeClipViewController onto the undo action-list,
00361     // so that if the user presses undo then it will be hidden.
00362     if (ok)
00363     {
00364         HideNodeAction* pUndoHideNodeAction = NULL;
00365         ActionCode ac = HideNodeAction::Init(this,
00366                                             &UndoActions,
00367                                             pClipViewController,
00368                                             FALSE,      // don't include subtree size
00369                                             (Action**)&pUndoHideNodeAction,
00370                                             FALSE);     // don't tell subtree when undone
00371         if (ac == AC_FAIL)
00372         {
00373             delete pClipViewController;
00374             End();
00375             return;
00376         }
00377         else
00378         {
00379             // right! we've got our node, we've got our action - lets stick it in the tree
00380             // (at a position just next to the last node which will go in the group).
00381             pClipViewController->AttachNode(pLastNode, NEXT);
00382         }
00383     }
00384 
00385     // move each item from the selection into our ClipView group,
00386     // remembering to deselect them as we go.
00387     // TODO:
00388     //  sneaky suspicion I should be putting this in a Do fn in UndoableOperation...
00389     if (ok)
00390     {
00391         pNode = Sel.FindNext(pFirstNode);               // the node we're moving now.
00392         ok = DoMoveNode(pFirstNode, pClipViewController, FIRSTCHILD);
00393         if (ok)
00394             ((NodeRenderable*)pFirstNode)->DeSelect(FALSE);
00395     }
00396 
00397     Node* pNextNode     = NULL;                         // the next node to move.
00398     Node* pAnchorNode   = pFirstNode;                   // the node we've just moved.
00399     while (ok && pNode != NULL)
00400     {
00401         // get the next node to move.
00402         pNextNode = Sel.FindNext(pNode);
00403 
00404         // now move the current node next to the anchor and deselect it.
00405         ok = DoMoveNode(pNode, pAnchorNode, NEXT);
00406         if (ok)
00407             ((NodeRenderable*)pNode)->DeSelect(FALSE);
00408 
00409         // get the new anchor node and the next node to move.
00410         pAnchorNode = pNode;
00411         pNode = pNextNode;
00412     }
00413 
00414     // try and locate a suitable candidate for a keyhole node.
00415     Node* pKeyhole = NULL;
00416     if (ok)
00417     {
00418         // now get the keyhole node, which is the first object-node child of the NCVC.
00419         pKeyhole = pClipViewController->FindFirstChild();
00420         while (pKeyhole != NULL && !pKeyhole->IsAnObject())
00421         {
00422             pKeyhole = pKeyhole->FindNext();
00423         }
00424 
00425         // doh! can't find _one_ NodeRenderableInk child! I don't know...
00426         if (pKeyhole == NULL)
00427         {
00428             ok = FALSE;
00429             ERROR2RAW("ClipViewController has no object children");
00430         }
00431     }
00432 
00433     // now attach a new NodeClipView, as the immediate NEXT-sibling of the keyhole node.
00434     NodeClipView* pClipView = NULL;
00435     if (ok)
00436     {
00437         ALLOC_WITH_FAIL(pClipView, new NodeClipView(pKeyhole, NEXT), this);
00438         ok = (pClipView != NULL);
00439     }
00440 
00441     // wow - succeeded! now all we need to do is some house-keeping.
00442     if (ok)
00443     {
00444         // tell the new NodeClipViewController that its current keyhole path is now invalid.
00445         pClipViewController->MarkKeyholeInvalid();
00446 
00447         // invalidate ours and our parent's bounding rects. our bounding rect is almost
00448         // certainly already invalid, as we haven't done anything to make it valid yet.
00449         // this is why we invalidate *both* rects - just to cover all cases.
00450         pClipViewController->InvalidateBoundingRect();
00451         Node* pParent = pClipViewController->FindParent();
00452         if (pParent != NULL && pParent->IsBounded())
00453             ((NodeRenderableBounded*)pParent)->InvalidateBoundingRect();
00454 
00455         // select the new NodeClipViewController, but don't draw any blobs yet.
00456         pClipViewController->Select(FALSE);
00457 
00458         // invalidate the region bounding the selection.
00459         if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE))
00460         {
00461             End();
00462             return;
00463         }
00464 
00465         // factor out any common attributes.
00466         if (!DoFactorOutCommonChildAttributes(pClipViewController))
00467         {
00468             End();
00469             return;
00470         }
00471         
00472         // render blobs back on if the current tool doesn't automatically redraw its blobs.
00473         if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
00474             pTool->RenderToolBlobs(pSpread, NULL);
00475     }
00476     else
00477     {
00478         FailAndExecute();
00479     }
00480 
00481     // end the operation.
00482     End();
00483 }

void OpApplyClipView::GetOpName String_256 pstrOpName  )  [virtual]
 

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01 February 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Reimplemented from Operation.

Definition at line 267 of file opclip.cpp.

00268 {
00269     *pstrOpName = String_256("ClipView Object(s)");
00270 }

OpState OpApplyClipView::GetState String_256 pstrDescription,
OpDescriptor pOpDesc
[static]
 

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01 February 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Definition at line 207 of file opclip.cpp.

00208 {
00209     // default is an unticked, *GREYED*, on-menu state.
00210     OpState OpSt;
00211     OpSt.Greyed = TRUE;
00212     *pstrDescription = String_256(_R(IDS_CLIPVIEW_NEEDS_MULTIPLE_NODES));
00213 
00214     // obtain the app's current selection.
00215     // we want to treat bevels/contours etc. as atomic objects.
00216     Range Sel(*(GetApplication()->FindSelection()));
00217     RangeControl rc = Sel.GetRangeControlFlags();
00218     rc.PromoteToParent = TRUE;
00219     Sel.Range::SetRangeControl(rc);
00220 
00221     // is there actually anything in the selection?
00222     Node* pNode = Sel.FindFirst();
00223     if (pNode != NULL)
00224     {
00225         // yes - then is it only one node?
00226         if (Sel.FindNext(pNode) == NULL)
00227         {
00228             // yes - then if that node is a NodeClipViewController, remove ourself from the menu.
00229             if (pNode->IsANodeClipViewController())
00230             {
00231                 OpSt.RemoveFromMenu = TRUE;
00232                 pstrDescription->Empty();
00233             }
00234         }
00235 
00236         // two or more nodes - that's ok, but only if there is currently no select-inside.
00237         else if (Sel.ContainsSelectInside())
00238         {
00239             *pstrDescription = String_256(_R(IDS_GREY_WHEN_SELECT_INSIDE));
00240         }
00241         else
00242         {
00243             OpSt.Greyed = FALSE;
00244             pstrDescription->Empty();
00245         }
00246     }
00247 
00248     return OpSt;
00249 }

BOOL OpApplyClipView::Init void   )  [static]
 

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01 February 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also:

Reimplemented from SimpleCCObject.

Definition at line 171 of file opclip.cpp.

00172 {
00173     return RegisterOpDescriptor(0,                              // Tool ID
00174                                 _R(IDS_APPLY_CLIPVIEW),             // String resource ID
00175                                 CC_RUNTIME_CLASS(OpApplyClipView),  // Runtime class
00176                                 OPTOKEN_APPLY_CLIPVIEW,         // Token string
00177                                 OpApplyClipView::GetState,      // GetState function
00178                                 0,                              // Help ID
00179                                 _R(IDBBL_APPLY_CLIPVIEW),           // Bubble ID
00180                                 0,                              // Resource ID
00181                                 0,                              // Control ID
00182                                 SYSTEMBAR_ILLEGAL,              // Bar ID
00183                                 TRUE,                           // Receive system messages
00184                                 FALSE,                          // Smart duplicate operation
00185                                 FALSE,                          // Clean operation
00186                                 0,                              // No vertical counterpart
00187                                 GREY_WHEN_NO_CURRENT_DOC |
00188                                 DONT_GREY_WHEN_SELECT_INSIDE);  // automatic state checking.
00189 }

virtual BOOL OpApplyClipView::MayChangeNodeBounds  )  const [inline, virtual]
 

Reimplemented from SelOperation.

Definition at line 144 of file opclip.h.

00144 { return FALSE; }


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