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