コード例 #1
0
ファイル: customlist.cpp プロジェクト: vata/xarino
// Function to create a custom header from a bitmap resource
BOOL CCustomList::CreateCustomHeader(UINT32 bitmapID)
{
    //The listview control has a built-in header, but we will create our own as we want it to display bitmaps
    //First get control's coordinates, so that we know where to place the header

    CRect listviewRect;
    GetWindowRect(&listviewRect);
    POINT listviewOrigin = { listviewRect.left, listviewRect.top };
    ::ScreenToClient((HWND) GetOwner()->m_hWnd, &listviewOrigin);

    if(!m_hHeaderBitmap.LoadBitmap(MAKEINTRESOURCE(bitmapID)))
        ERROR2RAW("Failed to load header bitmap");

    //Get the height of the bitmap so we can figure out the height of the header
    BITMAP bitmap ;
    if (!m_hHeaderBitmap.GetBitmap(&bitmap))
    {
        ERROR2RAW("Failed to get header bitmap data");
        return(FALSE);
    }
    //Change the background colour of the bitmap to the one used by dialog backgrounds, in case the colour scheme used is not the default
    SetBitmapBkgToSystem(m_hHeaderBitmap);

    CRect srect;
    srect.left = listviewOrigin.x + m_ColumnOffsetsArray[0] + 1;
    srect.right = listviewRect.right  ;
    srect.top	= listviewOrigin.y - bitmap.bmHeight;
    srect.bottom = listviewOrigin.y;

    m_hHeader.Create(NULL, WS_VISIBLE | SS_BITMAP, srect, this->GetOwner());
    m_hHeader.SetBitmap(m_hHeaderBitmap);
    return TRUE;
}
コード例 #2
0
ファイル: filtirr.cpp プロジェクト: Amadiro/xara-cairo
void ImagemapRenderRegion::DrawPathToOutputDevice(Path *ppthRender, PathShape shapePath)
{
	//First check our path parameter
 	if (ppthRender==NULL)
	{
		ERROR2RAW("ImagemapRenderRegion::DrawPathToOutputDevice not given a path!");
		return;
	}

	//Now get the current WebAddressAttribute
	WebAddressAttribute* pwaaCurrent=(WebAddressAttribute*) GetCurrentAttribute(ATTR_WEBADDRESS);

	if (pwaaCurrent==NULL)
	{
		ERROR2RAW("ImagemapRenderRegion::DrawPathToOutputDevice - no current WebAddressAttribute!");
		return;
	}

	
	//IF the current WebAddressAttribute has a URL
	if (pwaaCurrent->HasURL())
	{
		//Then we want to add a clickable area into the imagemap

		//Now, if EITHER the user has specified that this clickable area is a rectangle
		//OR the user has specified all clickable areas should be rectangles
		//OR this path is a rectangle shape
		if (m_Options.m_fAllRectangles 
			|| pwaaCurrent->UseBoundingRectangle()
			|| shapePath==PATHSHAPE_RECTANGLE
			|| shapePath==PATHSHAPE_SQUARE)
		{
			//Then we want to add a clickable area into the imagemap
			
			//So get the rectangle to add
			DocRect rectToAdd=pwaaCurrent->GetClickableRectangleInRendering();

			//And add it
			AddRectangleToImagemap(rectToAdd, pwaaCurrent);

		}
		else
		{
			//It's not a rectangle

			//So, what shape is the path?
			if (shapePath==PATHSHAPE_CIRCLE)
				//Circular. So add a circle to the imagemap
				AddCircleToImagemap(ppthRender, pwaaCurrent);
			else
				//Otherwise, add a polygon to the imagemap
				AddPathToImagemap(ppthRender, pwaaCurrent);

		}//End if/else rectangle

	} //ENd if/else has URL

}
コード例 #3
0
ファイル: scroller.cpp プロジェクト: UIKit0/xara-xtreme
void CWinScroller::SetScrollRange(const XLONG& lo, const XLONG& hi, BOOL redraw)
{
	const INT32 MIN= -2147483647 - 1; 
	const INT32 MAX=  2147483647;		
	if( lo < MIN || hi < MIN || lo > MAX || hi > MAX )
	{
		ERROR2RAW( "SetScrollRange limits exceeded!");
	}

	// Calculate the "direction" (Delta) and the limits of the scroller.
	MinVal = lo;
	SnapToGrain(&MinVal);
	MaxVal = hi;
	SnapToGrain(&MaxVal);
	Range = Abs(MaxVal - MinVal);
	Delta = (MaxVal > MinVal ? 1 : (MaxVal < MinVal ? -1 : 0));

	// If necessary adjust the position of the thumb, so that it remains within
	// the new range.
	ClipThumbPos(ThumbVal);
	MoveThumb(redraw);

	// Now pass minimum and maximum position values to the CScrollBar control. Also set the 
	// nPage value because otherwise CScrollBar will miscalculate the thumbsize when we are 
	// zooming back up from a view that is smaller than the render window (e.g 25% to 100%).

	SCROLLINFO si;
	si.cbSize = sizeof(SCROLLINFO);
	si.fMask = SIF_PAGE|SIF_RANGE;
	si.nPage = (INT32)PageSize;
	si.nMin = MinVal;     
	si.nMax = MaxVal; 
	SetScrollInfo(&si, true);
}
コード例 #4
0
ファイル: webattr.cpp プロジェクト: UIKit0/xara-xtreme
void WebAddressAttribute::CopyString(TCHAR** ppcCopyTo, const TCHAR* pcCopyFrom)
{
	//We need to check that ppcCopyTo is valid
	if (ppcCopyTo==NULL)
	{
		ERROR2RAW("WebAddress::CopyString passed NULL parameter");
	 	return;
	}

	//Now, if *ppcCopyTo points to a string, we delete it now
	if (*ppcCopyTo)
	{
		free (*ppcCopyTo);
		*ppcCopyTo=NULL;	
	}
		
	//Does pcCopyFrom point to a string?
	if (pcCopyFrom)
	{
		//Yes (we assume it does if it's not NULL)
		//So copy that string into *ppcCopyTo
		(*ppcCopyTo) = camStrdup( pcCopyFrom );
	}

	//If pcCopyFrom is NULL, then ppcCopyTo is NULL, which is correct
	//So return
}
コード例 #5
0
ファイル: overlist.cpp プロジェクト: Amadiro/xara-cairo
void OverrideList::AddHead( OverrideListItem* poliToAdd)
{
	if (poliToAdd==NULL)
	{
		ERROR2RAW("OverrideList::AddHead - NULL parameter");
		return;
	}

	//Get the first item in the list
	OverrideListItem* pliFirst=(OverrideListItem*) GetHead();

	//Was there anything in the list?
	if (pliFirst!=NULL)				 
	{
		//Yes. So call our InsertBefore function
		InsertBefore(pliFirst, poliToAdd);
	}
	else
	{
		//No. So we need do no special checking - simply insert
		//the list item
		List::AddHead(poliToAdd);
	}
	
}
コード例 #6
0
ファイル: overlist.cpp プロジェクト: Amadiro/xara-cairo
void OverrideList::AddTail( OverrideListItem* poliToAdd)
{
	if (poliToAdd==NULL)
	{
		ERROR2RAW("OverrideList::AddTail - NULL parameter");
		return;
	}

	//Get the last item in the list
	OverrideListItem* pliLast=(OverrideListItem*) GetTail();

	//Was there anything in the list?
	if (pliLast!=NULL)				 
	{
		//Yes. So call our InsertAfter function
		InsertAfter(pliLast, poliToAdd);
	}
	else
	{
		//No. So we need do no special checking - simply insert
		//the list item
		List::AddTail(poliToAdd);
	}

	//And add our item after it
	InsertAfter(pliLast, poliToAdd);
	
}
コード例 #7
0
ファイル: uielem.cpp プロジェクト: vata/xarino
/*******************************************************************************************

>	virtual VisibleListItem& VisibleList::GetEntryAt(UINT32 Index)

	Author:		Colin_Barfoot (Xara Group Ltd) <*****@*****.**>
	Created:	09/06/97

	Purpose:	Support function to get the Index'th entry in the list

	Returns:	The VisibleListItem at the given Index

*******************************************************************************************/
VisibleListItem& VisibleList::GetEntryAt(UINT32 Index)
{
	VisibleListItemPtr* const pEntry = (VisibleListItemPtr*)GetContainer().FindItem(LISTPOS(Index));
	if (pEntry == NULL)
	{
		ERROR2RAW("NULL member");
	}

	return pEntry->GetEntry();
}
コード例 #8
0
ファイル: webattr.cpp プロジェクト: UIKit0/xara-xtreme
void AttrWebAddress::Render( RenderRegion* pRender)
{
	//Check the render region pointer
	if (pRender==NULL)
		ERROR2RAW("AttrWebAddress::Render - pRender is NULL");

	//Set the clickable rectangle of our WebAddressAttribute
	Value.SetClickableRectangleInRendering(GetClickableRectangle());

	//Then set our WebAddressAttribute member variable into that render region
	pRender->SetWebAddress(&Value, FALSE);
}
コード例 #9
0
ファイル: stemplate.cpp プロジェクト: vata/xarino
void WebAddress::CorrectBackslashes(String_256* pstrCorrect)  
{	
	//Check our parameter
	if (pstrCorrect==NULL)
	{
		ERROR2RAW("WebAddress::CorrectBackslashes - NULL parameter");
		return;
	}

	//And correct all backslashes to forward slashes
	pstrCorrect->SwapChar('\\', '/');

}
コード例 #10
0
ファイル: stemplate.cpp プロジェクト: vata/xarino
void WebAddress::CorrectNetscapeFilenames(String_256* pstrCorrect)  
{	
	//Check our parameter
	if(pstrCorrect==NULL)
	{
		ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
		return;
	}
																		
	//Simply delete the fifth character, removing one of the slashes
	pstrCorrect->Remove(6, 1);

}
コード例 #11
0
ファイル: errors.cpp プロジェクト: Amadiro/xara-cairo
void CDECL Error::XSetError( UINT32 errID, ...)
{


	if ( (errID==FALSE) || (errID==TRUE) )
	{
		// someone probably used the wrong macro parameters e.g. TRUE and FALSE instead of ID
		// This call will set an _R(IDE_INTERNAL_ERROR) for us
		ERROR2RAW( "ERROR1 macro used with invalid parameters" );
		return;
	}

	TCHAR				buf[256];

	va_list marker;

	va_start( marker, errID );

	String_256 result;

	// load the format string as a resoure (note no module ID yet)
	if (!SmartLoadString(0, errID, buf, sizeof(buf)))
	{
		camSnprintf( buf, 256, wxT("Error<%u>"), errID ); // keep inline
	}

	// now do _MakeMsg type formatting
	result.CCvsprintf(buf, marker);

#if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX)
	// Set the help context.
	SetNextMsgHelpContext(errID);
#endif
	// ralph needs this so that he can map the ID to a HRESULT before passing it
	// back to a harness
	TRACEUSER( "Chris", wxT("oOoOo Ralph Set Error %d \n"), RalphErrorID );

	RalphErrorID =errID;

	// and copy result into ErrorString
	SetErrorSerious( result );

	// trace output because SetErrorSerious doesn't bother
	TRACE( wxT("Setting error: ID = %d: \"%s\"\n"), errID, ErrorString);

	// then tidy up	
	va_end( marker );

	ResetWhere();
}
コード例 #12
0
ファイル: stemplate.cpp プロジェクト: vata/xarino
void WebAddress::CorrectNoSlash(String_256* pstrCorrect)  
{	
	//Check our parameter
	if(pstrCorrect==NULL)
	{
		ERROR2RAW("WebAddress::CorrectNoSlash - NULL parameter");
		return;
	}
	
	//And if the string is long enough
	if (pstrCorrect->Length()<255)
	{
		//Add a slash to the end
		*pstrCorrect+='/';
	}
}
コード例 #13
0
ファイル: stemplate.cpp プロジェクト: vata/xarino
void WebAddress::CorrectLocalFilenames(String_256* pstrCorrect)  
{	
	//Check our parameter
	if(pstrCorrect==NULL)
	{
		ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
		return;
	}

	
	//Now, create a pathname out of our string
	PathName pthTemp=*pstrCorrect;

	//And call the GetWebAddress function
	*pstrCorrect=pthTemp.GetWebAddress();

}
コード例 #14
0
ファイル: errors.cpp プロジェクト: Amadiro/xara-cairo
INT32 test2(INT32 which)
{
	if (which==0)
	{
		ERROR2RAW( "Simple raw error" );
		return 0;
	}
	if (which==1)
		ERROR2( 10, "Simple error" );
	if (which==2)
		ERROR2IF( TRUE, 20, "Simple error if");
	if (which==3)
		ERROR2_PF( 30, ("String (%s)", "blobby") );
	if (which==4)
		ERROR2IF_PF( TRUE, 40, ("Numbers (%d,%d)" , 42,43) );
	return 0;
}
コード例 #15
0
ファイル: customlist.cpp プロジェクト: vata/xarino
// add bitmap at the specified  column
void CCustomListRowWnd::AddBitmap(INT32 col, HBITMAP hBitmap,HBITMAP, DWORD dwBackColour)
{
    CStatic* pStat = new CStatic();
    ASSERT(m_ColumnObjects[col] == NULL);
    m_ColumnObjects[col] = pStat ;

    CRect cr;
    GetClientRect(&cr);

    BITMAP bitmap;
    CBitmap::FromHandle(hBitmap)->GetBitmap(&bitmap);
    CRect srect;
    srect.left = m_Parent->m_Parent->m_ColumnOffsetsArray[col] ;
    srect.right = srect.left + bitmap.bmWidth;
    srect.top	= cr.Height()/2 - bitmap.bmHeight/2;
    srect.bottom = cr.Height()/2 + bitmap.bmHeight/2;

    ////
    HDC hBitmapDC = CreateCompatibleDC(NULL);
    if (!hBitmapDC)
    {
        ERROR2RAW("Non-fatal GDI error");
    }
    SelectObject(hBitmapDC, hBitmap);
    // Iff we haven't been told what the background colour is...
    // We make the assumption that the pixel in the lower right corner has the background colour
    if (dwBackColour == 0xFFFFFFFF)
        dwBackColour = (DWORD) GetPixel(hBitmapDC, bitmap.bmWidth - 1, bitmap.bmHeight -1);
    DWORD sysBkColour = GetSysColor(COLOR_3DFACE);
    for (INT32 i = 0; i < bitmap.bmWidth; i++)
    {
        for (INT32 j = 0; j < bitmap.bmHeight; j++)
        {
            if ((DWORD) GetPixel(hBitmapDC, i, j) == dwBackColour)
                SetPixelV(hBitmapDC, i, j, (COLORREF) sysBkColour);
        }
    }
    DeleteDC(hBitmapDC);

    ////
    pStat->Create(NULL, WS_VISIBLE | SS_BITMAP, srect, this);
    pStat->SetBitmap(hBitmap);
}
コード例 #16
0
ファイル: gendwnd.cpp プロジェクト: vata/xarino
void OpGenericDownload::OnDownloadFail()
{
	//First get a pointer to the parameters
	GenericDownloadParam* pGenParam = (GenericDownloadParam*) pParam;

	if (pGenParam==NULL)
	{
		ERROR2RAW("OpBitmapDownload::OnDownloadFail - no download parameters");
		return;
	}

	//Get the URL which the user typed
	String_256 strURL=pGenParam->strURL;

	//And put it up as a message
	String_256 strMessage;
	strMessage.MakeMsg(_R(IDS_HTML_DOWNLOADFAILED), &strURL);
	Error::SetError(0, strMessage, 0);
	InformError();

}
コード例 #17
0
ファイル: webattr.cpp プロジェクト: UIKit0/xara-xtreme
void WebAddressAttribute::SimpleCopy(AttributeValue *pValue)
{
	//Check parameter
	if (pValue==NULL)
	{
		ERROR2RAW("WebAddressAttribute::SimpleCopy - NULL parameter");
		return;
	}



	//If pValue is a Web Address
	if (pValue->IsKindOf(CC_RUNTIME_CLASS(WebAddressAttribute)))
	{
		//Copy it into this attribute
		*this=*((WebAddressAttribute*) pValue);
	}
	else
		//Make this attribute blank
		*this=WebAddressAttribute();
}
コード例 #18
0
ファイル: stemplate.cpp プロジェクト: vata/xarino
void WebAddress::CorrectNoNetLoc(String_256* pstrCorrect)  
{	
	//Check our parameter
	if(pstrCorrect==NULL)
	{
		ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
		return;
	}
	
	//We already know that our string does not start with "http://"
	//But does it start with "http:/"?
	if (pstrCorrect->SubWithoutCase(String_256("http:/"))==0)
	{
		//Yes it does. So insert an extra slash
		pstrCorrect->Insert(&String_256("/"), 5);
	}
	else
	{
		//No it doesn't. So insert an extra two slashes after the HTTP
		pstrCorrect->Insert(&String_256("//"), 5);
	}
}
コード例 #19
0
ファイル: stemplate.cpp プロジェクト: vata/xarino
void WebAddress::CorrectMailto(String_256* pstrCorrect)  
{	
	//Check our parameter
	if(pstrCorrect==NULL)
	{
		ERROR2RAW("WebAddress::CorrectBackslash - NULL parameter");
		return;
	}
	
	//If our string is over two hundred and fifty characters long, return
	if (pstrCorrect->Length()>250)
		return;

	//Otherwise, create a new string containing "mailto:"
	String_256 strToReturn="mailto:";

	//Add our other string onto the end of it
	strToReturn+=*pstrCorrect;

	//And copy our new string into our old string
	*pstrCorrect=strToReturn;
}
コード例 #20
0
ファイル: customlist.cpp プロジェクト: vata/xarino
// helper function to change the background colour of the bitmap to the one used by dialog backgrounds
BOOL SetBitmapBkgToSystem(HBITMAP hBitmap)
{
    BITMAP bitmap;
    HDC hBitmapDC = CreateCompatibleDC(NULL);
    if (!GetObject(hBitmap, sizeof(bitmap), &bitmap) || !hBitmapDC)
    {
        ERROR2RAW("Non-fatal GDI error");
        return(FALSE);
    }
    SelectObject(hBitmapDC, hBitmap);
    // We make the assumption that the pixel in the lower right corner has the background colour
    DWORD currentBkColour = (DWORD) GetPixel(hBitmapDC, bitmap.bmWidth - 1, bitmap.bmHeight -1);
    DWORD sysBkColour = GetSysColor(COLOR_3DFACE);
    for (INT32 i = 0; i < bitmap.bmWidth; i++)
    {
        for (INT32 j = 0; j < bitmap.bmHeight; j++)
        {
            if ((DWORD) GetPixel(hBitmapDC, i, j) == currentBkColour)
                SetPixelV(hBitmapDC, i, j, (COLORREF) sysBkColour);
        }
    }
    DeleteDC(hBitmapDC);
    return TRUE;
}
コード例 #21
0
ファイル: tooldlg.cpp プロジェクト: Amadiro/xara-cairo
void ToolbarDlg::ShowToolbarList()
{
	if (!WindowID)
		return;

	// set the custom list gadget 
	CCustomList* pListGadget = CCustomList::GetGadget(GetReadWriteWindowID(), _R(IDC_BARLIST));
	if(!pListGadget)
	{
		ERROR2RAW("No list gadget");
		return;
	}
	pListGadget->SetColumnWidth(0,GetSystemMetrics(SM_CXMENUCHECK) + 10);

	CMainFrame* pFrame = GetMainFrame();
	ERROR3IF(pFrame == NULL, "Can't find Main Frame in ShowToolBarList");

	if(pFrame->IsChangingViewMode())
		return ;

	// Fetch the names and states of all defined bars...
	List* pBarList = MessageHandler::GetClassList(CC_RUNTIME_CLASS(DialogBarOp));
	ENSURE(pBarList,"Can't find list of DialogBarOps in ShowToolBarList");

	// Delete any existing list items...
	pListGadget->DeleteAllItems();

	// Add names of all bars to the list...
	// First do the infobar...
	pListGadget->AddItem(InfoBarName);
	pListGadget->SetSwitchState(InformationBarOp::IsVisible(), (pListGadget->GetItemCount() - 1), 0);

	// Scan the list of all barops and add the names of those which should be shown
	// to the user to the scrollable list.
	DialogBarOp* pBar = (DialogBarOp*)pBarList->GetHead();
	
	BOOL FoundControlBank = FALSE;
	BOOL ControlBankVisible = FALSE;
	while (pBar)
	{
		// Show any bar that's NOT a system bar and NOT an information bar
		// and NOT a Super Gallery put the Controlbank at the end
		if ( IS_A(pBar,DialogBarOp) )
		{
			// Put its name in the list
			String_32 BarName = pBar->GetName();
			if (BarName != ControlBankName)
			{	
				pListGadget->AddItem(BarName);
				pListGadget->SetSwitchState(pBar->IsVisible(), (pListGadget->GetItemCount() - 1), 0);
			}
			else
			{
				FoundControlBank = TRUE;
				ControlBankVisible = pBar->IsVisible();
			}
		}
		pBar = (DialogBarOp*)pBarList->GetNext(pBar);
	}
	
	if (FoundControlBank)
	{
		pListGadget->AddItem(ControlBankName);
		pListGadget->SetSwitchState(ControlBankVisible, (pListGadget->GetItemCount() - 1), 0);
	}
}
コード例 #22
0
ファイル: nativeop.cpp プロジェクト: vata/xarino
void OpMenuSave::Do(OpDescriptor* pOpDesc)
{
	//First get the selected document
	Document* pdocToSave=Document::GetSelected();
	CCamDoc* pccamdocToSave = pdocToSave->GetOilDoc();

	if (pdocToSave==NULL || pccamdocToSave==NULL)
	{
		ERROR2RAW("No default document!");
		return;
	}

	//And we'll need a pointer to the application
	Application*		pCamelot = GetApplication();
	CTemplateManager&	TemplateManager( pCamelot->GetTemplateManager() );

	//And put the default templates path in the dialog
	PathName			pathToPutInDialog = TemplateManager.GetTemplatesPath();

	FileUtil::RecursiveCreateDirectory( pathToPutInDialog.GetPath() );
	
	//Now create the dialog
	SaveTemplateDialog	dialogToDisplay(pathToPutInDialog);
		
	//And show it
	if (dialogToDisplay.ShowModal() == wxID_OK)
	{
		//Then get the path they specified, using this amazingly bad, confusing and
		//undocumented file dialog code

		//The "CString" reference should ideally go in Winoil
		PathName pathToSaveTo;
		dialogToDisplay.GetChosenFileName(&pathToSaveTo);

		wxString cstrPathToSaveTo=pathToSaveTo.GetPath(FALSE);
		dialogToDisplay.AppendExtension(&cstrPathToSaveTo);

		String_256 strPathToSaveTo=cstrPathToSaveTo;
		pathToSaveTo=strPathToSaveTo;
						
		// Create the save file.
		CCDiskFile file(pathToSaveTo, ios::out | ios::binary | ios::trunc);

		// First find the filter.
		Filter *pFilter = FindFilter ( FILTERID_NATIVE );

		// Tell it to save attributes.
		pFilter->SetSaveAttributes ( TRUE );

		// Then save the image to the file.
		Save ( pFilter, &file );
		
		//Now, if we should make that path the default path
		if (SaveTemplateDialog::m_fUseAsDefault)
		{
			if (pdocToSave->IsAnimated())
			{
				CTemplateManager::SetDefaultAnimationTemplate( strPathToSaveTo );
			}
			else
			{
				CTemplateManager::SetDefaultDrawingTemplate( strPathToSaveTo );
			}
		}

		if (SaveTemplateDialog::m_fDefaultTemplatesFolder)
		{
			String_256	strDefaultPath = pathToSaveTo.GetLocation( TRUE );
			CTemplateManager::SetTemplatesPath( strDefaultPath );
		}
	}

	// Finished the operation
	End();
}
コード例 #23
0
ファイル: opclip.cpp プロジェクト: Amadiro/xara-cairo
/********************************************************************************************

>	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();
}
コード例 #24
0
ファイル: aligndlg.cpp プロジェクト: Amadiro/xara-cairo
void OpAlign::DoWithParam(OpDescriptor* pOp, OpParam* pAlignParam)
{
	// DMc alterations so that this works with compound nodes	
	SelRange   Selection(*(GetApplication()->FindSelection()));

	RangeControl rg = Selection.GetRangeControlFlags();
	rg.PromoteToParent = TRUE;
	Selection.Range::SetRangeControl(rg);

	DocRect		SelRect   = Selection.GetBoundingRect();
	DocRect		TargetRect;
	TargetRect.MakeEmpty();
	INT32        NumObjs   = Selection.Count();
	AlignParam* pAlign    =(AlignParam*)pAlignParam;

	BOOL moved=FALSE;					// set to TRUE if any object is moved
	BeginSlowJob(-1,FALSE);
	BOOL OK=DoStartTransOp(FALSE);

	// find parent spread of first object in selection
	Node*   pFirstNode=NULL;
	Spread* pSpread   =NULL;
	if (OK)
	{
		pFirstNode=Selection.FindFirst();
		if (pFirstNode!=NULL)
			pSpread=pFirstNode->FindParentSpread();
		OK=(pSpread!=NULL);
		if (!OK)
			ERROR2RAW("OpAlign::DoWithParam() - could not find parent spread");
	}

	// Find the size of the target rectangle
	if (pAlign->target==ToSelection)
		TargetRect=SelRect;
	else
	{
		Page* pPage=pSpread->FindFirstPageInSpread();
		while (pPage)
		{
			DocRect PageRect=pPage->GetPageRect();
			if (pAlign->target==ToSpread || SelRect.IsIntersectedWith(PageRect))
				TargetRect=TargetRect.Union(PageRect);
			pPage=pPage->FindNextPage();
		}
	}

	// allocate all dynamic memory required
	Node**	 pObj=NULL;
	ObjInfo* x   =NULL;
	ObjInfo* y   =NULL;
	INT32*    dx  =NULL;
	INT32*    dy  =NULL;
	if (OK)			ALLOC_WITH_FAIL(pObj,(Node**)  CCMalloc(NumObjs*sizeof(Node*)),  this);
	if (pObj!=NULL)	ALLOC_WITH_FAIL(x,   (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this);
	if (   x!=NULL) ALLOC_WITH_FAIL(y,   (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this);
	if (   y!=NULL) ALLOC_WITH_FAIL(dx,  (INT32*)   CCMalloc(NumObjs*sizeof(INT32)),   this);
	if (  dx!=NULL) ALLOC_WITH_FAIL(dy,  (INT32*)   CCMalloc(NumObjs*sizeof(INT32)),   this);
	OK=(dy!=NULL);

	// if memory claimed OK and target rect not empty proceed with op
	// (ie. do nothing if 'within page(s)' when no object on a page)
	DocRect EmptyRect;
	if (OK && TargetRect!=EmptyRect)
	{
		// create an array of pointers to objects (nodes) to be affected
		Node* pNode=Selection.FindFirst();
		INT32  i=0;
		while (pNode!=NULL)
		{
			if (pNode->IsBounded() && !((NodeRenderableBounded*)pNode)->GetBoundingRect(TRUE).IsEmpty())
				pObj[i++]=pNode;
			pNode=Selection.FindNext(pNode);
		}
		NumObjs=i;

		// cache x & y info in separate arrays so they can be sorted separately
		XLONG SumObjWidths =0;
		XLONG SumObjHeights=0;
		for (i=0; i<NumObjs; i++)
		{
			DocRect ObjRect=((NodeRenderableBounded*)pObj[i])->GetBoundingRect();
			x[i].i=i;
			x[i].lo=ObjRect.lo.x;
			x[i].hi=ObjRect.hi.x;
			SumObjWidths+=ObjRect.hi.x-ObjRect.lo.x;
			y[i].i=i;
			y[i].lo=ObjRect.lo.y;
			y[i].hi=ObjRect.hi.y;
			SumObjHeights+=ObjRect.hi.y-ObjRect.lo.y;
		}

		// for each object, calculate the x and y displacements independently
		AlignOneAxis(pAlign->h,NumObjs,SumObjWidths, TargetRect.lo.x,TargetRect.hi.x,x,dx);
		AlignOneAxis(pAlign->v,NumObjs,SumObjHeights,TargetRect.lo.y,TargetRect.hi.y,y,dy);

		// apply the x and y displacements simultaneously to each object
		for (i=0; i<NumObjs; i++)
			if (dx[i]!=0 || dy[i]!=0)
			{
				moved=TRUE;
				Trans2DMatrix* pMatrix=new Trans2DMatrix(dx[i],dy[i]);
				DoTransformNode((NodeRenderableInk*)pObj[i],pMatrix);
			}
	}

	// free up any memory which was allocated
	CCFree(dx);
	CCFree(dy);
	CCFree(x);
	CCFree(y);
	CCFree(pObj);

	if (moved)
	{
		Document::GetSelected()->ForceRedraw(pSpread, TargetRect);
		GetApplication()->UpdateSelection();
	}
	else
		FailAndExecute();
	End();
	EndSlowJob();
}