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
SdrExchangeView(SdrModel * pModel1,OutputDevice * pOut)66 SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut):
67 SdrObjEditView(pModel1,pOut)
68 {
69 }
70
71 ////////////////////////////////////////////////////////////////////////////////////////////////////
72
GetViewCenter(const OutputDevice * pOut) const73 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
GetPastePos(SdrObjList * pLst,OutputDevice * pOut)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
ImpLimitToWorkArea(Point & rPt) const104 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
ImpGetPasteObjList(Point &,SdrObjList * & rpLst)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
ImpGetPasteLayer(const SdrObjList * pObjList,SdrLayerID & rLayer) const149 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
Paste(const GDIMetaFile & rMtf,const Point & rPos,SdrObjList * pLst,sal_uInt32 nOptions)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
Paste(const Bitmap & rBmp,const Point & rPos,SdrObjList * pLst,sal_uInt32 nOptions)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
Paste(const XubString & rStr,const Point & rPos,SdrObjList * pLst,sal_uInt32 nOptions)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
Paste(SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat,const Point & rPos,SdrObjList * pLst,sal_uInt32 nOptions)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
Paste(const SdrModel & rMod,const Point & rPos,SdrObjList * pLst,sal_uInt32 nOptions)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
IsExchangeFormatSupported(sal_uIntPtr nFormat) const473 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
ImpPasteObject(SdrObject * pObj,SdrObjList & rLst,const Point & rCenter,const Size & rSiz,const MapMode & rMap,sal_uInt32 nOptions)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
GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked) const531 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 SdrObject* pCandidate = aSdrObjects[a];
578 SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pCandidate);
579
580 if(pSdrGrafObj)
581 {
582 // #122753# To ensure existance of graphic content, force swap in
583 pSdrGrafObj->ForceSwapIn();
584 }
585
586 xPrimitives[a] = new drawinglayer::primitive2d::GroupPrimitive2D(
587 pCandidate->GetViewContact().getViewIndependentPrimitive2DSequence());
588 }
589
590 // get logic range
591 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
592 const basegfx::B2DRange aRange(
593 drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
594 xPrimitives,
595 aViewInformation2D));
596
597 if(!aRange.isEmpty())
598 {
599 // if we have geometry and it has a range, convert to BitmapEx using
600 // common tooling
601 aBmp = convertPrimitive2DSequenceToBitmapEx(
602 xPrimitives,
603 aRange,
604 500000);
605 }
606 }
607 }
608 }
609
610 return aBmp;
611 }
612
613 // -----------------------------------------------------------------------------
614
GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) const615 GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) const
616 {
617 GDIMetaFile aMtf;
618
619 if( AreObjectsMarked() )
620 {
621 Rectangle aBound( GetMarkedObjBoundRect() );
622 Size aBoundSize( aBound.GetWidth(), aBound.GetHeight() );
623 MapMode aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() );
624
625 if( bNoVDevIfOneMtfMarked )
626 {
627 SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
628 SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
629
630 if( pGrafObj )
631 {
632 Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
633
634 // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
635 aMtf = aGraphic.GetGDIMetaFile();
636 }
637 }
638
639 if( !aMtf.GetActionCount() )
640 {
641 VirtualDevice aOut;
642 const Size aDummySize(2, 2);
643
644 aOut.SetOutputSizePixel(aDummySize);
645 aOut.EnableOutput(false);
646 aOut.SetMapMode(aMap);
647 aMtf.Clear();
648 aMtf.Record(&aOut);
649
650 DrawMarkedObj(aOut);
651
652 aMtf.Stop();
653 aMtf.WindStart();
654
655 // moving the result is more reliable then setting a relative MapMode at the VDev (used
656 // before), also see #i99268# in GetObjGraphic() below. Some draw actions at
657 // the OutDev are simply not handled correctly when a MapMode is set at the
658 // target devive, e.g. MetaFloatTransparentAction. Even the Move for this action
659 // was missing the manipulation of the embedded Metafile
660 aMtf.Move(-aBound.Left(), -aBound.Top());
661
662 aMtf.SetPrefMapMode( aMap );
663
664 // removed PrefSize extension. It is principially wrong to set a reduced size at
665 // the created MetaFile. The mentioned errors occurr at output time since the integer
666 // MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for
667 // primitives (and may later be done in breaking up a MetaFile to primitives)
668 aMtf.SetPrefSize(aBoundSize);
669 }
670 }
671
672 return aMtf;
673 }
674
675 // -----------------------------------------------------------------------------
676
GetAllMarkedGraphic() const677 Graphic SdrExchangeView::GetAllMarkedGraphic() const
678 {
679 Graphic aRet;
680
681 if( AreObjectsMarked() )
682 {
683 if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) )
684 aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) );
685 else
686 aRet = GetMarkedObjMetaFile(false);
687 }
688
689 return aRet;
690 }
691
692 // -----------------------------------------------------------------------------
693
GetObjGraphic(const SdrModel * pModel,const SdrObject * pObj)694 Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj )
695 {
696 Graphic aRet;
697
698 if( pModel && pObj )
699 {
700 // try to get a graphic from the object first
701 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
702 const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
703
704 if(pSdrGrafObj)
705 {
706 if(pSdrGrafObj->isEmbeddedSvg())
707 {
708 // get Metafile for Svg content
709 aRet = pSdrGrafObj->getMetafileFromEmbeddedSvg();
710 }
711 else
712 {
713 // #110981# Make behaviour coherent with metafile
714 // recording below (which of course also takes
715 // view-transformed objects)
716 aRet = pSdrGrafObj->GetTransformedGraphic();
717 }
718 }
719 else if(pSdrOle2Obj)
720 {
721 if ( pSdrOle2Obj->GetGraphic() )
722 aRet = *pSdrOle2Obj->GetGraphic();
723 }
724
725 // if graphic could not be retrieved => go the hard way and create a MetaFile
726 if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) )
727 {
728 VirtualDevice aOut;
729 GDIMetaFile aMtf;
730 const Rectangle aBoundRect( pObj->GetCurrentBoundRect() );
731 const MapMode aMap( pModel->GetScaleUnit(),
732 Point(),
733 pModel->GetScaleFraction(),
734 pModel->GetScaleFraction() );
735
736 aOut.EnableOutput( sal_False );
737 aOut.SetMapMode( aMap );
738 aMtf.Record( &aOut );
739 pObj->SingleObjectPainter( aOut ); // #110094#-17
740 aMtf.Stop();
741 aMtf.WindStart();
742
743 // #i99268# replace the original offset from using XOutDev's SetOffset
744 // NOT (as tried with #i92760#) with another MapMode which gets recorded
745 // by the Metafile itself (what always leads to problems), but by
746 // moving the result directly
747 aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
748
749 aMtf.SetPrefMapMode( aMap );
750 aMtf.SetPrefSize( aBoundRect.GetSize() );
751
752 if( aMtf.GetActionCount() )
753 aRet = aMtf;
754 }
755 }
756
757 return aRet;
758 }
759
760 // -----------------------------------------------------------------------------
761
GetMarkedObjects() const762 ::std::vector< SdrObject* > SdrExchangeView::GetMarkedObjects() const
763 {
764 SortMarkedObjects();
765 ::std::vector< SdrObject* > aRetval;
766
767 ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 );
768 ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ];
769 ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ];
770 const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin();
771 const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
772 sal_uInt32 n, nCount;
773
774 for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
775 {
776 SdrMark* pMark = GetSdrMarkByIndex( n );
777
778 // paint objects on control layer on top of all otherobjects
779 if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
780 rObjVector2.push_back( pMark );
781 else
782 rObjVector1.push_back( pMark );
783 }
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 SdrMark* pMark = rObjVector[ i ];
792 aRetval.push_back(pMark->GetMarkedSdrObj());
793 }
794 }
795
796 return aRetval;
797 }
798
799 // -----------------------------------------------------------------------------
800
DrawMarkedObj(OutputDevice & rOut) const801 void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const
802 {
803 ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects());
804
805 if(aSdrObjects.size())
806 {
807 sdr::contact::ObjectContactOfObjListPainter aPainter(rOut, aSdrObjects, aSdrObjects[0]->GetPage());
808 sdr::contact::DisplayInfo aDisplayInfo;
809
810 // do processing
811 aPainter.ProcessDisplay(aDisplayInfo);
812 }
813 }
814
815 // -----------------------------------------------------------------------------
816
GetMarkedObjModel() const817 SdrModel* SdrExchangeView::GetMarkedObjModel() const
818 {
819 // Wenn das sortieren der MarkList mal stoeren sollte,
820 // werde ich sie mir wohl kopieren muessen.
821 SortMarkedObjects();
822 SdrModel* pNeuMod=pMod->AllocModel();
823 SdrPage* pNeuPag=pNeuMod->AllocPage(sal_False);
824 pNeuMod->InsertPage(pNeuPag);
825
826 if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) )
827 {
828 ::std::vector< SdrObject* > aSdrObjects(GetMarkedObjects());
829
830 // #i13033#
831 // New mechanism to re-create the connections of cloned connectors
832 CloneList aCloneList;
833 sal_uInt32 nCloneErrCnt(0);
834
835 for( sal_uInt32 i(0); i < aSdrObjects.size(); i++ )
836 {
837 const SdrObject* pObj = aSdrObjects[i];
838 SdrObject* pNeuObj;
839
840 if( pObj->ISA( SdrPageObj ) )
841 {
842 // convert SdrPageObj's to a graphic representation, because
843 // virtual connection to referenced page gets lost in new model
844 pNeuObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() );
845 pNeuObj->SetPage( pNeuPag );
846 pNeuObj->SetModel( pNeuMod );
847 }
848 else
849 {
850 // #116235#
851 // pNeuObj = pObj->Clone( pNeuPag, pNeuMod );
852 pNeuObj = pObj->Clone();
853 pNeuObj->SetPage( pNeuPag );
854 pNeuObj->SetModel( pNeuMod );
855 }
856
857 if( pNeuObj )
858 {
859 SdrInsertReason aReason(SDRREASON_VIEWCALL);
860 pNeuPag->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
861
862 // #i13033#
863 aCloneList.AddPair(pObj, pNeuObj);
864 }
865 else
866 nCloneErrCnt++;
867 }
868
869 // #i13033#
870 // New mechanism to re-create the connections of cloned connectors
871 aCloneList.CopyConnections();
872
873 if(0L != nCloneErrCnt)
874 {
875 #ifdef DBG_UTIL
876 ByteString aStr("SdrExchangeView::GetMarkedObjModel(): Fehler beim Clonen ");
877
878 if(nCloneErrCnt == 1)
879 {
880 aStr += "eines Zeichenobjekts.";
881 }
882 else
883 {
884 aStr += "von ";
885 aStr += ByteString::CreateFromInt32( nCloneErrCnt );
886 aStr += " Zeichenobjekten.";
887 }
888
889 aStr += " Objektverbindungen werden nicht mitkopiert.";
890
891 DBG_ERROR(aStr.GetBuffer());
892 #endif
893 }
894 }
895 return pNeuMod;
896 }
897
898 // -----------------------------------------------------------------------------
899
Cut(sal_uIntPtr)900 sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */)
901 {
902 DBG_ERROR( "SdrExchangeView::Cut: Not supported anymore" );
903 return sal_False;
904 }
905
906 // -----------------------------------------------------------------------------
907
CutMarked(sal_uIntPtr)908 void SdrExchangeView::CutMarked( sal_uIntPtr /*nFormat */)
909 {
910 DBG_ERROR( "SdrExchangeView::CutMarked: Not supported anymore" );
911 }
912
913 // -----------------------------------------------------------------------------
914
Yank(sal_uIntPtr)915 sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/)
916 {
917 DBG_ERROR( "SdrExchangeView::Yank: Not supported anymore" );
918 return sal_False;
919 }
920
921 // -----------------------------------------------------------------------------
922
YankMarked(sal_uIntPtr)923 void SdrExchangeView::YankMarked(sal_uIntPtr /*nFormat*/)
924 {
925 DBG_ERROR( "YankMarked: Not supported anymore" );
926 }
927
928 // -----------------------------------------------------------------------------
929
Paste(Window *,sal_uIntPtr)930 sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/)
931 {
932 DBG_ERROR( "SdrExchangeView::Paste: Not supported anymore" );
933 return sal_False;
934 }
935
936 // eof
937