| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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> |
| #include <clonelist.hxx> |
| #include <vcl/virdev.hxx> |
| #include <svl/style.hxx> |
| #include <fmobj.hxx> |
| #include <vcl/svgdata.hxx> |
| #include <drawinglayer/primitive2d/baseprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/groupprimitive2d.hxx> |
| #include <drawinglayer/geometry/viewinformation2d.hxx> |
| #include <svx/sdr/contact/viewcontact.hxx> |
| #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> |
| #include <svx/sdr/contact/displayinfo.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); |
| } |
| } |
| |
| BitmapEx SdrExchangeView::GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked) const |
| { |
| BitmapEx aBmp; |
| |
| if( AreObjectsMarked() ) |
| { |
| if(1 == GetMarkedObjectCount()) |
| { |
| if(bNoVDevIfOneBmpMarked) |
| { |
| SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 ); |
| SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL; |
| |
| if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) ) |
| { |
| aBmp = pGrafObj->GetTransformedGraphic().GetBitmapEx(); |
| } |
| } |
| else |
| { |
| const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(GetMarkedObjectByIndex(0)); |
| |
| if(pSdrGrafObj && pSdrGrafObj->isEmbeddedSvg()) |
| { |
| aBmp = pSdrGrafObj->GetGraphic().getSvgData()->getReplacement(); |
| } |
| } |
| } |
| |
| if( !aBmp ) |
| { |
| // choose conversion directly using primitives to bitmap to avoid |
| // rendering errors with tiled bitmap fills (these will be tiled in a |
| // in-between metafile, but tend to show 'gaps' since the target is *no* |
| // bitmap rendering) |
| ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects()); |
| const sal_uInt32 nCount(aSdrObjects.size()); |
| |
| if(nCount) |
| { |
| // collect sub-primitives as group objects, thus no expensive append |
| // to existing sequence is needed |
| drawinglayer::primitive2d::Primitive2DSequence xPrimitives(nCount); |
| |
| for(sal_uInt32 a(0); a < nCount; a++) |
| { |
| SdrObject* pCandidate = aSdrObjects[a]; |
| SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pCandidate); |
| |
| if(pSdrGrafObj) |
| { |
| // #122753# To ensure existance of graphic content, force swap in |
| pSdrGrafObj->ForceSwapIn(); |
| } |
| |
| xPrimitives[a] = new drawinglayer::primitive2d::GroupPrimitive2D( |
| pCandidate->GetViewContact().getViewIndependentPrimitive2DSequence()); |
| } |
| |
| // get logic range |
| const drawinglayer::geometry::ViewInformation2D aViewInformation2D; |
| const basegfx::B2DRange aRange( |
| drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence( |
| xPrimitives, |
| aViewInformation2D)); |
| |
| if(!aRange.isEmpty()) |
| { |
| // if we have geometry and it has a range, convert to BitmapEx using |
| // common tooling |
| aBmp = convertPrimitive2DSequenceToBitmapEx( |
| xPrimitives, |
| aRange, |
| 500000); |
| } |
| } |
| } |
| } |
| |
| return aBmp; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(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() ); |
| |
| // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically |
| aMtf = aGraphic.GetGDIMetaFile(); |
| } |
| } |
| |
| if( !aMtf.GetActionCount() ) |
| { |
| VirtualDevice aOut; |
| const Size aDummySize(2, 2); |
| |
| aOut.SetOutputSizePixel(aDummySize); |
| aOut.EnableOutput(false); |
| aOut.SetMapMode(aMap); |
| aMtf.Clear(); |
| aMtf.Record(&aOut); |
| |
| DrawMarkedObj(aOut); |
| |
| aMtf.Stop(); |
| aMtf.WindStart(); |
| |
| // moving the result is more reliable then setting a relative MapMode at the VDev (used |
| // before), also see #i99268# in GetObjGraphic() below. Some draw actions at |
| // the OutDev are simply not handled correctly when a MapMode is set at the |
| // target devive, e.g. MetaFloatTransparentAction. Even the Move for this action |
| // was missing the manipulation of the embedded Metafile |
| aMtf.Move(-aBound.Left(), -aBound.Top()); |
| |
| 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(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) |
| { |
| if(pSdrGrafObj->isEmbeddedSvg()) |
| { |
| // get Metafile for Svg content |
| aRet = pSdrGrafObj->getMetafileFromEmbeddedSvg(); |
| } |
| else |
| { |
| // #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 |
| // moving the result directly |
| aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top()); |
| |
| aMtf.SetPrefMapMode( aMap ); |
| aMtf.SetPrefSize( aBoundRect.GetSize() ); |
| |
| if( aMtf.GetActionCount() ) |
| aRet = aMtf; |
| } |
| } |
| |
| return aRet; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| ::std::vector< SdrObject* > SdrExchangeView::GetMarkedObjects() const |
| { |
| SortMarkedObjects(); |
| ::std::vector< SdrObject* > aRetval; |
| |
| ::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 ]; |
| aRetval.push_back(pMark->GetMarkedSdrObj()); |
| } |
| } |
| |
| return aRetval; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const |
| { |
| ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects()); |
| |
| if(aSdrObjects.size()) |
| { |
| sdr::contact::ObjectContactOfObjListPainter aPainter(rOut, aSdrObjects, aSdrObjects[0]->GetPage()); |
| sdr::contact::DisplayInfo aDisplayInfo; |
| |
| // do processing |
| aPainter.ProcessDisplay(aDisplayInfo); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| 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< SdrObject* > aSdrObjects(GetMarkedObjects()); |
| |
| // #i13033# |
| // New mechanism to re-create the connections of cloned connectors |
| CloneList aCloneList; |
| sal_uInt32 nCloneErrCnt(0); |
| |
| for( sal_uInt32 i(0); i < aSdrObjects.size(); i++ ) |
| { |
| const SdrObject* pObj = aSdrObjects[i]; |
| 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; |
| } |
| |
| // eof |