xref: /trunk/main/svx/source/svdraw/svdxcgv.cxx (revision 914d351e5f5b84e4342a86d6ab8d4aca7308b9bd)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svx.hxx"
24 
25 #include <vector>
26 #include <editeng/editeng.hxx>
27 #include <svx/xexch.hxx>
28 #include <svx/xflclit.hxx>
29 #include <svx/svdxcgv.hxx>
30 #include <svx/svdoutl.hxx>
31 #include <svx/svditext.hxx>
32 #include <svx/svdetc.hxx>
33 #include <svx/svdundo.hxx>
34 #include <svx/svdograf.hxx>
35 #include <svx/svdoole2.hxx> // für kein OLE im SdrClipboardFormat
36 #include <svx/svdorect.hxx>
37 #include <svx/svdoedge.hxx> // für Konnektoren uebers Clipboard
38 #include <svx/svdopage.hxx> // für Konnektoren uebers Clipboard
39 #include <svx/svdpage.hxx>
40 #include <svx/svdpagv.hxx>
41 #include <svx/svdtrans.hxx> // Für GetMapFactor zum umskalieren bei PasteModel
42 #include "svx/svdstr.hrc" // Names from resource
43 #include "svx/svdglob.hxx" // StringCache
44 #include "svx/xoutbmp.hxx"
45 #include <vcl/metaact.hxx>
46 #include <svl/poolitem.hxx>
47 #include <svl/itempool.hxx>
48 #include <tools/bigint.hxx>
49 #include <sot/formats.hxx>
50 #include <clonelist.hxx>
51 #include <vcl/virdev.hxx>
52 #include <svl/style.hxx>
53 #include <fmobj.hxx>
54 #include <vcl/svgdata.hxx>
55 #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
56 #include <drawinglayer/primitive2d/groupprimitive2d.hxx>
57 #include <drawinglayer/geometry/viewinformation2d.hxx>
58 #include <svx/sdr/contact/viewcontact.hxx>
59 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
60 #include <svx/sdr/contact/displayinfo.hxx>
61 
62 ////////////////////////////////////////////////////////////////////////////////////////////////////
63 
64 SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut):
65     SdrObjEditView(pModel1,pOut)
66 {
67 }
68 
69 ////////////////////////////////////////////////////////////////////////////////////////////////////
70 
71 Point SdrExchangeView::GetViewCenter(const OutputDevice* pOut) const
72 {
73     Point aCenter;
74     if (pOut==NULL)
75     {
76         pOut = GetFirstOutputDevice();
77     }
78     if (pOut!=NULL) {
79         Point aOfs=pOut->GetMapMode().GetOrigin();
80         Size aOutSiz=pOut->GetOutputSize();
81         aOutSiz.Width()/=2;
82         aOutSiz.Height()/=2;
83         aCenter.X()=aOutSiz.Width() -aOfs.X();
84         aCenter.Y()=aOutSiz.Height()-aOfs.Y();
85     }
86     return aCenter;
87 }
88 
89 Point SdrExchangeView::GetPastePos(SdrObjList* pLst, OutputDevice* pOut)
90 {
91     Point aP(GetViewCenter(pOut));
92     SdrPage* pPg=NULL;
93     if (pLst!=NULL) pPg=pLst->GetPage();
94     if (pPg!=NULL) {
95         Size aSiz(pPg->GetSize());
96         aP.X()=aSiz.Width()/2;
97         aP.Y()=aSiz.Height()/2;
98     }
99     return aP;
100 }
101 
102 sal_Bool SdrExchangeView::ImpLimitToWorkArea(Point& rPt) const
103 {
104     sal_Bool bRet(sal_False);
105 
106     if(!aMaxWorkArea.IsEmpty())
107     {
108         if(rPt.X()<aMaxWorkArea.Left())
109         {
110             rPt.X() = aMaxWorkArea.Left();
111             bRet = sal_True;
112         }
113 
114         if(rPt.X()>aMaxWorkArea.Right())
115         {
116             rPt.X() = aMaxWorkArea.Right();
117             bRet = sal_True;
118         }
119 
120         if(rPt.Y()<aMaxWorkArea.Top())
121         {
122             rPt.Y() = aMaxWorkArea.Top();
123             bRet = sal_True;
124         }
125 
126         if(rPt.Y()>aMaxWorkArea.Bottom())
127         {
128             rPt.Y() = aMaxWorkArea.Bottom();
129             bRet = sal_True;
130         }
131     }
132     return bRet;
133 }
134 
135 void SdrExchangeView::ImpGetPasteObjList(Point& /*rPos*/, SdrObjList*& rpLst)
136 {
137     if (rpLst==NULL)
138     {
139         SdrPageView* pPV = GetSdrPageView();
140 
141         if (pPV!=NULL) {
142             rpLst=pPV->GetObjList();
143         }
144     }
145 }
146 
147 sal_Bool SdrExchangeView::ImpGetPasteLayer(const SdrObjList* pObjList, SdrLayerID& rLayer) const
148 {
149     sal_Bool bRet=sal_False;
150     rLayer=0;
151     if (pObjList!=NULL) {
152         const SdrPage* pPg=pObjList->GetPage();
153         if (pPg!=NULL) {
154             rLayer=pPg->GetLayerAdmin().GetLayerID(aAktLayer,sal_True);
155             if (rLayer==SDRLAYER_NOTFOUND) rLayer=0;
156             SdrPageView* pPV = GetSdrPageView();
157             if (pPV!=NULL) {
158                 bRet=!pPV->GetLockedLayers().IsSet(rLayer) && pPV->GetVisibleLayers().IsSet(rLayer);
159             }
160         }
161     }
162     return bRet;
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////////////////////////
166 
167 sal_Bool SdrExchangeView::Paste(const GDIMetaFile& rMtf, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
168 {
169     Point aPos(rPos);
170     ImpGetPasteObjList(aPos,pLst);
171     ImpLimitToWorkArea( aPos );
172     if (pLst==NULL) return sal_False;
173     SdrLayerID nLayer;
174     if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
175     sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
176     if (bUnmark) UnmarkAllObj();
177     SdrGrafObj* pObj=new SdrGrafObj(Graphic(rMtf));
178     pObj->SetLayer(nLayer);
179     ImpPasteObject(pObj,*pLst,aPos,rMtf.GetPrefSize(),rMtf.GetPrefMapMode(),nOptions);
180     return sal_True;
181 }
182 
183 sal_Bool SdrExchangeView::Paste(const Bitmap& rBmp, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
184 {
185     Point aPos(rPos);
186     ImpGetPasteObjList(aPos,pLst);
187     ImpLimitToWorkArea( aPos );
188     if (pLst==NULL) return sal_False;
189     SdrLayerID nLayer;
190     if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
191     sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
192     if (bUnmark) UnmarkAllObj();
193     SdrGrafObj* pObj=new SdrGrafObj(Graphic(rBmp));
194     pObj->SetLayer(nLayer);
195     ImpPasteObject(pObj,*pLst,aPos,rBmp.GetSizePixel(),MapMode(MAP_PIXEL),nOptions);
196     return sal_True;
197 }
198 
199 sal_Bool SdrExchangeView::Paste(const XubString& rStr, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
200 {
201     if(!rStr.Len())
202         return sal_False;
203 
204     Point aPos(rPos);
205     ImpGetPasteObjList(aPos,pLst);
206     ImpLimitToWorkArea( aPos );
207     if (pLst==NULL) return sal_False;
208     SdrLayerID nLayer;
209     if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
210     sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
211     if (bUnmark) UnmarkAllObj();
212     Rectangle aTextRect(0,0,500,500);
213     SdrPage* pPage=pLst->GetPage();
214     if (pPage!=NULL) {
215         aTextRect.SetSize(pPage->GetSize());
216     }
217     SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
218     pObj->SetModel(pMod);
219     pObj->SetLayer(nLayer);
220     pObj->NbcSetText(rStr); // #32424# SetText vor SetAttr, weil SetAttr sonst unwirksam!
221     if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
222 
223     pObj->SetMergedItemSet(aDefaultAttr);
224 
225     SfxItemSet aTempAttr(pMod->GetItemPool()); // Keine Füllung oder Linie
226     aTempAttr.Put(XLineStyleItem(XLINE_NONE));
227     aTempAttr.Put(XFillStyleItem(XFILL_NONE));
228 
229     pObj->SetMergedItemSet(aTempAttr);
230 
231     pObj->FitFrameToTextSize();
232     Size aSiz(pObj->GetLogicRect().GetSize());
233     MapUnit eMap=pMod->GetScaleUnit();
234     Fraction aMap=pMod->GetScaleFraction();
235     ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
236     return sal_True;
237 }
238 
239 sal_Bool SdrExchangeView::Paste(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
240 {
241     Point aPos(rPos);
242     ImpGetPasteObjList(aPos,pLst);
243     ImpLimitToWorkArea( aPos );
244     if (pLst==NULL) return sal_False;
245     SdrLayerID nLayer;
246     if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
247     sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
248     if (bUnmark) UnmarkAllObj();
249     Rectangle aTextRect(0,0,500,500);
250     SdrPage* pPage=pLst->GetPage();
251     if (pPage!=NULL) {
252         aTextRect.SetSize(pPage->GetSize());
253     }
254     SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
255     pObj->SetModel(pMod);
256     pObj->SetLayer(nLayer);
257     if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
258 
259     pObj->SetMergedItemSet(aDefaultAttr);
260 
261     SfxItemSet aTempAttr(pMod->GetItemPool()); // Keine Füllung oder Linie
262     aTempAttr.Put(XLineStyleItem(XLINE_NONE));
263     aTempAttr.Put(XFillStyleItem(XFILL_NONE));
264 
265     pObj->SetMergedItemSet(aTempAttr);
266 
267     pObj->NbcSetText(rInput,rBaseURL,eFormat);
268     pObj->FitFrameToTextSize();
269     Size aSiz(pObj->GetLogicRect().GetSize());
270     MapUnit eMap=pMod->GetScaleUnit();
271     Fraction aMap=pMod->GetScaleFraction();
272     ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
273 
274     // b4967543
275     if(pObj && pObj->GetModel() && pObj->GetOutlinerParaObject())
276     {
277         SdrOutliner& rOutliner = pObj->GetModel()->GetHitTestOutliner();
278         rOutliner.SetText(*pObj->GetOutlinerParaObject());
279 
280         if(1L == rOutliner.GetParagraphCount())
281         {
282             SfxStyleSheet* pCandidate = rOutliner.GetStyleSheet(0L);
283 
284             if(pCandidate)
285             {
286                 if(pObj->GetModel()->GetStyleSheetPool() == &pCandidate->GetPool())
287                 {
288                     pObj->NbcSetStyleSheet(pCandidate, sal_True);
289                 }
290             }
291         }
292     }
293 
294     return sal_True;
295 }
296 
297 sal_Bool SdrExchangeView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
298 {
299     const SdrModel* pSrcMod=&rMod;
300     if (pSrcMod==pMod)
301         return sal_False; // na so geht's ja nun nicht
302 
303     const bool bUndo = IsUndoEnabled();
304 
305     if( bUndo )
306         BegUndo(ImpGetResStr(STR_ExchangePaste));
307 
308     if( mxSelectionController.is() && mxSelectionController->PasteObjModel( rMod ) )
309     {
310         if( bUndo )
311             EndUndo();
312         return sal_True;
313     }
314 
315     Point aPos(rPos);
316     ImpGetPasteObjList(aPos,pLst);
317     SdrPageView* pMarkPV=NULL;
318     SdrPageView* pPV = GetSdrPageView();
319 
320     if(pPV)
321     {
322         if ( pPV->GetObjList() == pLst )
323             pMarkPV=pPV;
324     }
325 
326     ImpLimitToWorkArea( aPos );
327     if (pLst==NULL)
328         return sal_False;
329 
330     sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
331     if (bUnmark)
332         UnmarkAllObj();
333 
334     // evtl. umskalieren bei unterschiedlicher MapUnit am Model
335     // Dafür erstmal die Faktoren berechnen
336     MapUnit eSrcUnit=pSrcMod->GetScaleUnit();
337     MapUnit eDstUnit=pMod->GetScaleUnit();
338     sal_Bool bResize=eSrcUnit!=eDstUnit;
339     Fraction xResize,yResize;
340     Point aPt0;
341     if (bResize)
342     {
343         FrPair aResize(GetMapFactor(eSrcUnit,eDstUnit));
344         xResize=aResize.X();
345         yResize=aResize.Y();
346     }
347     SdrObjList*  pDstLst=pLst;
348     sal_uInt16 nPg,nPgAnz=pSrcMod->GetPageCount();
349     for (nPg=0; nPg<nPgAnz; nPg++)
350     {
351         const SdrPage* pSrcPg=pSrcMod->GetPage(nPg);
352 
353         // #104148# Use SnapRect, not BoundRect here
354         Rectangle aR=pSrcPg->GetAllObjSnapRect();
355 
356         if (bResize)
357             ResizeRect(aR,aPt0,xResize,yResize);
358         Point aDist(aPos-aR.Center());
359         Size  aSiz(aDist.X(),aDist.Y());
360         //sal_uIntPtr nDstObjAnz0=pDstLst->GetObjCount();
361         sal_uIntPtr nCloneErrCnt=0;
362         sal_uIntPtr nOb,nObAnz=pSrcPg->GetObjCount();
363         sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
364 
365         // #i13033#
366         // New mechanism to re-create the connections of cloned connectors
367         CloneList aCloneList;
368 
369         for (nOb=0; nOb<nObAnz; nOb++)
370         {
371             const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);
372 
373             // #116235#
374             SdrObject* pNewObj = pSrcOb->Clone();
375 
376             if (pNewObj!=NULL)
377             {
378                 if(bResize)
379                 {
380                     pNewObj->GetModel()->SetPasteResize(sal_True); // #51139#
381                     pNewObj->NbcResize(aPt0,xResize,yResize);
382                     pNewObj->GetModel()->SetPasteResize(sal_False); // #51139#
383                 }
384 
385                 // #i39861#
386                 pNewObj->SetModel(pDstLst->GetModel());
387                 pNewObj->SetPage(pDstLst->GetPage());
388 
389                 pNewObj->NbcMove(aSiz);
390 
391                 const SdrPage* pPg = pDstLst->GetPage();
392 
393                 if(pPg)
394                 {
395                     // #i72535#
396                     const SdrLayerAdmin& rAd = pPg->GetLayerAdmin();
397                     SdrLayerID nLayer(0);
398 
399                     if(pNewObj->ISA(FmFormObj))
400                     {
401                         // for FormControls, force to form layer
402                         nLayer = rAd.GetLayerID(rAd.GetControlLayerName(), true);
403                     }
404                     else
405                     {
406                         nLayer = rAd.GetLayerID(aAktLayer, sal_True);
407                     }
408 
409                     if(SDRLAYER_NOTFOUND == nLayer)
410                     {
411                         nLayer = 0;
412                     }
413 
414                     pNewObj->SetLayer(nLayer);
415                 }
416 
417                 SdrInsertReason aReason(SDRREASON_VIEWCALL);
418                 pDstLst->InsertObject(pNewObj,CONTAINER_APPEND,&aReason);
419 
420                 if( bUndo )
421                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNewObj));
422 
423                 if (bMark) {
424                     // Markhandles noch nicht sofort setzen!
425                     // Das erledigt das ModelHasChanged der MarkView.
426                     MarkObj(pNewObj,pMarkPV,sal_False,sal_True);
427                 }
428 
429                 // #i13033#
430                 aCloneList.AddPair(pSrcOb, pNewObj);
431             }
432             else
433             {
434                 nCloneErrCnt++;
435             }
436         }
437 
438         // #i13033#
439         // New mechanism to re-create the connections of cloned connectors
440         aCloneList.CopyConnections();
441 
442         if(0L != nCloneErrCnt)
443         {
444 #ifdef DBG_UTIL
445             ByteString aStr("SdrExchangeView::Paste(): Fehler beim Clonen ");
446 
447             if(nCloneErrCnt == 1)
448             {
449                 aStr += "eines Zeichenobjekts.";
450             }
451             else
452             {
453                 aStr += "von ";
454                 aStr += ByteString::CreateFromInt32( nCloneErrCnt );
455                 aStr += " Zeichenobjekten.";
456             }
457 
458             aStr += " Objektverbindungen werden nicht mitkopiert.";
459 
460             DBG_ERROR(aStr.GetBuffer());
461 #endif
462         }
463     }
464 
465     if( bUndo )
466         EndUndo();
467 
468     return sal_True;
469 }
470 
471 sal_Bool SdrExchangeView::IsExchangeFormatSupported(sal_uIntPtr nFormat) const
472 {
473     return( FORMAT_PRIVATE == nFormat ||
474             FORMAT_GDIMETAFILE == nFormat ||
475             FORMAT_BITMAP == nFormat ||
476             FORMAT_RTF == nFormat ||
477             FORMAT_STRING == nFormat ||
478             SOT_FORMATSTR_ID_DRAWING == nFormat ||
479             SOT_FORMATSTR_ID_EDITENGINE == nFormat );
480 }
481 
482 void SdrExchangeView::ImpPasteObject(SdrObject* pObj, SdrObjList& rLst, const Point& rCenter, const Size& rSiz, const MapMode& rMap, sal_uInt32 nOptions)
483 {
484     BigInt nSizX(rSiz.Width());
485     BigInt nSizY(rSiz.Height());
486     MapUnit eSrcMU=rMap.GetMapUnit();
487     MapUnit eDstMU=pMod->GetScaleUnit();
488     FrPair aMapFact(GetMapFactor(eSrcMU,eDstMU));
489     Fraction aDstFr(pMod->GetScaleFraction());
490     nSizX*=aMapFact.X().GetNumerator();
491     nSizX*=rMap.GetScaleX().GetNumerator();
492     nSizX*=aDstFr.GetDenominator();
493     nSizX/=aMapFact.X().GetDenominator();
494     nSizX/=rMap.GetScaleX().GetDenominator();
495     nSizX/=aDstFr.GetNumerator();
496     nSizY*=aMapFact.Y().GetNumerator();
497     nSizY*=rMap.GetScaleY().GetNumerator();
498     nSizX*=aDstFr.GetDenominator();
499     nSizY/=aMapFact.Y().GetDenominator();
500     nSizY/=rMap.GetScaleY().GetDenominator();
501     nSizY/=aDstFr.GetNumerator();
502     long xs=nSizX;
503     long ys=nSizY;
504     Point aPos(rCenter.X()-xs/2,rCenter.Y()-ys/2);
505     Rectangle aR(aPos.X(),aPos.Y(),aPos.X()+xs,aPos.Y()+ys);
506     pObj->SetLogicRect(aR);
507     SdrInsertReason aReason(SDRREASON_VIEWCALL);
508     rLst.InsertObject(pObj,CONTAINER_APPEND,&aReason);
509 
510     if( IsUndoEnabled() )
511         AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
512 
513     SdrPageView* pMarkPV=NULL;
514     SdrPageView* pPV = GetSdrPageView();
515 
516     if(pPV)
517     {
518         if (pPV->GetObjList()==&rLst)
519             pMarkPV=pPV;
520     }
521 
522     sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
523     if (bMark)
524     { // Obj in der ersten gefundenen PageView markieren
525         MarkObj(pObj,pMarkPV);
526     }
527 }
528 
529 BitmapEx SdrExchangeView::GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked) const
530 {
531     BitmapEx aBmp;
532 
533     if( AreObjectsMarked() )
534     {
535         if(1 == GetMarkedObjectCount())
536         {
537             if(bNoVDevIfOneBmpMarked)
538             {
539                 SdrObject*  pGrafObjTmp = GetMarkedObjectByIndex( 0 );
540                 SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
541 
542                 if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) )
543                 {
544                     aBmp = pGrafObj->GetTransformedGraphic().GetBitmapEx();
545                 }
546             }
547             else
548             {
549                 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(GetMarkedObjectByIndex(0));
550 
551                 if(pSdrGrafObj && pSdrGrafObj->isEmbeddedSvg())
552                 {
553                     aBmp = pSdrGrafObj->GetGraphic().getSvgData()->getReplacement();
554                 }
555             }
556         }
557 
558         if( !aBmp )
559         {
560             // choose conversion directly using primitives to bitmap to avoid
561             // rendering errors with tiled bitmap fills (these will be tiled in a
562             // in-between metafile, but tend to show 'gaps' since the target is *no*
563             // bitmap rendering)
564             ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects());
565             const sal_uInt32 nCount(aSdrObjects.size());
566 
567             if(nCount)
568             {
569                 // collect sub-primitives as group objects, thus no expensive append
570                 // to existing sequence is needed
571                 drawinglayer::primitive2d::Primitive2DSequence xPrimitives(nCount);
572 
573                 for(sal_uInt32 a(0); a < nCount; a++)
574                 {
575                     SdrObject* pCandidate = aSdrObjects[a];
576                     SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pCandidate);
577 
578                     if(pSdrGrafObj)
579                     {
580                         // #122753# To ensure existence of graphic content, force swap in
581                         pSdrGrafObj->ForceSwapIn();
582                     }
583 
584                     xPrimitives[a] = new drawinglayer::primitive2d::GroupPrimitive2D(
585                         pCandidate->GetViewContact().getViewIndependentPrimitive2DSequence());
586                 }
587 
588                 // get logic range
589                 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
590                 const basegfx::B2DRange aRange(
591                     drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
592                         xPrimitives,
593                         aViewInformation2D));
594 
595                 if(!aRange.isEmpty())
596                 {
597                     // if we have geometry and it has a range, convert to BitmapEx using
598                     // common tooling
599                     aBmp = convertPrimitive2DSequenceToBitmapEx(
600                         xPrimitives,
601                         aRange,
602                         500000);
603                 }
604             }
605         }
606     }
607 
608     return aBmp;
609 }
610 
611 // -----------------------------------------------------------------------------
612 
613 GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) const
614 {
615     GDIMetaFile aMtf;
616 
617     if( AreObjectsMarked() )
618     {
619         Rectangle   aBound( GetMarkedObjBoundRect() );
620         Size        aBoundSize( aBound.GetWidth(), aBound.GetHeight() );
621         MapMode     aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() );
622 
623         if( bNoVDevIfOneMtfMarked )
624         {
625             SdrObject*  pGrafObjTmp = GetMarkedObjectByIndex( 0 );
626             SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
627 
628             if( pGrafObj )
629             {
630                 Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
631 
632                 // #119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
633                 aMtf = aGraphic.GetGDIMetaFile();
634             }
635         }
636 
637         if( !aMtf.GetActionCount() )
638         {
639             VirtualDevice aOut;
640             const Size aDummySize(2, 2);
641 
642             aOut.SetOutputSizePixel(aDummySize);
643             aOut.EnableOutput(false);
644             aOut.SetMapMode(aMap);
645             aMtf.Clear();
646             aMtf.Record(&aOut);
647 
648             DrawMarkedObj(aOut);
649 
650             aMtf.Stop();
651             aMtf.WindStart();
652 
653             // moving the result is more reliable then setting a relative MapMode at the VDev (used
654             // before), also see #i99268# in GetObjGraphic() below. Some draw actions at
655             // the OutDev are simply not handled correctly when a MapMode is set at the
656             // target device, e.g. MetaFloatTransparentAction. Even the Move for this action
657             // was missing the manipulation of the embedded Metafile
658             aMtf.Move(-aBound.Left(), -aBound.Top());
659 
660             aMtf.SetPrefMapMode( aMap );
661 
662             // removed PrefSize extension. It is principally wrong to set a reduced size at
663             // the created MetaFile. The mentioned errors occur at output time since the integer
664             // MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for
665             // primitives (and may later be done in breaking up a MetaFile to primitives)
666             aMtf.SetPrefSize(aBoundSize);
667         }
668     }
669 
670     return aMtf;
671 }
672 
673 // -----------------------------------------------------------------------------
674 
675 Graphic SdrExchangeView::GetAllMarkedGraphic() const
676 {
677     Graphic aRet;
678 
679     if( AreObjectsMarked() )
680     {
681         if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) )
682             aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) );
683         else
684             aRet = GetMarkedObjMetaFile(false);
685     }
686 
687     return aRet;
688 }
689 
690 // -----------------------------------------------------------------------------
691 
692 Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj )
693 {
694     Graphic aRet;
695 
696     if( pModel && pObj )
697     {
698         // try to get a graphic from the object first
699         const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
700         const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
701 
702         if(pSdrGrafObj)
703         {
704             if(pSdrGrafObj->isEmbeddedSvg())
705             {
706                 // get Metafile for Svg content
707                 aRet = pSdrGrafObj->getMetafileFromEmbeddedSvg();
708             }
709             else
710             {
711                 // #110981# Make behavior coherent with metafile
712                 // recording below (which of course also takes
713                 // view-transformed objects)
714                 aRet = pSdrGrafObj->GetTransformedGraphic();
715             }
716         }
717         else if(pSdrOle2Obj)
718         {
719             if ( pSdrOle2Obj->GetGraphic() )
720                 aRet = *pSdrOle2Obj->GetGraphic();
721         }
722 
723         // if graphic could not be retrieved => go the hard way and create a MetaFile
724         if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) )
725         {
726             VirtualDevice   aOut;
727             GDIMetaFile     aMtf;
728             const Rectangle aBoundRect( pObj->GetCurrentBoundRect() );
729             const MapMode   aMap( pModel->GetScaleUnit(),
730                                   Point(),
731                                   pModel->GetScaleFraction(),
732                                   pModel->GetScaleFraction() );
733 
734             aOut.EnableOutput( sal_False );
735             aOut.SetMapMode( aMap );
736             aMtf.Record( &aOut );
737             pObj->SingleObjectPainter( aOut ); // #110094#-17
738             aMtf.Stop();
739             aMtf.WindStart();
740 
741             // #i99268# replace the original offset from using XOutDev's SetOffset
742             // NOT (as tried with #i92760#) with another MapMode which gets recorded
743             // by the Metafile itself (what always leads to problems), but by
744             // moving the result directly
745             aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
746 
747             aMtf.SetPrefMapMode( aMap );
748             aMtf.SetPrefSize( aBoundRect.GetSize() );
749 
750             if( aMtf.GetActionCount() )
751                 aRet = aMtf;
752         }
753     }
754 
755     return aRet;
756 }
757 
758 // -----------------------------------------------------------------------------
759 
760 ::std::vector< SdrObject* > SdrExchangeView::GetMarkedObjects() const
761 {
762     SortMarkedObjects();
763     ::std::vector< SdrObject* > aRetval;
764 
765     ::std::vector< ::std::vector< SdrMark* > >  aObjVectors( 2 );
766     ::std::vector< SdrMark* >&                  rObjVector1 = aObjVectors[ 0 ];
767     ::std::vector< SdrMark* >&                  rObjVector2 = aObjVectors[ 1 ];
768     const SdrLayerAdmin&                        rLayerAdmin = pMod->GetLayerAdmin();
769     const sal_uInt32                            nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
770     sal_uInt32                                  n, nCount;
771 
772     for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
773     {
774         SdrMark* pMark = GetSdrMarkByIndex( n );
775 
776         // paint objects on control layer on top of all other objects
777         if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
778             rObjVector2.push_back( pMark );
779         else
780             rObjVector1.push_back( pMark );
781     }
782 
783     for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
784     {
785         ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
786 
787         for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
788         {
789             SdrMark*    pMark = rObjVector[ i ];
790             aRetval.push_back(pMark->GetMarkedSdrObj());
791         }
792     }
793 
794     return aRetval;
795 }
796 
797 // -----------------------------------------------------------------------------
798 
799 void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const
800 {
801     ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects());
802 
803     if(aSdrObjects.size())
804     {
805         sdr::contact::ObjectContactOfObjListPainter aPainter(rOut, aSdrObjects, aSdrObjects[0]->GetPage());
806         sdr::contact::DisplayInfo aDisplayInfo;
807 
808         // do processing
809         aPainter.ProcessDisplay(aDisplayInfo);
810     }
811 }
812 
813 // -----------------------------------------------------------------------------
814 
815 SdrModel* SdrExchangeView::GetMarkedObjModel() const
816 {
817     // Wenn das sortieren der MarkList mal stören sollte,
818     // werde ich sie mir wohl kopieren müssen.
819     SortMarkedObjects();
820     SdrModel* pNeuMod=pMod->AllocModel();
821     SdrPage* pNeuPag=pNeuMod->AllocPage(sal_False);
822     pNeuMod->InsertPage(pNeuPag);
823 
824     if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) )
825     {
826         ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects());
827 
828         // #i13033#
829         // New mechanism to re-create the connections of cloned connectors
830         CloneList aCloneList;
831         sal_uInt32 nCloneErrCnt(0);
832 
833         for( sal_uInt32 i(0); i < aSdrObjects.size(); i++ )
834         {
835             const SdrObject*    pObj = aSdrObjects[i];
836             SdrObject*          pNewObj;
837 
838             if( pObj->ISA( SdrPageObj ) )
839             {
840                 // convert SdrPageObj's to a graphic representation, because
841                 // virtual connection to referenced page gets lost in new model
842                 pNewObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() );
843                 pNewObj->SetPage( pNeuPag );
844                 pNewObj->SetModel( pNeuMod );
845             }
846             else
847             {
848                 // #116235#
849                 // pNewObj = pObj->Clone( pNeuPag, pNeuMod );
850                 pNewObj = pObj->Clone();
851                 pNewObj->SetPage( pNeuPag );
852                 pNewObj->SetModel( pNeuMod );
853             }
854 
855             if( pNewObj )
856             {
857                 SdrInsertReason aReason(SDRREASON_VIEWCALL);
858                 pNeuPag->InsertObject(pNewObj,CONTAINER_APPEND,&aReason);
859 
860                 // #i13033#
861                 aCloneList.AddPair(pObj, pNewObj);
862             }
863             else
864                 nCloneErrCnt++;
865         }
866 
867         // #i13033#
868         // New mechanism to re-create the connections of cloned connectors
869         aCloneList.CopyConnections();
870 
871         if(0L != nCloneErrCnt)
872         {
873 #ifdef DBG_UTIL
874             ByteString aStr("SdrExchangeView::GetMarkedObjModel(): Fehler beim Clonen ");
875 
876             if(nCloneErrCnt == 1)
877             {
878                 aStr += "eines Zeichenobjekts.";
879             }
880             else
881             {
882                 aStr += "von ";
883                 aStr += ByteString::CreateFromInt32( nCloneErrCnt );
884                 aStr += " Zeichenobjekten.";
885             }
886 
887             aStr += " Objektverbindungen werden nicht mitkopiert.";
888 
889             DBG_ERROR(aStr.GetBuffer());
890 #endif
891         }
892     }
893     return pNeuMod;
894 }
895 
896 // -----------------------------------------------------------------------------
897 
898 sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */)
899 {
900     DBG_ERROR( "SdrExchangeView::Cut: Not supported anymore" );
901     return sal_False;
902 }
903 
904 // -----------------------------------------------------------------------------
905 
906 void SdrExchangeView::CutMarked( sal_uIntPtr /*nFormat */)
907 {
908     DBG_ERROR( "SdrExchangeView::CutMarked: Not supported anymore" );
909 }
910 
911 // -----------------------------------------------------------------------------
912 
913 sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/)
914 {
915     DBG_ERROR( "SdrExchangeView::Yank: Not supported anymore" );
916     return sal_False;
917 }
918 
919 // -----------------------------------------------------------------------------
920 
921 void SdrExchangeView::YankMarked(sal_uIntPtr /*nFormat*/)
922 {
923     DBG_ERROR( "YankMarked: Not supported anymore" );
924 }
925 
926 // -----------------------------------------------------------------------------
927 
928 sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/)
929 {
930     DBG_ERROR( "SdrExchangeView::Paste: Not supported anymore" );
931     return sal_False;
932 }
933 
934 /* vim: set noet sw=4 ts=4: */
935