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