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