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