diff options
Diffstat (limited to 'svx/source/svdraw/svdxcgv.cxx')
-rw-r--r-- | svx/source/svdraw/svdxcgv.cxx | 894 |
1 files changed, 894 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdxcgv.cxx b/svx/source/svdraw/svdxcgv.cxx new file mode 100644 index 000000000000..dd7275f9cfdc --- /dev/null +++ b/svx/source/svdraw/svdxcgv.cxx @@ -0,0 +1,894 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#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> // fuer kein OLE im SdrClipboardFormat +#include <svx/svdorect.hxx> +#include <svx/svdoedge.hxx> // fuer Konnektoren uebers Clipboard +#include <svx/svdopage.hxx> // fuer Konnektoren uebers Clipboard +#include <svx/svdpage.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdtrans.hxx> // Fuer GetMapFactor zum umskalieren bei PasteModel +#include "svx/svdstr.hrc" // Namen aus der 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> + +// b4967543 +#include <svl/style.hxx> + +// #i72535# +#include "fmobj.hxx" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut): + SdrObjEditView(pModel1,pOut) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Point SdrExchangeView::GetViewCenter(const OutputDevice* pOut) const +{ + Point aCenter; + if (pOut==NULL) + { + pOut = GetFirstOutputDevice(); + } + if (pOut!=NULL) { + Point aOfs=pOut->GetMapMode().GetOrigin(); + Size aOutSiz=pOut->GetOutputSize(); + aOutSiz.Width()/=2; + aOutSiz.Height()/=2; + aCenter.X()=aOutSiz.Width() -aOfs.X(); + aCenter.Y()=aOutSiz.Height()-aOfs.Y(); + } + return aCenter; +} + +Point SdrExchangeView::GetPastePos(SdrObjList* pLst, OutputDevice* pOut) +{ + Point aP(GetViewCenter(pOut)); + SdrPage* pPg=NULL; + if (pLst!=NULL) pPg=pLst->GetPage(); + if (pPg!=NULL) { + Size aSiz(pPg->GetSize()); + aP.X()=aSiz.Width()/2; + aP.Y()=aSiz.Height()/2; + } + return aP; +} + +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 GDIMetaFile& rMtf, 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(); + SdrGrafObj* pObj=new SdrGrafObj(Graphic(rMtf)); + pObj->SetLayer(nLayer); + ImpPasteObject(pObj,*pLst,aPos,rMtf.GetPrefSize(),rMtf.GetPrefMapMode(),nOptions); + return sal_True; +} + +sal_Bool SdrExchangeView::Paste(const Bitmap& rBmp, 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(); + SdrGrafObj* pObj=new SdrGrafObj(Graphic(rBmp)); + pObj->SetLayer(nLayer); + ImpPasteObject(pObj,*pLst,aPos,rBmp.GetSizePixel(),MapMode(MAP_PIXEL),nOptions); + return sal_True; +} + +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); // #32424# SetText vor SetAttr, weil SetAttr sonst unwirksam! + if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False); + + pObj->SetMergedItemSet(aDefaultAttr); + + SfxItemSet aTempAttr(pMod->GetItemPool()); // Keine Fuellung oder Linie + 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()); // Keine Fuellung oder Linie + 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; // na so geht's ja nun nicht + + 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(); + + // evtl. umskalieren bei unterschiedlicher MapUnit am Model + // Dafuer erstmal die Faktoren berechnen + 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); + + // #104148# 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 nDstObjAnz0=pDstLst->GetObjCount(); + 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); + + // #116235# + SdrObject* pNeuObj = pSrcOb->Clone(); + + if (pNeuObj!=NULL) + { + if(bResize) + { + pNeuObj->GetModel()->SetPasteResize(sal_True); // #51139# + pNeuObj->NbcResize(aPt0,xResize,yResize); + pNeuObj->GetModel()->SetPasteResize(sal_False); // #51139# + } + + // #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) { + // Markhandles noch nicht sofort setzen! + // Das erledigt das ModelHasChanged der 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 + ByteString aStr("SdrExchangeView::Paste(): Fehler beim Clonen "); + + if(nCloneErrCnt == 1) + { + aStr += "eines Zeichenobjekts."; + } + else + { + aStr += "von "; + aStr += ByteString::CreateFromInt32( nCloneErrCnt ); + aStr += " Zeichenobjekten."; + } + + aStr += " Objektverbindungen werden nicht mitkopiert."; + + DBG_ERROR(aStr.GetBuffer()); +#endif + } + } + + if( bUndo ) + EndUndo(); + + return sal_True; +} + +sal_Bool SdrExchangeView::IsExchangeFormatSupported(sal_uIntPtr nFormat) const +{ + return( FORMAT_PRIVATE == nFormat || + FORMAT_GDIMETAFILE == nFormat || + FORMAT_BITMAP == nFormat || + FORMAT_RTF == nFormat || + FORMAT_STRING == nFormat || + SOT_FORMATSTR_ID_DRAWING == nFormat || + SOT_FORMATSTR_ID_EDITENGINE == nFormat ); +} + +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) + { // Obj in der ersten gefundenen PageView markieren + 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 + // rasterconverted 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.GetActionCount() ) + { + 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 principially wrong to set a reduced size at + // the created MetaFile. The mentioned errors occurr 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) + { + // #110981# 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 ); // #110094#-17 + 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.GetActionCount() ) + 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 otherobjects + 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 ); // #110094#-17 + } + } +} + +// ----------------------------------------------------------------------------- + +SdrModel* SdrExchangeView::GetMarkedObjModel() const +{ + // Wenn das sortieren der MarkList mal stoeren sollte, + // werde ich sie mir wohl kopieren muessen. + 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 + { + // #116235# + // pNeuObj = pObj->Clone( pNeuPag, pNeuMod ); + 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 + ByteString aStr("SdrExchangeView::GetMarkedObjModel(): Fehler beim Clonen "); + + if(nCloneErrCnt == 1) + { + aStr += "eines Zeichenobjekts."; + } + else + { + aStr += "von "; + aStr += ByteString::CreateFromInt32( nCloneErrCnt ); + aStr += " Zeichenobjekten."; + } + + aStr += " Objektverbindungen werden nicht mitkopiert."; + + DBG_ERROR(aStr.GetBuffer()); +#endif + } + } + return pNeuMod; +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */) +{ + DBG_ERROR( "SdrExchangeView::Cut: Not supported anymore" ); + return sal_False; +} + +// ----------------------------------------------------------------------------- + +void SdrExchangeView::CutMarked( sal_uIntPtr /*nFormat */) +{ + DBG_ERROR( "SdrExchangeView::CutMarked: Not supported anymore" ); +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/) +{ + DBG_ERROR( "SdrExchangeView::Yank: Not supported anymore" ); + return sal_False; +} + +// ----------------------------------------------------------------------------- + +void SdrExchangeView::YankMarked(sal_uIntPtr /*nFormat*/) +{ + DBG_ERROR( "YankMarked: Not supported anymore" ); +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/) +{ + DBG_ERROR( "SdrExchangeView::Paste: Not supported anymore" ); + return sal_False; +} |