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