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