803 lines
26 KiB
C++
803 lines
26 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
|
|
#include <vector>
|
|
#include <editeng/editeng.hxx>
|
|
#include "svx/xexch.hxx"
|
|
#include <svx/xflclit.hxx>
|
|
#include <svx/svdxcgv.hxx>
|
|
#include <svx/svdoutl.hxx>
|
|
#include "svx/svditext.hxx"
|
|
#include <svx/svdetc.hxx>
|
|
#include <svx/svdundo.hxx>
|
|
#include <svx/svdograf.hxx>
|
|
#include <svx/svdoole2.hxx> // to not have OLE in SdrClipboardFormat
|
|
#include <svx/svdorect.hxx>
|
|
#include <svx/svdoedge.hxx> // for connectors via the clipboard
|
|
#include <svx/svdopage.hxx> // for connectors via the clipboard
|
|
#include <svx/svdpage.hxx>
|
|
#include <svx/svdpagv.hxx>
|
|
#include <svx/svdtrans.hxx> // for GetMapFactor, to rescale at PasteModel
|
|
#include "svx/svdstr.hrc" // names taken from the resource
|
|
#include "svx/svdglob.hxx" // StringCache
|
|
#include "svx/xoutbmp.hxx"
|
|
#include <vcl/metaact.hxx>
|
|
#include <svl/poolitem.hxx>
|
|
#include <svl/itempool.hxx>
|
|
#include <tools/bigint.hxx>
|
|
#include <sot/formats.hxx>
|
|
|
|
// #i13033#
|
|
#include <clonelist.hxx>
|
|
#include <vcl/virdev.hxx>
|
|
|
|
#include <svl/style.hxx>
|
|
|
|
// #i72535#
|
|
#include "fmobj.hxx"
|
|
#include <rtl/strbuf.hxx>
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut):
|
|
SdrObjEditView(pModel1,pOut)
|
|
{
|
|
}
|
|
|
|
sal_Bool SdrExchangeView::ImpLimitToWorkArea(Point& rPt) const
|
|
{
|
|
sal_Bool bRet(sal_False);
|
|
|
|
if(!aMaxWorkArea.IsEmpty())
|
|
{
|
|
if(rPt.X()<aMaxWorkArea.Left())
|
|
{
|
|
rPt.X() = aMaxWorkArea.Left();
|
|
bRet = sal_True;
|
|
}
|
|
|
|
if(rPt.X()>aMaxWorkArea.Right())
|
|
{
|
|
rPt.X() = aMaxWorkArea.Right();
|
|
bRet = sal_True;
|
|
}
|
|
|
|
if(rPt.Y()<aMaxWorkArea.Top())
|
|
{
|
|
rPt.Y() = aMaxWorkArea.Top();
|
|
bRet = sal_True;
|
|
}
|
|
|
|
if(rPt.Y()>aMaxWorkArea.Bottom())
|
|
{
|
|
rPt.Y() = aMaxWorkArea.Bottom();
|
|
bRet = sal_True;
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
void SdrExchangeView::ImpGetPasteObjList(Point& /*rPos*/, SdrObjList*& rpLst)
|
|
{
|
|
if (rpLst==NULL)
|
|
{
|
|
SdrPageView* pPV = GetSdrPageView();
|
|
|
|
if (pPV!=NULL) {
|
|
rpLst=pPV->GetObjList();
|
|
}
|
|
}
|
|
}
|
|
|
|
sal_Bool SdrExchangeView::ImpGetPasteLayer(const SdrObjList* pObjList, SdrLayerID& rLayer) const
|
|
{
|
|
sal_Bool bRet=sal_False;
|
|
rLayer=0;
|
|
if (pObjList!=NULL) {
|
|
const SdrPage* pPg=pObjList->GetPage();
|
|
if (pPg!=NULL) {
|
|
rLayer=pPg->GetLayerAdmin().GetLayerID(aAktLayer,sal_True);
|
|
if (rLayer==SDRLAYER_NOTFOUND) rLayer=0;
|
|
SdrPageView* pPV = GetSdrPageView();
|
|
if (pPV!=NULL) {
|
|
bRet=!pPV->GetLockedLayers().IsSet(rLayer) && pPV->GetVisibleLayers().IsSet(rLayer);
|
|
}
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
sal_Bool SdrExchangeView::Paste(const XubString& rStr, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
|
|
{
|
|
if(!rStr.Len())
|
|
return sal_False;
|
|
|
|
Point aPos(rPos);
|
|
ImpGetPasteObjList(aPos,pLst);
|
|
ImpLimitToWorkArea( aPos );
|
|
if (pLst==NULL) return sal_False;
|
|
SdrLayerID nLayer;
|
|
if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
|
|
sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
|
|
if (bUnmark) UnmarkAllObj();
|
|
Rectangle aTextRect(0,0,500,500);
|
|
SdrPage* pPage=pLst->GetPage();
|
|
if (pPage!=NULL) {
|
|
aTextRect.SetSize(pPage->GetSize());
|
|
}
|
|
SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
|
|
pObj->SetModel(pMod);
|
|
pObj->SetLayer(nLayer);
|
|
pObj->NbcSetText(rStr); // SetText before SetAttr, else SetAttr doesn't work!
|
|
if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
|
|
|
|
pObj->SetMergedItemSet(aDefaultAttr);
|
|
|
|
SfxItemSet aTempAttr(pMod->GetItemPool()); // no fill, no line
|
|
aTempAttr.Put(XLineStyleItem(XLINE_NONE));
|
|
aTempAttr.Put(XFillStyleItem(XFILL_NONE));
|
|
|
|
pObj->SetMergedItemSet(aTempAttr);
|
|
|
|
pObj->FitFrameToTextSize();
|
|
Size aSiz(pObj->GetLogicRect().GetSize());
|
|
MapUnit eMap=pMod->GetScaleUnit();
|
|
Fraction aMap=pMod->GetScaleFraction();
|
|
ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
|
|
return sal_True;
|
|
}
|
|
|
|
sal_Bool SdrExchangeView::Paste(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
|
|
{
|
|
Point aPos(rPos);
|
|
ImpGetPasteObjList(aPos,pLst);
|
|
ImpLimitToWorkArea( aPos );
|
|
if (pLst==NULL) return sal_False;
|
|
SdrLayerID nLayer;
|
|
if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
|
|
sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
|
|
if (bUnmark) UnmarkAllObj();
|
|
Rectangle aTextRect(0,0,500,500);
|
|
SdrPage* pPage=pLst->GetPage();
|
|
if (pPage!=NULL) {
|
|
aTextRect.SetSize(pPage->GetSize());
|
|
}
|
|
SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
|
|
pObj->SetModel(pMod);
|
|
pObj->SetLayer(nLayer);
|
|
if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
|
|
|
|
pObj->SetMergedItemSet(aDefaultAttr);
|
|
|
|
SfxItemSet aTempAttr(pMod->GetItemPool()); // no fill, no line
|
|
aTempAttr.Put(XLineStyleItem(XLINE_NONE));
|
|
aTempAttr.Put(XFillStyleItem(XFILL_NONE));
|
|
|
|
pObj->SetMergedItemSet(aTempAttr);
|
|
|
|
pObj->NbcSetText(rInput,rBaseURL,eFormat);
|
|
pObj->FitFrameToTextSize();
|
|
Size aSiz(pObj->GetLogicRect().GetSize());
|
|
MapUnit eMap=pMod->GetScaleUnit();
|
|
Fraction aMap=pMod->GetScaleFraction();
|
|
ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
|
|
|
|
// b4967543
|
|
if(pObj && pObj->GetModel() && pObj->GetOutlinerParaObject())
|
|
{
|
|
SdrOutliner& rOutliner = pObj->GetModel()->GetHitTestOutliner();
|
|
rOutliner.SetText(*pObj->GetOutlinerParaObject());
|
|
|
|
if(1L == rOutliner.GetParagraphCount())
|
|
{
|
|
SfxStyleSheet* pCandidate = rOutliner.GetStyleSheet(0L);
|
|
|
|
if(pCandidate)
|
|
{
|
|
if(pObj->GetModel()->GetStyleSheetPool() == &pCandidate->GetPool())
|
|
{
|
|
pObj->NbcSetStyleSheet(pCandidate, sal_True);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return sal_True;
|
|
}
|
|
|
|
sal_Bool SdrExchangeView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
|
|
{
|
|
const SdrModel* pSrcMod=&rMod;
|
|
if (pSrcMod==pMod)
|
|
return sal_False; // this can't work, right?
|
|
|
|
const bool bUndo = IsUndoEnabled();
|
|
|
|
if( bUndo )
|
|
BegUndo(ImpGetResStr(STR_ExchangePaste));
|
|
|
|
if( mxSelectionController.is() && mxSelectionController->PasteObjModel( rMod ) )
|
|
{
|
|
if( bUndo )
|
|
EndUndo();
|
|
return sal_True;
|
|
}
|
|
|
|
Point aPos(rPos);
|
|
ImpGetPasteObjList(aPos,pLst);
|
|
SdrPageView* pMarkPV=NULL;
|
|
SdrPageView* pPV = GetSdrPageView();
|
|
|
|
if(pPV)
|
|
{
|
|
if ( pPV->GetObjList() == pLst )
|
|
pMarkPV=pPV;
|
|
}
|
|
|
|
ImpLimitToWorkArea( aPos );
|
|
if (pLst==NULL)
|
|
return sal_False;
|
|
|
|
sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
|
|
if (bUnmark)
|
|
UnmarkAllObj();
|
|
|
|
// Rescale, if the Model uses a different MapUnit.
|
|
// Calculate the necessary factors first.
|
|
MapUnit eSrcUnit=pSrcMod->GetScaleUnit();
|
|
MapUnit eDstUnit=pMod->GetScaleUnit();
|
|
sal_Bool bResize=eSrcUnit!=eDstUnit;
|
|
Fraction xResize,yResize;
|
|
Point aPt0;
|
|
if (bResize)
|
|
{
|
|
FrPair aResize(GetMapFactor(eSrcUnit,eDstUnit));
|
|
xResize=aResize.X();
|
|
yResize=aResize.Y();
|
|
}
|
|
SdrObjList* pDstLst=pLst;
|
|
sal_uInt16 nPg,nPgAnz=pSrcMod->GetPageCount();
|
|
for (nPg=0; nPg<nPgAnz; nPg++)
|
|
{
|
|
const SdrPage* pSrcPg=pSrcMod->GetPage(nPg);
|
|
|
|
// Use SnapRect, not BoundRect here
|
|
Rectangle aR=pSrcPg->GetAllObjSnapRect();
|
|
|
|
if (bResize)
|
|
ResizeRect(aR,aPt0,xResize,yResize);
|
|
Point aDist(aPos-aR.Center());
|
|
Size aSiz(aDist.X(),aDist.Y());
|
|
sal_uIntPtr nCloneErrCnt=0;
|
|
sal_uIntPtr nOb,nObAnz=pSrcPg->GetObjCount();
|
|
sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
|
|
|
|
// #i13033#
|
|
// New mechanism to re-create the connections of cloned connectors
|
|
CloneList aCloneList;
|
|
|
|
for (nOb=0; nOb<nObAnz; nOb++)
|
|
{
|
|
const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);
|
|
|
|
SdrObject* pNeuObj = pSrcOb->Clone();
|
|
|
|
if (pNeuObj!=NULL)
|
|
{
|
|
if(bResize)
|
|
{
|
|
pNeuObj->GetModel()->SetPasteResize(sal_True);
|
|
pNeuObj->NbcResize(aPt0,xResize,yResize);
|
|
pNeuObj->GetModel()->SetPasteResize(sal_False);
|
|
}
|
|
|
|
// #i39861#
|
|
pNeuObj->SetModel(pDstLst->GetModel());
|
|
pNeuObj->SetPage(pDstLst->GetPage());
|
|
|
|
pNeuObj->NbcMove(aSiz);
|
|
|
|
const SdrPage* pPg = pDstLst->GetPage();
|
|
|
|
if(pPg)
|
|
{
|
|
// #i72535#
|
|
const SdrLayerAdmin& rAd = pPg->GetLayerAdmin();
|
|
SdrLayerID nLayer(0);
|
|
|
|
if(pNeuObj->ISA(FmFormObj))
|
|
{
|
|
// for FormControls, force to form layer
|
|
nLayer = rAd.GetLayerID(rAd.GetControlLayerName(), true);
|
|
}
|
|
else
|
|
{
|
|
nLayer = rAd.GetLayerID(aAktLayer, sal_True);
|
|
}
|
|
|
|
if(SDRLAYER_NOTFOUND == nLayer)
|
|
{
|
|
nLayer = 0;
|
|
}
|
|
|
|
pNeuObj->SetLayer(nLayer);
|
|
}
|
|
|
|
SdrInsertReason aReason(SDRREASON_VIEWCALL);
|
|
pDstLst->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
|
|
|
|
if( bUndo )
|
|
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNeuObj));
|
|
|
|
if (bMark) {
|
|
// Don't already set Markhandles!
|
|
// That is instead being done by ModelHasChanged in MarkView.
|
|
MarkObj(pNeuObj,pMarkPV,sal_False,sal_True);
|
|
}
|
|
|
|
// #i13033#
|
|
aCloneList.AddPair(pSrcOb, pNeuObj);
|
|
}
|
|
else
|
|
{
|
|
nCloneErrCnt++;
|
|
}
|
|
}
|
|
|
|
// #i13033#
|
|
// New mechanism to re-create the connections of cloned connectors
|
|
aCloneList.CopyConnections();
|
|
|
|
if(0L != nCloneErrCnt)
|
|
{
|
|
#ifdef DBG_UTIL
|
|
rtl::OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM(
|
|
"SdrExchangeView::Paste(): Error when cloning "));
|
|
|
|
if(nCloneErrCnt == 1)
|
|
{
|
|
aStr.append(RTL_CONSTASCII_STRINGPARAM(
|
|
"a drawing object."));
|
|
}
|
|
else
|
|
{
|
|
aStr.append(static_cast<sal_Int32>(nCloneErrCnt));
|
|
aStr.append(RTL_CONSTASCII_STRINGPARAM(" drawing objects."));
|
|
}
|
|
|
|
aStr.append(RTL_CONSTASCII_STRINGPARAM(
|
|
" Not copying object connectors."));
|
|
|
|
OSL_FAIL(aStr.getStr());
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if( bUndo )
|
|
EndUndo();
|
|
|
|
return sal_True;
|
|
}
|
|
|
|
void SdrExchangeView::ImpPasteObject(SdrObject* pObj, SdrObjList& rLst, const Point& rCenter, const Size& rSiz, const MapMode& rMap, sal_uInt32 nOptions)
|
|
{
|
|
BigInt nSizX(rSiz.Width());
|
|
BigInt nSizY(rSiz.Height());
|
|
MapUnit eSrcMU=rMap.GetMapUnit();
|
|
MapUnit eDstMU=pMod->GetScaleUnit();
|
|
FrPair aMapFact(GetMapFactor(eSrcMU,eDstMU));
|
|
Fraction aDstFr(pMod->GetScaleFraction());
|
|
nSizX*=aMapFact.X().GetNumerator();
|
|
nSizX*=rMap.GetScaleX().GetNumerator();
|
|
nSizX*=aDstFr.GetDenominator();
|
|
nSizX/=aMapFact.X().GetDenominator();
|
|
nSizX/=rMap.GetScaleX().GetDenominator();
|
|
nSizX/=aDstFr.GetNumerator();
|
|
nSizY*=aMapFact.Y().GetNumerator();
|
|
nSizY*=rMap.GetScaleY().GetNumerator();
|
|
nSizX*=aDstFr.GetDenominator();
|
|
nSizY/=aMapFact.Y().GetDenominator();
|
|
nSizY/=rMap.GetScaleY().GetDenominator();
|
|
nSizY/=aDstFr.GetNumerator();
|
|
long xs=nSizX;
|
|
long ys=nSizY;
|
|
Point aPos(rCenter.X()-xs/2,rCenter.Y()-ys/2);
|
|
Rectangle aR(aPos.X(),aPos.Y(),aPos.X()+xs,aPos.Y()+ys);
|
|
pObj->SetLogicRect(aR);
|
|
SdrInsertReason aReason(SDRREASON_VIEWCALL);
|
|
rLst.InsertObject(pObj,CONTAINER_APPEND,&aReason);
|
|
|
|
if( IsUndoEnabled() )
|
|
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
|
|
|
|
SdrPageView* pMarkPV=NULL;
|
|
SdrPageView* pPV = GetSdrPageView();
|
|
|
|
if(pPV)
|
|
{
|
|
if (pPV->GetObjList()==&rLst)
|
|
pMarkPV=pPV;
|
|
}
|
|
|
|
sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
|
|
if (bMark)
|
|
{ // select object the first PageView we found
|
|
MarkObj(pObj,pMarkPV);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Bitmap SdrExchangeView::GetMarkedObjBitmap( sal_Bool bNoVDevIfOneBmpMarked ) const
|
|
{
|
|
Bitmap aBmp;
|
|
|
|
if( AreObjectsMarked() )
|
|
{
|
|
if( bNoVDevIfOneBmpMarked )
|
|
{
|
|
SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
|
|
SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
|
|
|
|
if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) )
|
|
aBmp = pGrafObj->GetTransformedGraphic().GetBitmap();
|
|
}
|
|
|
|
if( !aBmp )
|
|
{
|
|
const Graphic aGraphic( GetMarkedObjMetaFile( bNoVDevIfOneBmpMarked ) );
|
|
|
|
// #i102089# support user's settings of AA and LineSnap when the MetaFile gets
|
|
// raster-converted to a bitmap
|
|
const SvtOptionsDrawinglayer aDrawinglayerOpt;
|
|
const GraphicConversionParameters aParameters(
|
|
Size(),
|
|
false,
|
|
aDrawinglayerOpt.IsAntiAliasing(),
|
|
aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete());
|
|
|
|
aBmp = aGraphic.GetBitmap(aParameters);
|
|
}
|
|
}
|
|
|
|
return aBmp;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile( sal_Bool bNoVDevIfOneMtfMarked ) const
|
|
{
|
|
GDIMetaFile aMtf;
|
|
|
|
if( AreObjectsMarked() )
|
|
{
|
|
Rectangle aBound( GetMarkedObjBoundRect() );
|
|
Size aBoundSize( aBound.GetWidth(), aBound.GetHeight() );
|
|
MapMode aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() );
|
|
|
|
if( bNoVDevIfOneMtfMarked )
|
|
{
|
|
SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
|
|
SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
|
|
|
|
if( pGrafObj )
|
|
{
|
|
Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
|
|
|
|
if( aGraphic.GetType() == GRAPHIC_BITMAP )
|
|
{
|
|
const Point aPos;
|
|
|
|
aMtf.AddAction( new MetaBmpExScaleAction( aPos, aBoundSize, aGraphic.GetBitmapEx() ) );
|
|
aMtf.SetPrefMapMode( aMap );
|
|
aMtf.SetPrefSize( aBoundSize );
|
|
}
|
|
else
|
|
aMtf = aGraphic.GetGDIMetaFile();
|
|
}
|
|
}
|
|
|
|
if( !aMtf.GetActionSize() )
|
|
{
|
|
VirtualDevice aOut;
|
|
Size aDummySize( 2, 2 );
|
|
|
|
aOut.SetOutputSizePixel( aDummySize );
|
|
aOut.EnableOutput( sal_False );
|
|
aOut.SetMapMode( aMap );
|
|
|
|
aMtf.Clear();
|
|
aMtf.Record( &aOut );
|
|
|
|
// Replace offset given formally to DrawMarkedObj and used at XOutDev with relative
|
|
// MapMode (which was also used in XOutDev in that case). Goal is to paint the object
|
|
// as if TopLeft point is (0,0)
|
|
const Fraction aNeutralFraction(1, 1);
|
|
const MapMode aRelativeMapMode(MAP_RELATIVE, Point(-aBound.Left(), -aBound.Top()), aNeutralFraction, aNeutralFraction);
|
|
aOut.SetMapMode(aRelativeMapMode);
|
|
|
|
DrawMarkedObj(aOut);
|
|
|
|
aMtf.Stop();
|
|
aMtf.WindStart();
|
|
aMtf.SetPrefMapMode( aMap );
|
|
|
|
// removed PrefSize extension. It is principally wrong to set a reduced size at
|
|
// the created MetaFile. The mentioned errors occur at output time since the integer
|
|
// MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for
|
|
// primitives (and may later be done in breaking up a MetaFile to primitives)
|
|
aMtf.SetPrefSize(aBoundSize);
|
|
}
|
|
}
|
|
|
|
return aMtf;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
Graphic SdrExchangeView::GetAllMarkedGraphic() const
|
|
{
|
|
Graphic aRet;
|
|
|
|
if( AreObjectsMarked() )
|
|
{
|
|
if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) )
|
|
aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) );
|
|
else
|
|
aRet = GetMarkedObjMetaFile( sal_False );
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj )
|
|
{
|
|
Graphic aRet;
|
|
|
|
if( pModel && pObj )
|
|
{
|
|
// try to get a graphic from the object first
|
|
const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
|
|
const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
|
|
|
|
if(pSdrGrafObj)
|
|
{
|
|
// Make behaviour coherent with metafile
|
|
// recording below (which of course also takes
|
|
// view-transformed objects)
|
|
aRet = pSdrGrafObj->GetTransformedGraphic();
|
|
}
|
|
else if(pSdrOle2Obj)
|
|
{
|
|
if ( pSdrOle2Obj->GetGraphic() )
|
|
aRet = *pSdrOle2Obj->GetGraphic();
|
|
}
|
|
|
|
// if graphic could not be retrieved => go the hard way and create a MetaFile
|
|
if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) )
|
|
{
|
|
VirtualDevice aOut;
|
|
GDIMetaFile aMtf;
|
|
const Rectangle aBoundRect( pObj->GetCurrentBoundRect() );
|
|
const MapMode aMap( pModel->GetScaleUnit(),
|
|
Point(),
|
|
pModel->GetScaleFraction(),
|
|
pModel->GetScaleFraction() );
|
|
|
|
aOut.EnableOutput( sal_False );
|
|
aOut.SetMapMode( aMap );
|
|
aMtf.Record( &aOut );
|
|
pObj->SingleObjectPainter( aOut );
|
|
aMtf.Stop();
|
|
aMtf.WindStart();
|
|
|
|
// #i99268# replace the original offset from using XOutDev's SetOffset
|
|
// NOT (as tried with #i92760#) with another MapMode which gets recorded
|
|
// by the Metafile itself (what always leads to problems), but by hardly
|
|
// moving the result
|
|
aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
|
|
|
|
aMtf.SetPrefMapMode( aMap );
|
|
aMtf.SetPrefSize( aBoundRect.GetSize() );
|
|
|
|
if( aMtf.GetActionSize() )
|
|
aRet = aMtf;
|
|
}
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const
|
|
{
|
|
SortMarkedObjects();
|
|
|
|
::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 );
|
|
::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ];
|
|
::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ];
|
|
const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin();
|
|
const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
|
|
sal_uInt32 n, nCount;
|
|
|
|
for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
|
|
{
|
|
SdrMark* pMark = GetSdrMarkByIndex( n );
|
|
|
|
// paint objects on control layer on top of all other objects
|
|
if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
|
|
rObjVector2.push_back( pMark );
|
|
else
|
|
rObjVector1.push_back( pMark );
|
|
}
|
|
|
|
for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
|
|
{
|
|
::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
|
|
|
|
for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
|
|
{
|
|
SdrMark* pMark = rObjVector[ i ];
|
|
pMark->GetMarkedSdrObj()->SingleObjectPainter( rOut );
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
SdrModel* SdrExchangeView::GetMarkedObjModel() const
|
|
{
|
|
// Sorting the MarkList here might be problematic in the future, so
|
|
// use a copy.
|
|
SortMarkedObjects();
|
|
SdrModel* pNeuMod=pMod->AllocModel();
|
|
SdrPage* pNeuPag=pNeuMod->AllocPage(sal_False);
|
|
pNeuMod->InsertPage(pNeuPag);
|
|
|
|
if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) )
|
|
{
|
|
::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 );
|
|
::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ];
|
|
::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ];
|
|
const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin();
|
|
const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
|
|
sal_uInt32 n, nCount, nCloneErrCnt = 0;
|
|
|
|
for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
|
|
{
|
|
SdrMark* pMark = GetSdrMarkByIndex( n );
|
|
|
|
// paint objects on control layer on top of all otherobjects
|
|
if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
|
|
rObjVector2.push_back( pMark );
|
|
else
|
|
rObjVector1.push_back( pMark );
|
|
}
|
|
|
|
// #i13033#
|
|
// New mechanism to re-create the connections of cloned connectors
|
|
CloneList aCloneList;
|
|
|
|
for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
|
|
{
|
|
::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
|
|
|
|
for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
|
|
{
|
|
const SdrMark* pMark = rObjVector[ i ];
|
|
const SdrObject* pObj = pMark->GetMarkedSdrObj();
|
|
SdrObject* pNeuObj;
|
|
|
|
if( pObj->ISA( SdrPageObj ) )
|
|
{
|
|
// convert SdrPageObj's to a graphic representation, because
|
|
// virtual connection to referenced page gets lost in new model
|
|
pNeuObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() );
|
|
pNeuObj->SetPage( pNeuPag );
|
|
pNeuObj->SetModel( pNeuMod );
|
|
}
|
|
else
|
|
{
|
|
pNeuObj = pObj->Clone();
|
|
pNeuObj->SetPage( pNeuPag );
|
|
pNeuObj->SetModel( pNeuMod );
|
|
}
|
|
|
|
if( pNeuObj )
|
|
{
|
|
SdrInsertReason aReason(SDRREASON_VIEWCALL);
|
|
pNeuPag->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
|
|
|
|
// #i13033#
|
|
aCloneList.AddPair(pObj, pNeuObj);
|
|
}
|
|
else
|
|
nCloneErrCnt++;
|
|
}
|
|
}
|
|
|
|
// #i13033#
|
|
// New mechanism to re-create the connections of cloned connectors
|
|
aCloneList.CopyConnections();
|
|
|
|
if(0L != nCloneErrCnt)
|
|
{
|
|
#ifdef DBG_UTIL
|
|
rtl::OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM(
|
|
"SdrExchangeView::GetMarkedObjModel(): Error when cloning "));
|
|
|
|
if(nCloneErrCnt == 1)
|
|
{
|
|
aStr.append(RTL_CONSTASCII_STRINGPARAM(
|
|
"a drawing object."));
|
|
}
|
|
else
|
|
{
|
|
aStr.append(static_cast<sal_Int32>(nCloneErrCnt));
|
|
aStr.append(RTL_CONSTASCII_STRINGPARAM(" drawing objects."));
|
|
}
|
|
|
|
aStr.append(RTL_CONSTASCII_STRINGPARAM(
|
|
" Not copying object connectors."));
|
|
|
|
OSL_FAIL(aStr.getStr());
|
|
#endif
|
|
}
|
|
}
|
|
return pNeuMod;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */)
|
|
{
|
|
OSL_FAIL( "SdrExchangeView::Cut: Not supported any more." );
|
|
return sal_False;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/)
|
|
{
|
|
OSL_FAIL( "SdrExchangeView::Yank: Not supported any more." );
|
|
return sal_False;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/)
|
|
{
|
|
OSL_FAIL( "SdrExchangeView::Paste: Not supported any more." );
|
|
return sal_False;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|