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