xref: /aoo41x/main/svx/source/svdraw/svdxcgv.cxx (revision 47a7c0c1)
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 BitmapEx SdrExchangeView::GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked) const
533 {
534 	BitmapEx aBmp;
535 
536 	if( AreObjectsMarked() )
537 	{
538         if(1 == GetMarkedObjectCount())
539         {
540             if(bNoVDevIfOneBmpMarked)
541             {
542                 SdrObject*	pGrafObjTmp	= GetMarkedObjectByIndex( 0 );
543                 SdrGrafObj*	pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
544 
545                 if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) )
546                 {
547                     aBmp = pGrafObj->GetTransformedGraphic().GetBitmapEx();
548                 }
549             }
550             else
551             {
552                 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(GetMarkedObjectByIndex(0));
553 
554                 if(pSdrGrafObj && pSdrGrafObj->isEmbeddedSvg())
555                 {
556                     aBmp = pSdrGrafObj->GetGraphic().getSvgData()->getReplacement();
557                 }
558             }
559         }
560 
561 		if( !aBmp )
562 		{
563 			const Graphic aGraphic(GetMarkedObjMetaFile(bNoVDevIfOneBmpMarked));
564 
565             // #i102089# support user's settings of AA and LineSnap when the MetaFile gets
566             // rasterconverted to a bitmap
567             const SvtOptionsDrawinglayer aDrawinglayerOpt;
568             const GraphicConversionParameters aParameters(
569                 Size(),
570                 false,
571                 aDrawinglayerOpt.IsAntiAliasing(),
572                 aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete());
573 
574             aBmp = aGraphic.GetBitmapEx(aParameters);
575 		}
576 	}
577 
578 	return aBmp;
579 }
580 
581 // -----------------------------------------------------------------------------
582 
583 GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) const
584 {
585     GDIMetaFile aMtf;
586 
587     if( AreObjectsMarked() )
588 	{
589 		Rectangle	aBound( GetMarkedObjBoundRect() );
590 		Size        aBoundSize( aBound.GetWidth(), aBound.GetHeight() );
591 		MapMode	    aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() );
592 
593 		if( bNoVDevIfOneMtfMarked )
594 		{
595 			SdrObject*	pGrafObjTmp = GetMarkedObjectByIndex( 0 );
596 			SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
597 
598 			if( pGrafObj )
599             {
600                 Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
601 
602                 if( aGraphic.GetType() == GRAPHIC_BITMAP )
603                 {
604                     const Point aPos;
605 
606                     aMtf.AddAction( new MetaBmpExScaleAction( aPos, aBoundSize, aGraphic.GetBitmapEx() ) );
607         		    aMtf.SetPrefMapMode( aMap );
608                 	aMtf.SetPrefSize( aBoundSize );
609                 }
610                 else
611                     aMtf = aGraphic.GetGDIMetaFile();
612             }
613 		}
614 
615 		if( !aMtf.GetActionCount() )
616 		{
617 			VirtualDevice aOut;
618             const Size aDummySize(2, 2);
619 
620             aOut.SetOutputSizePixel(aDummySize);
621 			aOut.EnableOutput(false);
622 			aOut.SetMapMode(aMap);
623             aMtf.Clear();
624 			aMtf.Record(&aOut);
625 
626             DrawMarkedObj(aOut);
627 
628             aMtf.Stop();
629 			aMtf.WindStart();
630 
631             // moving the result is more reliable then setting a relative MapMode at the VDev (used
632             // before), also see #i99268# in GetObjGraphic() below. Some draw actions at
633             // the OutDev are simply not handled correctly when a MapMode is set at the
634             // target devive, e.g. MetaFloatTransparentAction. Even the Move for this action
635             // was missing the manipulation of the embedded Metafile
636 			aMtf.Move(-aBound.Left(), -aBound.Top());
637 
638             aMtf.SetPrefMapMode( aMap );
639 
640 			// removed PrefSize extension. It is principially wrong to set a reduced size at
641 			// the created MetaFile. The mentioned errors occurr at output time since the integer
642 			// MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for
643 			// primitives (and may later be done in breaking up a MetaFile to primitives)
644 			aMtf.SetPrefSize(aBoundSize);
645 		}
646 	}
647 
648 	return aMtf;
649 }
650 
651 // -----------------------------------------------------------------------------
652 
653 Graphic SdrExchangeView::GetAllMarkedGraphic() const
654 {
655     Graphic aRet;
656 
657     if( AreObjectsMarked() )
658     {
659         if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) )
660             aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) );
661         else
662             aRet = GetMarkedObjMetaFile(false);
663     }
664 
665     return aRet;
666 }
667 
668 // -----------------------------------------------------------------------------
669 
670 Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj )
671 {
672     Graphic aRet;
673 
674     if( pModel && pObj )
675     {
676         // try to get a graphic from the object first
677 		const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
678 		const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
679 
680 		if(pSdrGrafObj)
681         {
682             if(pSdrGrafObj->isEmbeddedSvg())
683             {
684                 // get Metafile for Svg content
685                 aRet = pSdrGrafObj->getMetafileFromEmbeddedSvg();
686             }
687             else
688             {
689                 // #110981# Make behaviour coherent with metafile
690                 // recording below (which of course also takes
691                 // view-transformed objects)
692                 aRet = pSdrGrafObj->GetTransformedGraphic();
693             }
694         }
695         else if(pSdrOle2Obj)
696         {
697             if ( pSdrOle2Obj->GetGraphic() )
698                 aRet = *pSdrOle2Obj->GetGraphic();
699         }
700 
701         // if graphic could not be retrieved => go the hard way and create a MetaFile
702         if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) )
703         {
704 			VirtualDevice	aOut;
705             GDIMetaFile     aMtf;
706 			const Rectangle	aBoundRect( pObj->GetCurrentBoundRect() );
707 			const MapMode	aMap( pModel->GetScaleUnit(),
708                                   Point(),
709 								  pModel->GetScaleFraction(),
710                                   pModel->GetScaleFraction() );
711 
712 			aOut.EnableOutput( sal_False );
713 			aOut.SetMapMode( aMap );
714 			aMtf.Record( &aOut );
715             pObj->SingleObjectPainter( aOut ); // #110094#-17
716             aMtf.Stop();
717 			aMtf.WindStart();
718 
719 			// #i99268# replace the original offset from using XOutDev's SetOffset
720 			// NOT (as tried with #i92760#) with another MapMode which gets recorded
721 			// by the Metafile itself (what always leads to problems), but by
722 			// moving the result directly
723 			aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
724 
725     		aMtf.SetPrefMapMode( aMap );
726 			aMtf.SetPrefSize( aBoundRect.GetSize() );
727 
728             if( aMtf.GetActionCount() )
729                 aRet = aMtf;
730         }
731      }
732 
733      return aRet;
734 }
735 
736 // -----------------------------------------------------------------------------
737 
738 void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const
739 {
740 	SortMarkedObjects();
741 
742     ::std::vector< ::std::vector< SdrMark* > >  aObjVectors( 2 );
743     ::std::vector< SdrMark* >&                  rObjVector1 = aObjVectors[ 0 ];
744     ::std::vector< SdrMark* >&                  rObjVector2 = aObjVectors[ 1 ];
745     const SdrLayerAdmin&                        rLayerAdmin = pMod->GetLayerAdmin();
746     const sal_uInt32                            nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
747     sal_uInt32                                  n, nCount;
748 
749 	for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
750     {
751         SdrMark* pMark = GetSdrMarkByIndex( n );
752 
753         // paint objects on control layer on top of all otherobjects
754         if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
755             rObjVector2.push_back( pMark );
756         else
757             rObjVector1.push_back( pMark );
758     }
759 
760     for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
761     {
762         ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
763 
764         for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
765         {
766     		SdrMark*    pMark = rObjVector[ i ];
767             pMark->GetMarkedSdrObj()->SingleObjectPainter( rOut ); // #110094#-17
768         }
769     }
770 }
771 
772 // -----------------------------------------------------------------------------
773 
774 SdrModel* SdrExchangeView::GetMarkedObjModel() const
775 {
776 	// Wenn das sortieren der MarkList mal stoeren sollte,
777 	// werde ich sie mir wohl kopieren muessen.
778 	SortMarkedObjects();
779 	SdrModel* pNeuMod=pMod->AllocModel();
780 	SdrPage* pNeuPag=pNeuMod->AllocPage(sal_False);
781 	pNeuMod->InsertPage(pNeuPag);
782 
783 	if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) )
784 	{
785 		::std::vector< ::std::vector< SdrMark* > >  aObjVectors( 2 );
786 		::std::vector< SdrMark* >&                  rObjVector1 = aObjVectors[ 0 ];
787 		::std::vector< SdrMark* >&                  rObjVector2 = aObjVectors[ 1 ];
788 		const SdrLayerAdmin&                        rLayerAdmin = pMod->GetLayerAdmin();
789 		const sal_uInt32                            nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
790 		sal_uInt32                                  n, nCount, nCloneErrCnt = 0;
791 
792 		for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
793 		{
794 			SdrMark* pMark = GetSdrMarkByIndex( n );
795 
796 			// paint objects on control layer on top of all otherobjects
797 			if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
798 				rObjVector2.push_back( pMark );
799 			else
800 				rObjVector1.push_back( pMark );
801 		}
802 
803 		// #i13033#
804 		// New mechanism to re-create the connections of cloned connectors
805 		CloneList aCloneList;
806 
807 		for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
808 		{
809 			::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
810 
811 			for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
812 			{
813    				const SdrMark*      pMark = rObjVector[ i ];
814 				const SdrObject*    pObj = pMark->GetMarkedSdrObj();
815 				SdrObject*          pNeuObj;
816 
817 				if( pObj->ISA( SdrPageObj ) )
818 				{
819 					// convert SdrPageObj's to a graphic representation, because
820 					// virtual connection to referenced page gets lost in new model
821 					pNeuObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() );
822 					pNeuObj->SetPage( pNeuPag );
823 					pNeuObj->SetModel( pNeuMod );
824 				}
825 				else
826 				{
827 					// #116235#
828     				// pNeuObj = pObj->Clone( pNeuPag, pNeuMod );
829     				pNeuObj = pObj->Clone();
830 					pNeuObj->SetPage( pNeuPag );
831 					pNeuObj->SetModel( pNeuMod );
832 				}
833 
834 				if( pNeuObj )
835 				{
836 					SdrInsertReason aReason(SDRREASON_VIEWCALL);
837 					pNeuPag->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
838 
839 					// #i13033#
840 					aCloneList.AddPair(pObj, pNeuObj);
841 				}
842 				else
843 					nCloneErrCnt++;
844 			}
845 		}
846 
847 		// #i13033#
848 		// New mechanism to re-create the connections of cloned connectors
849 		aCloneList.CopyConnections();
850 
851 		if(0L != nCloneErrCnt)
852 		{
853 #ifdef DBG_UTIL
854 			ByteString aStr("SdrExchangeView::GetMarkedObjModel(): Fehler beim Clonen ");
855 
856 			if(nCloneErrCnt == 1)
857 			{
858 				aStr += "eines Zeichenobjekts.";
859 			}
860 			else
861 			{
862 				aStr += "von ";
863 				aStr += ByteString::CreateFromInt32( nCloneErrCnt );
864 				aStr += " Zeichenobjekten.";
865 			}
866 
867 			aStr += " Objektverbindungen werden nicht mitkopiert.";
868 
869 			DBG_ERROR(aStr.GetBuffer());
870 #endif
871 		}
872 	}
873 	return pNeuMod;
874 }
875 
876 // -----------------------------------------------------------------------------
877 
878 sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */)
879 {
880     DBG_ERROR( "SdrExchangeView::Cut: Not supported anymore" );
881     return sal_False;
882 }
883 
884 // -----------------------------------------------------------------------------
885 
886 void SdrExchangeView::CutMarked( sal_uIntPtr /*nFormat */)
887 {
888     DBG_ERROR( "SdrExchangeView::CutMarked: Not supported anymore" );
889 }
890 
891 // -----------------------------------------------------------------------------
892 
893 sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/)
894 {
895     DBG_ERROR( "SdrExchangeView::Yank: Not supported anymore" );
896     return sal_False;
897 }
898 
899 // -----------------------------------------------------------------------------
900 
901 void SdrExchangeView::YankMarked(sal_uIntPtr /*nFormat*/)
902 {
903     DBG_ERROR( "YankMarked: Not supported anymore" );
904 }
905 
906 // -----------------------------------------------------------------------------
907 
908 sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/)
909 {
910     DBG_ERROR( "SdrExchangeView::Paste: Not supported anymore" );
911     return sal_False;
912 }
913