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