Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vector>
21 : #include <editeng/editeng.hxx>
22 : #include "svx/xexch.hxx"
23 : #include <svx/xflclit.hxx>
24 : #include <svx/svdxcgv.hxx>
25 : #include <svx/svdoutl.hxx>
26 : #include "svx/svditext.hxx"
27 : #include <svx/svdetc.hxx>
28 : #include <svx/svdundo.hxx>
29 : #include <svx/svdograf.hxx>
30 : #include <svx/svdoole2.hxx> // to not have OLE in SdrClipboardFormat
31 : #include <svx/svdorect.hxx>
32 : #include <svx/svdoedge.hxx> // for connectors via the clipboard
33 : #include <svx/svdopage.hxx> // for connectors via the clipboard
34 : #include <svx/svdpage.hxx>
35 : #include <svx/svdpagv.hxx>
36 : #include <svx/svdtrans.hxx> // for GetMapFactor, to rescale at PasteModel
37 : #include "svx/svdstr.hrc" // names taken from the resource
38 : #include "svx/svdglob.hxx" // StringCache
39 : #include "svx/xoutbmp.hxx"
40 : #include <vcl/metaact.hxx>
41 : #include <svl/poolitem.hxx>
42 : #include <svl/itempool.hxx>
43 : #include <tools/bigint.hxx>
44 : #include <sot/formats.hxx>
45 :
46 : // #i13033#
47 : #include <clonelist.hxx>
48 : #include <vcl/virdev.hxx>
49 :
50 : #include <svl/style.hxx>
51 :
52 : // #i72535#
53 : #include "fmobj.hxx"
54 : #include <rtl/strbuf.hxx>
55 :
56 : ////////////////////////////////////////////////////////////////////////////////////////////////////
57 :
58 640 : SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut):
59 640 : SdrObjEditView(pModel1,pOut)
60 : {
61 640 : }
62 :
63 0 : sal_Bool SdrExchangeView::ImpLimitToWorkArea(Point& rPt) const
64 : {
65 0 : sal_Bool bRet(sal_False);
66 :
67 0 : if(!aMaxWorkArea.IsEmpty())
68 : {
69 0 : if(rPt.X()<aMaxWorkArea.Left())
70 : {
71 0 : rPt.X() = aMaxWorkArea.Left();
72 0 : bRet = sal_True;
73 : }
74 :
75 0 : if(rPt.X()>aMaxWorkArea.Right())
76 : {
77 0 : rPt.X() = aMaxWorkArea.Right();
78 0 : bRet = sal_True;
79 : }
80 :
81 0 : if(rPt.Y()<aMaxWorkArea.Top())
82 : {
83 0 : rPt.Y() = aMaxWorkArea.Top();
84 0 : bRet = sal_True;
85 : }
86 :
87 0 : if(rPt.Y()>aMaxWorkArea.Bottom())
88 : {
89 0 : rPt.Y() = aMaxWorkArea.Bottom();
90 0 : bRet = sal_True;
91 : }
92 : }
93 0 : return bRet;
94 : }
95 :
96 0 : void SdrExchangeView::ImpGetPasteObjList(Point& /*rPos*/, SdrObjList*& rpLst)
97 : {
98 0 : if (rpLst==NULL)
99 : {
100 0 : SdrPageView* pPV = GetSdrPageView();
101 :
102 0 : if (pPV!=NULL) {
103 0 : rpLst=pPV->GetObjList();
104 : }
105 : }
106 0 : }
107 :
108 0 : sal_Bool SdrExchangeView::ImpGetPasteLayer(const SdrObjList* pObjList, SdrLayerID& rLayer) const
109 : {
110 0 : sal_Bool bRet=sal_False;
111 0 : rLayer=0;
112 0 : if (pObjList!=NULL) {
113 0 : const SdrPage* pPg=pObjList->GetPage();
114 0 : if (pPg!=NULL) {
115 0 : rLayer=pPg->GetLayerAdmin().GetLayerID(aAktLayer,sal_True);
116 0 : if (rLayer==SDRLAYER_NOTFOUND) rLayer=0;
117 0 : SdrPageView* pPV = GetSdrPageView();
118 0 : if (pPV!=NULL) {
119 0 : bRet=!pPV->GetLockedLayers().IsSet(rLayer) && pPV->GetVisibleLayers().IsSet(rLayer);
120 : }
121 : }
122 : }
123 0 : return bRet;
124 : }
125 :
126 0 : sal_Bool SdrExchangeView::Paste(const XubString& rStr, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
127 : {
128 0 : if(!rStr.Len())
129 0 : return sal_False;
130 :
131 0 : Point aPos(rPos);
132 0 : ImpGetPasteObjList(aPos,pLst);
133 0 : ImpLimitToWorkArea( aPos );
134 0 : if (pLst==NULL) return sal_False;
135 : SdrLayerID nLayer;
136 0 : if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
137 0 : sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
138 0 : if (bUnmark) UnmarkAllObj();
139 0 : Rectangle aTextRect(0,0,500,500);
140 0 : SdrPage* pPage=pLst->GetPage();
141 0 : if (pPage!=NULL) {
142 0 : aTextRect.SetSize(pPage->GetSize());
143 : }
144 0 : SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
145 0 : pObj->SetModel(pMod);
146 0 : pObj->SetLayer(nLayer);
147 0 : pObj->NbcSetText(rStr); // SetText before SetAttr, else SetAttr doesn't work!
148 0 : if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
149 :
150 0 : pObj->SetMergedItemSet(aDefaultAttr);
151 :
152 0 : SfxItemSet aTempAttr(pMod->GetItemPool()); // no fill, no line
153 0 : aTempAttr.Put(XLineStyleItem(XLINE_NONE));
154 0 : aTempAttr.Put(XFillStyleItem(XFILL_NONE));
155 :
156 0 : pObj->SetMergedItemSet(aTempAttr);
157 :
158 0 : pObj->FitFrameToTextSize();
159 0 : Size aSiz(pObj->GetLogicRect().GetSize());
160 0 : MapUnit eMap=pMod->GetScaleUnit();
161 0 : Fraction aMap=pMod->GetScaleFraction();
162 0 : ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
163 0 : return sal_True;
164 : }
165 :
166 0 : sal_Bool SdrExchangeView::Paste(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
167 : {
168 0 : Point aPos(rPos);
169 0 : ImpGetPasteObjList(aPos,pLst);
170 0 : ImpLimitToWorkArea( aPos );
171 0 : if (pLst==NULL) return sal_False;
172 : SdrLayerID nLayer;
173 0 : if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False;
174 0 : sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
175 0 : if (bUnmark) UnmarkAllObj();
176 0 : Rectangle aTextRect(0,0,500,500);
177 0 : SdrPage* pPage=pLst->GetPage();
178 0 : if (pPage!=NULL) {
179 0 : aTextRect.SetSize(pPage->GetSize());
180 : }
181 0 : SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
182 0 : pObj->SetModel(pMod);
183 0 : pObj->SetLayer(nLayer);
184 0 : if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
185 :
186 0 : pObj->SetMergedItemSet(aDefaultAttr);
187 :
188 0 : SfxItemSet aTempAttr(pMod->GetItemPool()); // no fill, no line
189 0 : aTempAttr.Put(XLineStyleItem(XLINE_NONE));
190 0 : aTempAttr.Put(XFillStyleItem(XFILL_NONE));
191 :
192 0 : pObj->SetMergedItemSet(aTempAttr);
193 :
194 0 : pObj->NbcSetText(rInput,rBaseURL,eFormat);
195 0 : pObj->FitFrameToTextSize();
196 0 : Size aSiz(pObj->GetLogicRect().GetSize());
197 0 : MapUnit eMap=pMod->GetScaleUnit();
198 0 : Fraction aMap=pMod->GetScaleFraction();
199 0 : ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
200 :
201 : // b4967543
202 0 : if(pObj && pObj->GetModel() && pObj->GetOutlinerParaObject())
203 : {
204 0 : SdrOutliner& rOutliner = pObj->GetModel()->GetHitTestOutliner();
205 0 : rOutliner.SetText(*pObj->GetOutlinerParaObject());
206 :
207 0 : if(1L == rOutliner.GetParagraphCount())
208 : {
209 0 : SfxStyleSheet* pCandidate = rOutliner.GetStyleSheet(0L);
210 :
211 0 : if(pCandidate)
212 : {
213 0 : if(pObj->GetModel()->GetStyleSheetPool() == &pCandidate->GetPool())
214 : {
215 0 : pObj->NbcSetStyleSheet(pCandidate, sal_True);
216 : }
217 : }
218 : }
219 : }
220 :
221 0 : return sal_True;
222 : }
223 :
224 0 : sal_Bool SdrExchangeView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
225 : {
226 0 : const SdrModel* pSrcMod=&rMod;
227 0 : if (pSrcMod==pMod)
228 0 : return sal_False; // this can't work, right?
229 :
230 0 : const bool bUndo = IsUndoEnabled();
231 :
232 0 : if( bUndo )
233 0 : BegUndo(ImpGetResStr(STR_ExchangePaste));
234 :
235 0 : if( mxSelectionController.is() && mxSelectionController->PasteObjModel( rMod ) )
236 : {
237 0 : if( bUndo )
238 0 : EndUndo();
239 0 : return sal_True;
240 : }
241 :
242 0 : Point aPos(rPos);
243 0 : ImpGetPasteObjList(aPos,pLst);
244 0 : SdrPageView* pMarkPV=NULL;
245 0 : SdrPageView* pPV = GetSdrPageView();
246 :
247 0 : if(pPV)
248 : {
249 0 : if ( pPV->GetObjList() == pLst )
250 0 : pMarkPV=pPV;
251 : }
252 :
253 0 : ImpLimitToWorkArea( aPos );
254 0 : if (pLst==NULL)
255 0 : return sal_False;
256 :
257 0 : sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
258 0 : if (bUnmark)
259 0 : UnmarkAllObj();
260 :
261 : // Rescale, if the Model uses a different MapUnit.
262 : // Calculate the necessary factors first.
263 0 : MapUnit eSrcUnit=pSrcMod->GetScaleUnit();
264 0 : MapUnit eDstUnit=pMod->GetScaleUnit();
265 0 : sal_Bool bResize=eSrcUnit!=eDstUnit;
266 0 : Fraction xResize,yResize;
267 0 : Point aPt0;
268 0 : if (bResize)
269 : {
270 0 : FrPair aResize(GetMapFactor(eSrcUnit,eDstUnit));
271 0 : xResize=aResize.X();
272 0 : yResize=aResize.Y();
273 : }
274 0 : SdrObjList* pDstLst=pLst;
275 0 : sal_uInt16 nPg,nPgAnz=pSrcMod->GetPageCount();
276 0 : for (nPg=0; nPg<nPgAnz; nPg++)
277 : {
278 0 : const SdrPage* pSrcPg=pSrcMod->GetPage(nPg);
279 :
280 : // Use SnapRect, not BoundRect here
281 0 : Rectangle aR=pSrcPg->GetAllObjSnapRect();
282 :
283 0 : if (bResize)
284 0 : ResizeRect(aR,aPt0,xResize,yResize);
285 0 : Point aDist(aPos-aR.Center());
286 0 : Size aSiz(aDist.X(),aDist.Y());
287 0 : sal_uIntPtr nCloneErrCnt=0;
288 0 : sal_uIntPtr nOb,nObAnz=pSrcPg->GetObjCount();
289 0 : sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
290 :
291 : // #i13033#
292 : // New mechanism to re-create the connections of cloned connectors
293 0 : CloneList aCloneList;
294 :
295 0 : for (nOb=0; nOb<nObAnz; nOb++)
296 : {
297 0 : const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);
298 :
299 0 : SdrObject* pNeuObj = pSrcOb->Clone();
300 :
301 0 : if (pNeuObj!=NULL)
302 : {
303 0 : if(bResize)
304 : {
305 0 : pNeuObj->GetModel()->SetPasteResize(sal_True);
306 0 : pNeuObj->NbcResize(aPt0,xResize,yResize);
307 0 : pNeuObj->GetModel()->SetPasteResize(sal_False);
308 : }
309 :
310 : // #i39861#
311 0 : pNeuObj->SetModel(pDstLst->GetModel());
312 0 : pNeuObj->SetPage(pDstLst->GetPage());
313 :
314 0 : pNeuObj->NbcMove(aSiz);
315 :
316 0 : const SdrPage* pPg = pDstLst->GetPage();
317 :
318 0 : if(pPg)
319 : {
320 : // #i72535#
321 0 : const SdrLayerAdmin& rAd = pPg->GetLayerAdmin();
322 0 : SdrLayerID nLayer(0);
323 :
324 0 : if(pNeuObj->ISA(FmFormObj))
325 : {
326 : // for FormControls, force to form layer
327 0 : nLayer = rAd.GetLayerID(rAd.GetControlLayerName(), true);
328 : }
329 : else
330 : {
331 0 : nLayer = rAd.GetLayerID(aAktLayer, sal_True);
332 : }
333 :
334 0 : if(SDRLAYER_NOTFOUND == nLayer)
335 : {
336 0 : nLayer = 0;
337 : }
338 :
339 0 : pNeuObj->SetLayer(nLayer);
340 : }
341 :
342 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
343 0 : pDstLst->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
344 :
345 0 : if( bUndo )
346 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNeuObj));
347 :
348 0 : if (bMark) {
349 : // Don't already set Markhandles!
350 : // That is instead being done by ModelHasChanged in MarkView.
351 0 : MarkObj(pNeuObj,pMarkPV,sal_False,sal_True);
352 : }
353 :
354 : // #i13033#
355 0 : aCloneList.AddPair(pSrcOb, pNeuObj);
356 : }
357 : else
358 : {
359 0 : nCloneErrCnt++;
360 : }
361 : }
362 :
363 : // #i13033#
364 : // New mechanism to re-create the connections of cloned connectors
365 0 : aCloneList.CopyConnections();
366 :
367 : if(0L != nCloneErrCnt)
368 : {
369 : #ifdef DBG_UTIL
370 : rtl::OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM(
371 : "SdrExchangeView::Paste(): Error when cloning "));
372 :
373 : if(nCloneErrCnt == 1)
374 : {
375 : aStr.append(RTL_CONSTASCII_STRINGPARAM(
376 : "a drawing object."));
377 : }
378 : else
379 : {
380 : aStr.append(static_cast<sal_Int32>(nCloneErrCnt));
381 : aStr.append(RTL_CONSTASCII_STRINGPARAM(" drawing objects."));
382 : }
383 :
384 : aStr.append(RTL_CONSTASCII_STRINGPARAM(
385 : " Not copying object connectors."));
386 :
387 : OSL_FAIL(aStr.getStr());
388 : #endif
389 : }
390 0 : }
391 :
392 0 : if( bUndo )
393 0 : EndUndo();
394 :
395 0 : return sal_True;
396 : }
397 :
398 0 : void SdrExchangeView::ImpPasteObject(SdrObject* pObj, SdrObjList& rLst, const Point& rCenter, const Size& rSiz, const MapMode& rMap, sal_uInt32 nOptions)
399 : {
400 0 : BigInt nSizX(rSiz.Width());
401 0 : BigInt nSizY(rSiz.Height());
402 0 : MapUnit eSrcMU=rMap.GetMapUnit();
403 0 : MapUnit eDstMU=pMod->GetScaleUnit();
404 0 : FrPair aMapFact(GetMapFactor(eSrcMU,eDstMU));
405 0 : Fraction aDstFr(pMod->GetScaleFraction());
406 0 : nSizX*=aMapFact.X().GetNumerator();
407 0 : nSizX*=rMap.GetScaleX().GetNumerator();
408 0 : nSizX*=aDstFr.GetDenominator();
409 0 : nSizX/=aMapFact.X().GetDenominator();
410 0 : nSizX/=rMap.GetScaleX().GetDenominator();
411 0 : nSizX/=aDstFr.GetNumerator();
412 0 : nSizY*=aMapFact.Y().GetNumerator();
413 0 : nSizY*=rMap.GetScaleY().GetNumerator();
414 0 : nSizX*=aDstFr.GetDenominator();
415 0 : nSizY/=aMapFact.Y().GetDenominator();
416 0 : nSizY/=rMap.GetScaleY().GetDenominator();
417 0 : nSizY/=aDstFr.GetNumerator();
418 0 : long xs=nSizX;
419 0 : long ys=nSizY;
420 0 : Point aPos(rCenter.X()-xs/2,rCenter.Y()-ys/2);
421 0 : Rectangle aR(aPos.X(),aPos.Y(),aPos.X()+xs,aPos.Y()+ys);
422 0 : pObj->SetLogicRect(aR);
423 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
424 0 : rLst.InsertObject(pObj,CONTAINER_APPEND,&aReason);
425 :
426 0 : if( IsUndoEnabled() )
427 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
428 :
429 0 : SdrPageView* pMarkPV=NULL;
430 0 : SdrPageView* pPV = GetSdrPageView();
431 :
432 0 : if(pPV)
433 : {
434 0 : if (pPV->GetObjList()==&rLst)
435 0 : pMarkPV=pPV;
436 : }
437 :
438 0 : sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
439 0 : if (bMark)
440 : { // select object the first PageView we found
441 0 : MarkObj(pObj,pMarkPV);
442 : }
443 0 : }
444 :
445 : ////////////////////////////////////////////////////////////////////////////////////////////////////
446 :
447 0 : BitmapEx SdrExchangeView::GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked) const
448 : {
449 0 : BitmapEx aBmp;
450 :
451 0 : if( AreObjectsMarked() )
452 : {
453 0 : if(1 == GetMarkedObjectCount())
454 : {
455 0 : if(bNoVDevIfOneBmpMarked)
456 : {
457 0 : SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
458 0 : SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
459 :
460 0 : if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) )
461 : {
462 0 : aBmp = pGrafObj->GetTransformedGraphic().GetBitmapEx();
463 : }
464 : }
465 : else
466 : {
467 0 : const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(GetMarkedObjectByIndex(0));
468 :
469 0 : if(pSdrGrafObj && pSdrGrafObj->isEmbeddedSvg())
470 : {
471 0 : aBmp = pSdrGrafObj->GetGraphic().getSvgData()->getReplacement();
472 : }
473 : }
474 : }
475 :
476 0 : if( !aBmp )
477 : {
478 0 : const Graphic aGraphic(GetMarkedObjMetaFile(bNoVDevIfOneBmpMarked));
479 :
480 : // #i102089# support user's settings of AA and LineSnap when the MetaFile gets
481 : // raster-converted to a bitmap
482 0 : const SvtOptionsDrawinglayer aDrawinglayerOpt;
483 : const GraphicConversionParameters aParameters(
484 : Size(),
485 : false,
486 0 : aDrawinglayerOpt.IsAntiAliasing(),
487 0 : aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete());
488 :
489 0 : aBmp = aGraphic.GetBitmapEx(aParameters);
490 : }
491 : }
492 :
493 0 : return aBmp;
494 : }
495 :
496 : // -----------------------------------------------------------------------------
497 :
498 13 : GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) const
499 : {
500 13 : GDIMetaFile aMtf;
501 :
502 13 : if( AreObjectsMarked() )
503 : {
504 13 : Rectangle aBound( GetMarkedObjBoundRect() );
505 13 : Size aBoundSize( aBound.GetWidth(), aBound.GetHeight() );
506 13 : MapMode aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() );
507 :
508 13 : if( bNoVDevIfOneMtfMarked )
509 : {
510 0 : SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
511 0 : SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
512 :
513 0 : if( pGrafObj )
514 : {
515 0 : Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
516 :
517 0 : if( aGraphic.GetType() == GRAPHIC_BITMAP )
518 : {
519 0 : const Point aPos;
520 :
521 0 : aMtf.AddAction( new MetaBmpExScaleAction( aPos, aBoundSize, aGraphic.GetBitmapEx() ) );
522 0 : aMtf.SetPrefMapMode( aMap );
523 0 : aMtf.SetPrefSize( aBoundSize );
524 : }
525 : else
526 0 : aMtf = aGraphic.GetGDIMetaFile();
527 : }
528 : }
529 :
530 13 : if( !aMtf.GetActionSize() )
531 : {
532 13 : VirtualDevice aOut;
533 13 : Size aDummySize( 2, 2 );
534 :
535 13 : aOut.SetOutputSizePixel( aDummySize );
536 13 : aOut.EnableOutput( sal_False );
537 13 : aOut.SetMapMode( aMap );
538 :
539 13 : aMtf.Clear();
540 13 : aMtf.Record( &aOut );
541 :
542 : // Replace offset given formally to DrawMarkedObj and used at XOutDev with relative
543 : // MapMode (which was also used in XOutDev in that case). Goal is to paint the object
544 : // as if TopLeft point is (0,0)
545 13 : const Fraction aNeutralFraction(1, 1);
546 13 : const MapMode aRelativeMapMode(MAP_RELATIVE, Point(-aBound.Left(), -aBound.Top()), aNeutralFraction, aNeutralFraction);
547 13 : aOut.SetMapMode(aRelativeMapMode);
548 :
549 13 : DrawMarkedObj(aOut);
550 :
551 13 : aMtf.Stop();
552 13 : aMtf.WindStart();
553 13 : aMtf.SetPrefMapMode( aMap );
554 :
555 : // removed PrefSize extension. It is principally wrong to set a reduced size at
556 : // the created MetaFile. The mentioned errors occur at output time since the integer
557 : // MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for
558 : // primitives (and may later be done in breaking up a MetaFile to primitives)
559 13 : aMtf.SetPrefSize(aBoundSize);
560 13 : }
561 : }
562 :
563 13 : return aMtf;
564 : }
565 :
566 : // -----------------------------------------------------------------------------
567 :
568 0 : Graphic SdrExchangeView::GetAllMarkedGraphic() const
569 : {
570 0 : Graphic aRet;
571 :
572 0 : if( AreObjectsMarked() )
573 : {
574 0 : if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) )
575 0 : aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) );
576 : else
577 0 : aRet = GetMarkedObjMetaFile(false);
578 : }
579 :
580 0 : return aRet;
581 : }
582 :
583 : // -----------------------------------------------------------------------------
584 :
585 0 : Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj )
586 : {
587 0 : Graphic aRet;
588 :
589 0 : if( pModel && pObj )
590 : {
591 : // try to get a graphic from the object first
592 0 : const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
593 0 : const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
594 :
595 0 : if(pSdrGrafObj)
596 : {
597 0 : if(pSdrGrafObj->isEmbeddedSvg())
598 : {
599 : // get Metafile for Svg content
600 0 : aRet = pSdrGrafObj->getMetafileFromEmbeddedSvg();
601 : }
602 : else
603 : {
604 : // Make behaviour coherent with metafile
605 : // recording below (which of course also takes
606 : // view-transformed objects)
607 0 : aRet = pSdrGrafObj->GetTransformedGraphic();
608 : }
609 : }
610 0 : else if(pSdrOle2Obj)
611 : {
612 0 : if ( pSdrOle2Obj->GetGraphic() )
613 0 : aRet = *pSdrOle2Obj->GetGraphic();
614 : }
615 :
616 : // if graphic could not be retrieved => go the hard way and create a MetaFile
617 0 : if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) )
618 : {
619 0 : VirtualDevice aOut;
620 0 : GDIMetaFile aMtf;
621 0 : const Rectangle aBoundRect( pObj->GetCurrentBoundRect() );
622 : const MapMode aMap( pModel->GetScaleUnit(),
623 : Point(),
624 0 : pModel->GetScaleFraction(),
625 0 : pModel->GetScaleFraction() );
626 :
627 0 : aOut.EnableOutput( sal_False );
628 0 : aOut.SetMapMode( aMap );
629 0 : aMtf.Record( &aOut );
630 0 : pObj->SingleObjectPainter( aOut );
631 0 : aMtf.Stop();
632 0 : aMtf.WindStart();
633 :
634 : // #i99268# replace the original offset from using XOutDev's SetOffset
635 : // NOT (as tried with #i92760#) with another MapMode which gets recorded
636 : // by the Metafile itself (what always leads to problems), but by hardly
637 : // moving the result
638 0 : aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
639 :
640 0 : aMtf.SetPrefMapMode( aMap );
641 0 : aMtf.SetPrefSize( aBoundRect.GetSize() );
642 :
643 0 : if( aMtf.GetActionSize() )
644 0 : aRet = aMtf;
645 : }
646 : }
647 :
648 0 : return aRet;
649 : }
650 :
651 : // -----------------------------------------------------------------------------
652 :
653 13 : void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const
654 : {
655 13 : SortMarkedObjects();
656 :
657 13 : ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 );
658 13 : ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ];
659 13 : ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ];
660 13 : const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin();
661 13 : const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
662 : sal_uInt32 n, nCount;
663 :
664 26 : for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
665 : {
666 13 : SdrMark* pMark = GetSdrMarkByIndex( n );
667 :
668 : // paint objects on control layer on top of all other objects
669 13 : if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
670 0 : rObjVector2.push_back( pMark );
671 : else
672 13 : rObjVector1.push_back( pMark );
673 : }
674 :
675 39 : for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
676 : {
677 26 : ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
678 :
679 39 : for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
680 : {
681 13 : SdrMark* pMark = rObjVector[ i ];
682 13 : pMark->GetMarkedSdrObj()->SingleObjectPainter( rOut );
683 : }
684 13 : }
685 13 : }
686 :
687 : // -----------------------------------------------------------------------------
688 :
689 0 : SdrModel* SdrExchangeView::GetMarkedObjModel() const
690 : {
691 : // Sorting the MarkList here might be problematic in the future, so
692 : // use a copy.
693 0 : SortMarkedObjects();
694 0 : SdrModel* pNeuMod=pMod->AllocModel();
695 0 : SdrPage* pNeuPag=pNeuMod->AllocPage(sal_False);
696 0 : pNeuMod->InsertPage(pNeuPag);
697 :
698 0 : if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) )
699 : {
700 0 : ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 );
701 0 : ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ];
702 0 : ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ];
703 0 : const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin();
704 0 : const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False );
705 0 : sal_uInt32 n, nCount, nCloneErrCnt = 0;
706 :
707 0 : for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
708 : {
709 0 : SdrMark* pMark = GetSdrMarkByIndex( n );
710 :
711 : // paint objects on control layer on top of all otherobjects
712 0 : if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
713 0 : rObjVector2.push_back( pMark );
714 : else
715 0 : rObjVector1.push_back( pMark );
716 : }
717 :
718 : // #i13033#
719 : // New mechanism to re-create the connections of cloned connectors
720 0 : CloneList aCloneList;
721 :
722 0 : for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
723 : {
724 0 : ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
725 :
726 0 : for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
727 : {
728 0 : const SdrMark* pMark = rObjVector[ i ];
729 0 : const SdrObject* pObj = pMark->GetMarkedSdrObj();
730 : SdrObject* pNeuObj;
731 :
732 0 : if( pObj->ISA( SdrPageObj ) )
733 : {
734 : // convert SdrPageObj's to a graphic representation, because
735 : // virtual connection to referenced page gets lost in new model
736 0 : pNeuObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() );
737 0 : pNeuObj->SetPage( pNeuPag );
738 0 : pNeuObj->SetModel( pNeuMod );
739 : }
740 : else
741 : {
742 0 : pNeuObj = pObj->Clone();
743 0 : pNeuObj->SetPage( pNeuPag );
744 0 : pNeuObj->SetModel( pNeuMod );
745 : }
746 :
747 0 : if( pNeuObj )
748 : {
749 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
750 0 : pNeuPag->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
751 :
752 : // #i13033#
753 0 : aCloneList.AddPair(pObj, pNeuObj);
754 : }
755 : else
756 0 : nCloneErrCnt++;
757 : }
758 : }
759 :
760 : // #i13033#
761 : // New mechanism to re-create the connections of cloned connectors
762 0 : aCloneList.CopyConnections();
763 :
764 : if(0L != nCloneErrCnt)
765 : {
766 : #ifdef DBG_UTIL
767 : rtl::OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM(
768 : "SdrExchangeView::GetMarkedObjModel(): Error when cloning "));
769 :
770 : if(nCloneErrCnt == 1)
771 : {
772 : aStr.append(RTL_CONSTASCII_STRINGPARAM(
773 : "a drawing object."));
774 : }
775 : else
776 : {
777 : aStr.append(static_cast<sal_Int32>(nCloneErrCnt));
778 : aStr.append(RTL_CONSTASCII_STRINGPARAM(" drawing objects."));
779 : }
780 :
781 : aStr.append(RTL_CONSTASCII_STRINGPARAM(
782 : " Not copying object connectors."));
783 :
784 : OSL_FAIL(aStr.getStr());
785 : #endif
786 0 : }
787 : }
788 0 : return pNeuMod;
789 : }
790 :
791 : // -----------------------------------------------------------------------------
792 :
793 0 : sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */)
794 : {
795 : OSL_FAIL( "SdrExchangeView::Cut: Not supported any more." );
796 0 : return sal_False;
797 : }
798 :
799 : // -----------------------------------------------------------------------------
800 :
801 0 : sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/)
802 : {
803 : OSL_FAIL( "SdrExchangeView::Yank: Not supported any more." );
804 0 : return sal_False;
805 : }
806 :
807 : // -----------------------------------------------------------------------------
808 :
809 0 : sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/)
810 : {
811 : OSL_FAIL( "SdrExchangeView::Paste: Not supported any more." );
812 0 : return sal_False;
813 : }
814 :
815 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|