/******************************************************************************************** > virtual void OpRemoveClipView::Do(OpDescriptor* pOpDesc, OpParam* pOpParam) Author: Karim_MacDonald (Xara Group Ltd) <*****@*****.**> Created: 01 February 2000 Inputs: Outputs: Returns: Purpose: Errors: See also: ********************************************************************************************/ void OpRemoveClipView::Do(OpDescriptor* pOpDesc) { // try to record the selection state. if (DoStartSelOp(FALSE, FALSE)) { // obtain the current selection. Range Sel(*(GetApplication()->FindSelection())); RangeControl rc = Sel.GetRangeControlFlags(); rc.PromoteToParent = TRUE; Sel.Range::SetRangeControl(rc); // check that the selection is one lone NodeClipViewController. BOOL ok = FALSE; Node* pFirstNode = Sel.FindFirst(); if (pFirstNode != NULL && pFirstNode->IsANodeClipViewController()) if (Sel.FindNext(pFirstNode) == NULL) ok = TRUE; // remove tool blobs and localise any common attributes. Tool* pTool = NULL; Spread* pSpread = NULL; if (ok) { // render blobs off for tools which don't automatically redraw their blobs. pTool = Tool::GetCurrent(); pSpread = Document::GetSelectedSpread(); if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) pTool->RenderToolBlobs(pSpread, NULL); // invalidate the region of screen covering the selection. DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE); // localise any common attributes. ok = DoLocaliseCommonAttributes((NodeGroup*)pFirstNode); } // deselect and hide the NCVC. NodeHidden* pHiddenNode = NULL; if (ok) { // deselect the NCVC, but don't ask for its blobs to be redrawn. ((NodeRenderable*)pFirstNode)->DeSelect(FALSE); ERROR3IF(pFirstNode->IsSelected(), "Deselect failed to deselect current node"); // hide the NodeClipViewController. ok = DoHideNode(pFirstNode, FALSE, &pHiddenNode, FALSE); ERROR3IF(!ok, "Unable to hide NodeClipViewController!"); } // hide the NCVC's NodeClipView node. if (ok) { NodeHidden* pDummy; NodeClipView* pClipView = ((NodeClipViewController*)pFirstNode)->GetClipView(); ok = DoHideNode(pClipView, FALSE, &pDummy, FALSE); ERROR3IF(!ok, "Unable to hide NodeClipView!"); } // show and select the NCVC's children. // a straight loop-over should do, as it should skip the now-hidden NodeClipView. if (ok) { // get the first child node (the NCVC's keyhole node). Node* pChildNode = pFirstNode->FindFirstChild(); if (pChildNode == NULL) TRACEUSER( "Karim", _T("OpRemoveClipView::Do(); Found an empty NodeClipViewController!\n")); // move and select the child nodes in turn. Node* pAnchorNode = pHiddenNode; Node* pNextChildNode = NULL; while (pChildNode != NULL) { // get the next child-node. pNextChildNode = pChildNode->FindNext(); // if the node is not a NodeHidden then move the node to its new location in // the tree - there is no need to render the node. if (!pChildNode->IsAnAttribute() && !pChildNode->IsNodeHidden()) { // move pChildNode to be the next-sibling of the anchor node. ok = DoMoveNode(pChildNode, pAnchorNode, NEXT); if (!ok) break; pAnchorNode = pChildNode; } // select the child node and invalidate its bounding rect, // but don't bother redrawing its blobs yet. if (pChildNode->IsAnObject()) { ((NodeRenderableInk*)pChildNode)->Select(FALSE); ((NodeRenderableInk*)pChildNode)->InvalidateBoundingRect(); ok = this->DoInvalidateNodeRegion(((NodeRenderableInk*)pChildNode), TRUE); if (!ok) break; } pChildNode = pNextChildNode; } } // render blobs back on for tools which don't automatically redraw their blobs. if (ok) { if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) pTool->RenderToolBlobs(pSpread, NULL); } // fail gracefully if things went pear-shaped. else FailAndExecute(); } End(); }
/******************************************************************************************** > void OpConvertToBitmap::Do(OpDescriptor*) Author: Will_Cowling (Xara Group Ltd) <*****@*****.**> Created: 11/6/96 Inputs: - Purpose: Convert the selection into a bitmap Errors: - SeeAlso: - ********************************************************************************************/ void OpConvertToBitmap::Do(OpDescriptor*) { // We want to include bevel/contour/shadow controller nodes in our bitmap-copy // deliberations, so set PromoteToParent on a copy of the app's SelRange. SelRange Sel(*(GetApplication()->FindSelection())); RangeControl rg = Sel.GetRangeControlFlags(); rg.PromoteToParent = TRUE; Sel.Range::SetRangeControl(rg); // Find the first node which is selected Node* CurrentNode = Sel.FindFirst(); ERROR3IF(CurrentNode == NULL, "Called ConvertToBitmap with no nodes selected"); // In the retail build it is best to do nothing if we find there are no selected nodes if (CurrentNode != NULL) // No nodes selected so End { // We need to invalidate the region if (!DoInvalidateNodesRegions(Sel, TRUE)) goto EndOperation; if (!DoStartSelOp(FALSE,FALSE)) // Try to record the selection state , don't goto EndOperation; // render the blobs though // Create a special Bitmap filter, that creates a bitmap // and puts it in the tree MakeBitmapFilter* pBitmapFilter = new MakeBitmapFilter(); if (pBitmapFilter == NULL) { FailAndExecute(); goto EndOperation; } KernelBitmap* pBitmapToCreate = NULL; if (!pBitmapFilter->DoCreateBitmap(this, Document::GetSelected(), &pBitmapToCreate)) { delete pBitmapFilter; FailAndExecute(); goto EndOperation; } if (!pBitmapFilter->InsertBitmapIntoDocument(this, pBitmapToCreate, Document::GetSelected())) { delete pBitmapToCreate; delete pBitmapFilter; FailAndExecute(); goto EndOperation; } delete pBitmapFilter; if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE)) { // We need to invalidate the region FailAndExecute(); goto EndOperation; } } EndOperation: SelRange* pRng = GetApplication()->FindSelection(); End(); }
/******************************************************************************************** > virtual void OpApplyClipView::Do(OpDescriptor* pOpDesc, OpParam* pOpParam) Author: Karim_MacDonald (Xara Group Ltd) <*****@*****.**> Created: 01 February 2000 Inputs: Outputs: Returns: Purpose: Errors: See also: ********************************************************************************************/ void OpApplyClipView::Do(OpDescriptor* pOpDesc) { // obtain the current selection. Range Sel(*(GetApplication()->FindSelection())); RangeControl rc = Sel.GetRangeControlFlags(); rc.PromoteToParent = TRUE; Sel.Range::SetRangeControl(rc); // check that at least two nodes are selected. Node* pNode = NULL; Node* pFirstNode = Sel.FindFirst(); if (pFirstNode != NULL) pNode = Sel.FindNext(pFirstNode); if (pFirstNode == NULL || pNode == NULL) { ERROR3("OpApplyClipView invoked with less than two selected nodes. This should never occur."); End(); return; } // render blobs off for tools which don't automatically redraw their blobs. Tool* pTool = Tool::GetCurrent(); Spread* pSpread = Document::GetSelectedSpread(); if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) pTool->RenderToolBlobs(pSpread, NULL); // record the current selection state and if required, render off any selection blobs. if (!DoStartSelOp(FALSE, FALSE)) { End(); return; } // invalidate the region bounding the selection. // the commented code doesn't do the job properly (doesn't tackle undo) // though it should - I get the feeling I'm not using it correctly. // so we'll just have to invalidate the selection node by node. // if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE)) // { // End(); // return; // } Node* pSelNode = Sel.FindFirst(); while (pSelNode != NULL) { if (pSelNode->IsAnObject()) { if (!DoInvalidateNodeRegion((NodeRenderableInk*)pSelNode, TRUE)) { End(); return; } } pSelNode = Sel.FindNext(pSelNode); } // we need to insert the controller node at the position of the highest // selected node in the z-order, ie last in the selection, so find it. Node* pLastNode = NULL; while (pNode != NULL) { pLastNode = pNode; pNode = Sel.FindNext(pLastNode); } // loop terminates with pNode == NULL, pLastNode == last-node-in-sel. // create a new NodeClipViewController, which we will shortly insert into the tree; // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong. NodeClipViewController* pClipViewController = NULL; ALLOC_WITH_FAIL(pClipViewController, new NodeClipViewController, this); BOOL ok = (pClipViewController != NULL); // put an action to hide the NodeClipViewController onto the undo action-list, // so that if the user presses undo then it will be hidden. if (ok) { HideNodeAction* pUndoHideNodeAction = NULL; ActionCode ac = HideNodeAction::Init(this, &UndoActions, pClipViewController, FALSE, // don't include subtree size (Action**)&pUndoHideNodeAction, FALSE); // don't tell subtree when undone if (ac == AC_FAIL) { delete pClipViewController; End(); return; } else { // right! we've got our node, we've got our action - lets stick it in the tree // (at a position just next to the last node which will go in the group). pClipViewController->AttachNode(pLastNode, NEXT); } } // move each item from the selection into our ClipView group, // remembering to deselect them as we go. // TODO: // sneaky suspicion I should be putting this in a Do fn in UndoableOperation... if (ok) { pNode = Sel.FindNext(pFirstNode); // the node we're moving now. ok = DoMoveNode(pFirstNode, pClipViewController, FIRSTCHILD); if (ok) ((NodeRenderable*)pFirstNode)->DeSelect(FALSE); } Node* pNextNode = NULL; // the next node to move. Node* pAnchorNode = pFirstNode; // the node we've just moved. while (ok && pNode != NULL) { // get the next node to move. pNextNode = Sel.FindNext(pNode); // now move the current node next to the anchor and deselect it. ok = DoMoveNode(pNode, pAnchorNode, NEXT); if (ok) ((NodeRenderable*)pNode)->DeSelect(FALSE); // get the new anchor node and the next node to move. pAnchorNode = pNode; pNode = pNextNode; } // try and locate a suitable candidate for a keyhole node. Node* pKeyhole = NULL; if (ok) { // now get the keyhole node, which is the first object-node child of the NCVC. pKeyhole = pClipViewController->FindFirstChild(); while (pKeyhole != NULL && !pKeyhole->IsAnObject()) { pKeyhole = pKeyhole->FindNext(); } // doh! can't find _one_ NodeRenderableInk child! I don't know... if (pKeyhole == NULL) { ok = FALSE; ERROR2RAW("ClipViewController has no object children"); } } // now attach a new NodeClipView, as the immediate NEXT-sibling of the keyhole node. NodeClipView* pClipView = NULL; if (ok) { ALLOC_WITH_FAIL(pClipView, new NodeClipView(pKeyhole, NEXT), this); ok = (pClipView != NULL); } // wow - succeeded! now all we need to do is some house-keeping. if (ok) { // tell the new NodeClipViewController that its current keyhole path is now invalid. pClipViewController->MarkKeyholeInvalid(); // invalidate ours and our parent's bounding rects. our bounding rect is almost // certainly already invalid, as we haven't done anything to make it valid yet. // this is why we invalidate *both* rects - just to cover all cases. pClipViewController->InvalidateBoundingRect(); Node* pParent = pClipViewController->FindParent(); if (pParent != NULL && pParent->IsBounded()) ((NodeRenderableBounded*)pParent)->InvalidateBoundingRect(); // select the new NodeClipViewController, but don't draw any blobs yet. pClipViewController->Select(FALSE); // invalidate the region bounding the selection. if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE)) { End(); return; } // factor out any common attributes. if (!DoFactorOutCommonChildAttributes(pClipViewController)) { End(); return; } // render blobs back on if the current tool doesn't automatically redraw its blobs. if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) pTool->RenderToolBlobs(pSpread, NULL); } else { FailAndExecute(); } // end the operation. End(); }
/******************************************************************************************** > void OpMakeShapes::Do(OpDescriptor*) Author: Simon_Maneggio (Xara Group Ltd) <*****@*****.**> Created: 29/04/94 Inputs: OpDescriptor (unused) Outputs: - Returns: - Purpose: Performs the MakeShapes operation. ********************************************************************************************/ void OpMakeShapes::Do(OpDescriptor*) { // Obtain the current selections Range Selection(*GetApplication()->FindSelection()); RangeControl rg = Selection.GetRangeControlFlags(); rg.PromoteToParent = TRUE; Selection.Range::SetRangeControl(rg); // change the selection flags Node* CurrentNode = Selection.FindFirst(); BOOL Success = TRUE; ERROR3IF(CurrentNode == NULL, "Make shapes called with no nodes selected"); if (CurrentNode != NULL) // No nodes selected so End { // We need to invalidate the region if (Success) Success = DoInvalidateNodesRegions(Selection, TRUE, FALSE, FALSE, FALSE); // Don't recache // Try to record the selection state, don't render the blobs though if (Success) Success = DoStartSelOp(FALSE,FALSE); // The DoMakeShapes function does all the work while (Success && CurrentNode!=NULL) { Node* Next = Selection.FindNext(CurrentNode); // BODGE - since the group is selected and won't be replaced by anything else, no need to reselect it // this fixes a bug where make shapes on grouped text stories/molds/blends don't leave the parent group // selected but selects the objects inside! BOOL reselect = !IS_A(CurrentNode,NodeGroup) && !IS_A(CurrentNode,NodeBlend); // BOOL ok = TRUE; ObjChangeFlags cFlags(TRUE); ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL); if (CurrentNode->AllowOp(&ObjChange)) { BecomeA BecomeAPath(BECOMEA_REPLACE,CC_RUNTIME_CLASS(NodePath), this, reselect); BecomeAPath.SetResultsStayInPlace(TRUE); Success = CurrentNode->DoBecomeA(&BecomeAPath); } CurrentNode = Next; } // We need to invalidate the region again for the new positions GetApplication()->FindSelection()->Update(); if (Success) Success = DoInvalidateNodesRegions(*GetApplication()->FindSelection(), TRUE); } if (!Success) { InformError(); FailAndExecute(); } End(); }