Ejemplo n.º 1
0
BOOL OpRetroFit::BuildUndo(NodePath* pPreviousNode, NodePath* pNewNode)
{
	// A few quick error checks
	ENSURE(pPreviousNode!=NULL, "Previous Node was NULL in RetroFit::BuildUndo()");
	ENSURE(pPreviousNode->IsKindOf(CC_RUNTIME_CLASS(NodePath)), "Previous Node not a path");

	ENSURE(pNewNode!=NULL, "New Node was NULL in RetroFit::BuildUndo()");
	ENSURE(pNewNode->IsKindOf(CC_RUNTIME_CLASS(NodePath)), "New Node not a path");

	// Falg to see if it has worked
	BOOL IsOperationOk = TRUE;

	// Start the undo of the selected item
	IsOperationOk = DoStartSelOp(FALSE);

	// Will the node allow this op to take place?
	ObjChangeFlags cFlags;
	cFlags.ReplaceNode = TRUE;
	ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,pPreviousNode,this);
	if (IsOperationOk)
		IsOperationOk = pPreviousNode->AllowOp(&ObjChange);
	
	// insert our new object
	if (IsOperationOk)
	{
		// Insert the new node into the tree
		IsOperationOk = DoInsertNewNode(pNewNode, pPreviousNode, NEXT, TRUE);
	}

	// Invalidate the region covered by the old node
	if (IsOperationOk)
		IsOperationOk = DoInvalidateNodeRegion(pPreviousNode, TRUE);

	// Make sure everything has worked
	if (IsOperationOk)
	{
		// Remove the old node
		IsOperationOk = DoHideNode(pPreviousNode, TRUE);
	}

	ObjChange.Define(OBJCHANGE_FINISHED,cFlags,pPreviousNode,this);
	IsOperationOk = UpdateChangedNodes(&ObjChange);

	// If something went wrong then fail
	if (!IsOperationOk)
		FailAndExecute();
	
	// End the operation properly
	End();

	// return a value back to the caller
	return IsOperationOk;
}
Ejemplo n.º 2
0
/********************************************************************************************

>	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();
}			
Ejemplo n.º 3
0
void OpBreakAtPoints::Do(OpDescriptor*)
{   
	
	// Obtain the current selections 
	SelRange* Selected = GetApplication()->FindSelection();
	NodePath* pSplitNode;

	// Now, because we're going to be doing mad things to the selection, we have to make a list
	// of all the selected nodes, so that adding nodes into the tree won't confuse us

	List* NodeList = Selected->MakeListOfNodes();
	NodeListItem* CurItem = (NodeListItem*)(NodeList->GetHead());

	if (!CurItem)
		goto FailAndDeleteList;

	if (!DoStartSelOp(TRUE,TRUE))
		goto FailAndDeleteList;

	while (CurItem)
	{
		// get a pointer to the NodePath
		NodePath* pThisNode = (NodePath*)(CurItem->pNode);

		// Only interested in NodePaths that have a sub selection, and that will allow the op to happen
		if ((IS_A(pThisNode,NodePath) || IS_A(pThisNode,NodeBlendPath)) && pThisNode->InkPath.IsSubSelection())
		{
			// Find out how many nodes this op will reproduce
			INT32 NumSplinters = pThisNode->InkPath.NumSplinters();
			BOOL DoThisNode = FALSE;

			if (NumSplinters > 0)
			{
				// We need to ask the effected nodes if they (and their parents) can handle this node being replaced
				ObjChangeFlags cFlags;

				if (NumSplinters > 1)
					cFlags.MultiReplaceNode = TRUE;	// Node will be replaced with more than one node.
				else
					cFlags.ReplaceNode = TRUE;		// Node will be replaced with one node only.

				ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
				DoThisNode = pThisNode->AllowOp(&ObjChange);
			}

			if (DoThisNode)
			{

				BOOL ok;
				Node* pnode;

				// Copy the nodepath and all its children, without placing the copy in the tree
				CALL_WITH_FAIL(pThisNode->NodeCopy(&pnode), this, ok);
				if (!ok) goto DeleteList;
				pSplitNode = (NodePath*)pnode;

				// remove the fill from this path as we're about to open it
				pSplitNode->InkPath.IsFilled = FALSE;

				// Now stick the new path into the tree
				CALL_WITH_FAIL
				(
					DoInsertNewNode(pSplitNode, pThisNode, NEXT, TRUE, FALSE),
					this,ok
				);
				
				if (!ok) 
					goto DeleteListAndPath;

				// Now breakup this copy of the path where necessary
				Path* pChildPath;
				INT32 split;

			    do
			    {
					// Create a new path, ready for split
					ALLOC_WITH_FAIL(pChildPath, new Path, this);
					if (!pChildPath) 
						goto DeleteList;

					// Now split the path, possibly into two pieces.
			    	split = pSplitNode->InkPath.BreakInTwo(pChildPath);

					if (split==-1) 
					{
						InformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK));
						delete pChildPath;
						goto FailAndDeleteList;
					}

					/*	Karim 05/12/2000
						No longer required - see code addition at the bottom of this loop.

					if (split==1) 
			    	{
						delete pChildPath;
			    		continue;
					}

					*/

					if (split>1)
					{

						// update the split paths bounding rectangle
						pSplitNode->InvalidateBoundingRect();

						// Create a new nodepath.
						NodePath* pChildNode;
						ALLOC_WITH_FAIL(pChildNode, new NodePath(), this);
						if (!pChildNode)
						{
							delete pChildPath;
							goto DeleteList;
						}

						// make room for the new path in the node path.
						CALL_WITH_FAIL
						(
							pChildNode->SetUpPath(pChildPath->GetNumCoords(),12),
							this,ok
						);
				
						if (!ok)
						{
							delete pChildNode;
							delete pChildPath;
							goto DeleteList;
						}

						// now copy the path data in there.
						pChildNode->InkPath.CopyPathDataFrom(pChildPath);
						delete pChildPath;

						// Clear the selection flag from the first element in both the split
						// and child paths.  All others apart from the last will be	unselected
						// by definition.  Also select the last element in the child
						(pSplitNode->InkPath.GetFlagArray())[0].IsSelected = FALSE;
						(pChildNode->InkPath.GetFlagArray())[0].IsSelected = FALSE;
						(pChildNode->InkPath.GetFlagArray())[(pChildNode->InkPath.GetNumCoords()-1)].IsSelected = TRUE;
						pChildNode->InkPath.IsFilled = FALSE;

						// now, copy all attributes from the parent split to the child split
						Node* pAttr = pSplitNode->FindFirstChild();
						while (pAttr != NULL)
						{
							if (pAttr->IsKindOf(CC_RUNTIME_CLASS(NodeAttribute)))
							{
								Node* pAttrCopy;
								CALL_WITH_FAIL(pAttr->NodeCopy(&pAttrCopy), this,ok);
								if (!ok) 
								{
									pChildNode->CascadeDelete();
									delete pChildNode;
									goto DeleteList;
								}
								pAttrCopy->AttachNode(pChildNode, FIRSTCHILD);
							}
							pAttr = pAttr->FindNext();
						}

						for (INT32 loop = 0; loop < pChildNode->InkPath.GetNumCoords(); loop ++)
						{
							pChildNode->InkPath.GetVerbArray()[loop] = pChildNode->InkPath.GetVerbArray()[loop] & ~PT_CLOSEFIGURE;
						}

						// Now stick the new path into the tree
						CALL_WITH_FAIL
						(
							DoInsertNewNode(pChildNode, pSplitNode, NEXT, TRUE, FALSE),
							this,ok
						);

						if (!ok)
						{
							pChildNode->CascadeDelete();
							delete pChildNode;
							goto DeleteList;
						}

						pSplitNode = pChildNode;
					}

					// Karim 05/12/2000
					// Fix for memory leak.
					else
					{
						delete pChildPath;
					}
			    }
			    while (split);

				// Clear out any remaining closefigures on the last bit of the path
				for (INT32 loop = 0; loop < pSplitNode->InkPath.GetNumCoords(); loop ++)
				{
					pSplitNode->InkPath.GetVerbArray()[loop] = pSplitNode->InkPath.GetVerbArray()[loop] & ~PT_CLOSEFIGURE;
				}

				// Now we've broken up this path, let's hide it
				CALL_WITH_FAIL(DoHideNode(pThisNode,TRUE), this, ok)
				if (!ok) goto DeleteList;
			}
		}
		CurItem = (NodeListItem*)(NodeList->GetNext(CurItem));
	}