xref: /trunk/main/svx/source/svdraw/svdxcgv.cxx (revision 86e1cf34)
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 existence 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 occur 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