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