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
/********************************************************************************************
>	void OpMakeStroke::Do(OpDescriptor*)

	Author:		Richard_Millican (Xara Group Ltd) <*****@*****.**>
	Created:	04/03/97
	Inputs:		OpDescriptor (unused)
	Outputs:	-
	Returns:	-
	Purpose:	Performs the MakeShapes operation. 
********************************************************************************************/
void OpMakeStroke::Do(OpDescriptor*)
{   
	// Obtain the current selections 
	Range Selection = *GetApplication()->FindSelection();
	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
	{                    
		// Try to record the selection state, don't render the blobs though 
		if (Success)
			Success = DoStartSelOp(FALSE,FALSE);								   

		// First, Make Shapes on everything so they're all simple paths
		String_256 Desc("Building new stroke brush...");
		Progress::Start(FALSE, &Desc);
		OpDescriptor *pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_MAKE_SHAPES);
		if (pOp != NULL)
			pOp->Invoke();

		// Second, Group everything
		pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_GROUP);
		if (pOp != NULL)
			pOp->Invoke();

		pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_GROUP);
		if (pOp != NULL)
			pOp->Invoke();

		// Finally, create a new brush
		PathStrokerVector::BodgeRipSelection(/*(CommandIndex == 0) ? FALSE :*/ TRUE);
		Progress::Stop();

	}                   

	if (!Success)
	{
		InformError();
		FailAndExecute();
	}

 	End(); 
}			
Ejemplo n.º 3
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.º 4
0
/********************************************************************************************

>	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();
}
Ejemplo n.º 5
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));
	}
Ejemplo n.º 6
0
/********************************************************************************************
>	void OpBaseConvertPathSegment::Do(OpDescriptor*)

	Author:		Peter_Arnold (Xara Group Ltd) <*****@*****.**>
	Created:	16/8/95
	Inputs:		OpDescriptor (unused)
	Purpose:	Performs the common SelRange scanning part of converting path segments.  Calls
				the ProcessSegment function in derived classes to do the actual processing
	Errors:		-
	SeeAlso:	-
********************************************************************************************/
void OpBaseConvertPathSegment::Do(OpDescriptor*)
{   
#ifndef STANDALONE

	// Obtain the current selections and the first node in the selection
	SelRange* Selected = GetApplication()->FindSelection();
	BOOL ok = (Selected != NULL);

	// Start the op
	BeginSlowJob();
	if (ok)
		ok = DoStartSelOp(TRUE,TRUE);

	// Check with the selrange it is ok to run this op
	ObjChangeFlags cFlags;
	ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
	if (ok)
	{
		if (!Selected->AllowOp(&ObjChange))
		{
			EndSlowJob();
			FailAndExecute();
			End();
			return;
		}
	}

	Node* pNode = Selected->FindFirst();
	NodePath* ThisPath = NULL;

	while (ok && (pNode != NULL))
	{	// we're only interested in NodePaths which have selected points
		BOOL DoThisNode = pNode->IsNodePath();
		if (DoThisNode)
			DoThisNode = (((NodePath*)pNode)->InkPath.IsSubSelection());
		if (DoThisNode)
			DoThisNode = (((NodePath*)pNode)->IsPathAllowable());

		if 	( DoThisNode )
		{
			// for convenience, cast the pointer to a pointer to a NodePath
			ThisPath = (NodePath*)pNode;

			// First get pointers to the arrays
			PathVerb* Verbs = NULL;
			PathFlags* Flags = NULL;
			DocCoord* Coords = NULL;
			ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
			INT32 NumCoords = ThisPath->InkPath.GetNumCoords();
			BOOL PrevSelected = FALSE;
			INT32 PrevPos = 0;

			// Set the NeedToRender flags
			INT32		loop;
			for (loop = 0; loop < NumCoords; loop++)
			{
				if (Flags[loop].IsEndPoint && Flags[loop].IsSelected)
					Flags[loop].NeedToRender = TRUE;
				else
					Flags[loop].NeedToRender = FALSE;
			}

			// Force a re-draw of the place where the path used to be
			if (ok)
				ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);

			// loop through the points
			for (loop = 0; loop<NumCoords; loop++)
			{
				if (Flags[loop].IsEndPoint)
				{	// its an endpoint
					if (Flags[loop].IsSelected)
					{	// which is selected
						if (PrevSelected && ((Verbs[loop] & ~PT_CLOSEFIGURE) == GetProcessPathType()) )
						{	//  and the previous was selected and it's a processable segment
							if (ok)
								ok = ProcessSegment(ThisPath, &loop, PrevPos);
							// Recache array pointers
							ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
							NumCoords = ThisPath->InkPath.GetNumCoords();
							Flags[loop].NeedToRender = TRUE;
						}
						PrevSelected = TRUE;
						PrevPos = loop;
					}
					else
						PrevSelected = FALSE;
				}
			}

			// Having finished processing this path go round and smooth it.
			DocCoord NewCoord;
			for (loop = 0; (ok && (loop < NumCoords)); loop++)
			{
				if (Verbs[loop] == PT_BEZIERTO && !(Flags[loop].IsEndPoint) && Flags[loop].IsSmooth)
				{
					NewCoord = ThisPath->InkPath.SmoothControlPoint(loop);
					if (ok && (NewCoord != Coords[loop]))
					{
						ok = DoAlterPathElement(ThisPath, loop, NewCoord, Flags[loop], Verbs[loop], FALSE);
						ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
					}
				}
			}

			ThisPath->InvalidateBoundingRect();

			// Force a redraw of the place where the path is now.
			if (ok)
				ok = (RecordBoundsAction::DoRecord(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);
		}
		pNode = Selected->FindNext(pNode);
	}

	if (ok)
	{
		ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
		if (!UpdateChangedNodes(&ObjChange))
		{
			FailAndExecute();
			End();
			return;
		}
	}

	EndSlowJob();

	if (!ok)
	{	
		FailAndExecute();
		InformError();
	}

#endif

	End();
}
Ejemplo n.º 7
0
void OpReversePath::Do (OpDescriptor*)
{
	// Obtain the current selections and the first node in the selection
	SelRange* Selected = GetApplication()->FindSelection();
	BOOL ok = (Selected != NULL);

	// Start the op
	BeginSlowJob();
	if (ok)
		ok = DoStartSelOp(TRUE,TRUE);

	// Check with the selrange it is ok to run this op
	ObjChangeFlags cFlags;
	ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
	if (ok)
	{
		if (!Selected->AllowOp(&ObjChange))
		{
			EndSlowJob();
			FailAndExecute();
			End();
			return;
		}
	}

	Node* pNode = Selected->FindFirst();
	NodePath* ThisPath = NULL;

	//Document* pDocument = GetWorkingDoc();

	while (ok && (pNode != NULL))
	{	// we're only interested in NodePaths which have selected points
		BOOL DoThisNode = pNode->IsNodePath();
		//if (DoThisNode)
		//	DoThisNode = (((NodePath*)pNode)->InkPath.IsSubSelection());
		if (DoThisNode)
			DoThisNode = (((NodePath*)pNode)->IsPathAllowable());

		if 	( DoThisNode )
		{
			// for convenience, cast the pointer to a pointer to a NodePath
			ThisPath = (NodePath*)pNode;

			// First get pointers to the arrays
			PathVerb* Verbs = NULL;
			PathFlags* Flags = NULL;
			DocCoord* Coords = NULL;
			ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
			INT32 NumCoords = ThisPath->InkPath.GetNumCoords();
//			BOOL PrevSelected = FALSE;
//			INT32 PrevPos = 0;

			ObjChangeFlags cFlags;
			cFlags.TransformNode = TRUE;
			ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,ThisPath,this);
			if (!ThisPath->AllowOp(&ObjChange, TRUE))
			{
				return;
			}

			// Set the NeedToRender flags
			for (INT32 loop = 0; loop < NumCoords; loop++)
			{
				if (Flags[loop].IsEndPoint && Flags[loop].IsSelected)
					Flags[loop].NeedToRender = TRUE;
				else
					Flags[loop].NeedToRender = FALSE;
			}

			// Force a re-draw of the place where the path used to be
			if (ok)
				ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);

			DoReversePath (ThisPath);

			// Force a redraw of the place where the path is now.
			if (ok)
				ok = (RecordBoundsAction::DoRecord(this, &UndoActions, ThisPath, TRUE) != AC_FAIL);
		}
		pNode = Selected->FindNext(pNode);
	}

	if (ok)
	{
		ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
		if (!UpdateChangedNodes(&ObjChange))
		{
			FailAndExecute();
			End();
			return;
		}
	}

	EndSlowJob();

	if (!ok)
	{	
		FailAndExecute();
		InformError();
	}

	End();
}
Ejemplo n.º 8
0
/********************************************************************************************

>	void OpMoveToLayer::Do(OpDescriptor*)

	Author:		Simon_Knight (Xara Group Ltd) <*****@*****.**> 
	Created:	3/5/00
	Purpose:	This takes the selection and moves it to the active layer. This is a more
				powerful operation than the move forward/backward a layer

********************************************************************************************/
void OpMoveToLayer::Do(OpDescriptor*)
{
	if (DoStartSelOp(FALSE,TRUE))
	{
		// get the selection
		Range Sel(*(GetApplication()->FindSelection()));

		// set the range flags so it includes shadow and bevel manager nodes
		RangeControl rg = Sel.GetRangeControlFlags();
		rg.PromoteToParent = TRUE;
		Sel.Range::SetRangeControl(rg);

		// Prepare an ObjChangeParam so we can mark which nodes will allow this op to happen to them
		ObjChangeFlags cFlags;
		cFlags.MoveNode = TRUE;
		ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);

		// add items directly after the layer node as its first child
		Node * pTail = (Node *) (Document::GetCurrent()->GetInsertionPosition());
		AttachNodeDirection TailAttachDirection = PREV;
		Spread* pSpread = Document::GetSelectedSpread();

		if (!pTail)
		{
			if (pSpread)
			{
				pTail = pSpread->FindActiveLayer();
				// AttachNodeDirection TailAttachDirection = LASTCHILD; <--- AMB removed this and inserted the next line 2006-04-10 presuming bug
				TailAttachDirection = LASTCHILD;
			}
			else
			{
				FailAndExecute();
				End();
				return; // nowhere to put the nodes
			}
		}


		// Mark nodes that will allow this to happen, and error if no nodes will let it happen
		if (!Sel.AllowOp(&ObjChange))
		{
			FailAndExecute();
			End();
			return; // op not allowed
		}

		// get a list from which to move the nodes (fixes job #10781 - the re-selection of 
		// moved nodes caused an infinite loop)

		List* pNodeList = Sel.MakeListOfNodes(FALSE);
		NodeListItem* CurItem = (NodeListItem*)(pNodeList->GetHead());
		while (CurItem)
		{
			Node* pNode = CurItem->pNode;

			// Make sure the current owner Layer is told about the changes
			// and given the chance to release any cached info it may be
			// holding about the selected object
			// (I know that the original position coincides with the destination position
			//  but this is hte simplest way to get the original parent layer uncached
			//  and to get a record in the undo history so that the layer cacheing will
			//  be dealt with properly during gundo/redo)
			DoInvalidateNodeRegion((NodeRenderableBounded*) pNode, TRUE, FALSE);

			// localise attribs for this node
			DoLocaliseForAttrChange((NodeRenderableInk*) pNode, (AttrTypeSet *)NULL, (ObjectSet*) NULL);
			DoMoveNode(pNode, pTail, TailAttachDirection);
			// factor out common attribs
			if (pNode->IsCompound())
				DoFactorOutCommonChildAttributes((NodeRenderableInk*) pNode);
			else
				DoFactorOutAfterAttrChange((NodeRenderableInk*) pNode, (AttrTypeSet *)NULL);

			// make the nodes region be redrawn
			DoInvalidateNodeRegion((NodeRenderableBounded*) pNode, TRUE, FALSE);

			CurItem = (NodeListItem*)(pNodeList->GetNext(CurItem));
		}
		// delete the the list objects 
		pNodeList->DeleteAll();
		delete pNodeList;

		// the selection will have changed - after all we just deleted it
		BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
		GetApplication()->UpdateSelection();

		ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
		UpdateChangedNodes(&ObjChange);
		// end the op
		End();

		// update the bars
		DialogBarOp::SetSystemStateChanged();
		DialogBarOp::UpdateStateOfAllBars(); 
	}
	else
	{
		// give up and go home
		FailAndExecute();
		End();
	}
}
Ejemplo n.º 9
0
/********************************************************************************************

>	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();
}			
Ejemplo n.º 10
0
/********************************************************************************************
>	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(); 
}