1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <unordered_set>
22 #include <editeng/editdata.hxx>
23 #include <rtl/strbuf.hxx>
24 #include <svx/xfillit0.hxx>
25 #include <svx/xlineit0.hxx>
26 #include <svx/svdxcgv.hxx>
27 #include <svx/svdoutl.hxx>
28 #include <svx/svdundo.hxx>
29 #include <svx/svdograf.hxx>
30 #include <svx/svdomedia.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <svx/svdorect.hxx>
33 #include <svx/svdopage.hxx>
34 #include <svx/svdpage.hxx>
35 #include <svx/svdpagv.hxx>
36 #include <svx/svdtrans.hxx>
37 #include <svx/strings.hrc>
38 #include <svx/dialmgr.hxx>
39 #include <tools/bigint.hxx>
40 #include <clonelist.hxx>
41 #include <vcl/virdev.hxx>
42 #include <svl/style.hxx>
44 #include <vcl/vectorgraphicdata.hxx>
45 #include <drawinglayer/primitive2d/groupprimitive2d.hxx>
46 #include <drawinglayer/geometry/viewinformation2d.hxx>
47 #include <drawinglayer/converters.hxx>
48 #include <svx/sdr/contact/viewcontact.hxx>
49 #include <sdr/contact/objectcontactofobjlistpainter.hxx>
50 #include <svx/sdr/contact/displayinfo.hxx>
51 #include <svx/svdotable.hxx>
52 #include <sal/log.hxx>
53 #include <osl/diagnose.h>
54 #include <comphelper/lok.hxx>
56 using namespace com::sun::star
;
58 SdrExchangeView::SdrExchangeView(
61 : SdrObjEditView(rSdrModel
, pOut
)
65 bool SdrExchangeView::ImpLimitToWorkArea(Point
& rPt
) const
69 if(!maMaxWorkArea
.IsEmpty())
71 if(rPt
.X()<maMaxWorkArea
.Left())
73 rPt
.setX( maMaxWorkArea
.Left() );
77 if(rPt
.X()>maMaxWorkArea
.Right())
79 rPt
.setX( maMaxWorkArea
.Right() );
83 if(rPt
.Y()<maMaxWorkArea
.Top())
85 rPt
.setY( maMaxWorkArea
.Top() );
89 if(rPt
.Y()>maMaxWorkArea
.Bottom())
91 rPt
.setY( maMaxWorkArea
.Bottom() );
98 void SdrExchangeView::ImpGetPasteObjList(Point
& /*rPos*/, SdrObjList
*& rpLst
)
102 SdrPageView
* pPV
= GetSdrPageView();
105 rpLst
=pPV
->GetObjList();
110 bool SdrExchangeView::ImpGetPasteLayer(const SdrObjList
* pObjList
, SdrLayerID
& rLayer
) const
113 rLayer
=SdrLayerID(0);
114 if (pObjList
!=nullptr) {
115 const SdrPage
* pPg
=pObjList
->getSdrPageFromSdrObjList();
117 rLayer
=pPg
->GetLayerAdmin().GetLayerID(maActualLayer
);
118 if (rLayer
==SDRLAYER_NOTFOUND
) rLayer
=SdrLayerID(0);
119 SdrPageView
* pPV
= GetSdrPageView();
121 bRet
=!pPV
->GetLockedLayers().IsSet(rLayer
) && pPV
->GetVisibleLayers().IsSet(rLayer
);
128 bool SdrExchangeView::Paste(const OUString
& rStr
, const Point
& rPos
, SdrObjList
* pLst
, SdrInsertFlags nOptions
)
134 ImpGetPasteObjList(aPos
,pLst
);
135 ImpLimitToWorkArea( aPos
);
136 if (pLst
==nullptr) return false;
138 if (!ImpGetPasteLayer(pLst
,nLayer
)) return false;
139 bool bUnmark
= (nOptions
& (SdrInsertFlags::DONTMARK
|SdrInsertFlags::ADDMARK
))==SdrInsertFlags::NONE
&& !IsTextEdit();
140 if (bUnmark
) UnmarkAllObj();
141 tools::Rectangle
aTextRect(0,0,500,500);
142 SdrPage
* pPage
=pLst
->getSdrPageFromSdrObjList();
143 if (pPage
!=nullptr) {
144 aTextRect
.SetSize(pPage
->GetSize());
146 rtl::Reference
<SdrRectObj
> pObj
= new SdrRectObj(
147 getSdrModelFromSdrView(),
151 pObj
->SetLayer(nLayer
);
152 pObj
->NbcSetText(rStr
); // SetText before SetAttr, else SetAttr doesn't work!
153 if (mpDefaultStyleSheet
!=nullptr) pObj
->NbcSetStyleSheet(mpDefaultStyleSheet
, false);
155 pObj
->SetMergedItemSet(maDefaultAttr
);
157 SfxItemSet
aTempAttr(GetModel().GetItemPool()); // no fill, no line
158 aTempAttr
.Put(XLineStyleItem(drawing::LineStyle_NONE
));
159 aTempAttr
.Put(XFillStyleItem(drawing::FillStyle_NONE
));
161 pObj
->SetMergedItemSet(aTempAttr
);
163 pObj
->FitFrameToTextSize();
164 Size
aSiz(pObj
->GetLogicRect().GetSize());
165 MapUnit eMap
= GetModel().GetScaleUnit();
166 ImpPasteObject(pObj
.get(), *pLst
, aPos
, aSiz
, MapMode(eMap
), nOptions
);
170 bool SdrExchangeView::Paste(SvStream
& rInput
, EETextFormat eFormat
, const Point
& rPos
, SdrObjList
* pLst
, SdrInsertFlags nOptions
)
173 ImpGetPasteObjList(aPos
,pLst
);
174 ImpLimitToWorkArea( aPos
);
175 if (pLst
==nullptr) return false;
177 if (!ImpGetPasteLayer(pLst
,nLayer
)) return false;
178 bool bUnmark
=(nOptions
&(SdrInsertFlags::DONTMARK
|SdrInsertFlags::ADDMARK
))==SdrInsertFlags::NONE
&& !IsTextEdit();
179 if (bUnmark
) UnmarkAllObj();
180 tools::Rectangle
aTextRect(0,0,500,500);
181 SdrPage
* pPage
=pLst
->getSdrPageFromSdrObjList();
182 if (pPage
!=nullptr) {
183 aTextRect
.SetSize(pPage
->GetSize());
185 rtl::Reference
<SdrRectObj
> pObj
= new SdrRectObj(
186 getSdrModelFromSdrView(),
190 pObj
->SetLayer(nLayer
);
191 if (mpDefaultStyleSheet
!=nullptr) pObj
->NbcSetStyleSheet(mpDefaultStyleSheet
, false);
193 pObj
->SetMergedItemSet(maDefaultAttr
);
195 SfxItemSet
aTempAttr(GetModel().GetItemPool()); // no fill, no line
196 aTempAttr
.Put(XLineStyleItem(drawing::LineStyle_NONE
));
197 aTempAttr
.Put(XFillStyleItem(drawing::FillStyle_NONE
));
199 pObj
->SetMergedItemSet(aTempAttr
);
201 pObj
->NbcSetText(rInput
,OUString(),eFormat
);
202 pObj
->FitFrameToTextSize();
203 Size
aSiz(pObj
->GetLogicRect().GetSize());
204 MapUnit eMap
= GetModel().GetScaleUnit();
205 ImpPasteObject(pObj
.get(), *pLst
, aPos
, aSiz
, MapMode(eMap
), nOptions
);
208 if(pObj
->GetOutlinerParaObject())
210 SdrOutliner
& rOutliner
= pObj
->getSdrModelFromSdrObject().GetHitTestOutliner();
211 rOutliner
.SetText(*pObj
->GetOutlinerParaObject());
213 if(1 == rOutliner
.GetParagraphCount())
215 SfxStyleSheet
* pCandidate
= rOutliner
.GetStyleSheet(0);
219 if(pObj
->getSdrModelFromSdrObject().GetStyleSheetPool() == pCandidate
->GetPool())
221 pObj
->NbcSetStyleSheet(pCandidate
, true);
230 bool SdrExchangeView::Paste(
231 const SdrModel
& rMod
, const Point
& rPos
, SdrObjList
* pLst
, SdrInsertFlags nOptions
)
233 const SdrModel
* pSrcMod
=&rMod
;
234 if (pSrcMod
== &GetModel())
235 return false; // this can't work, right?
237 const bool bUndo
= IsUndoEnabled();
240 BegUndo(SvxResId(STR_ExchangePaste
));
242 if( mxSelectionController
.is() && mxSelectionController
->PasteObjModel( rMod
) )
250 ImpGetPasteObjList(aPos
,pLst
);
251 SdrPageView
* pMarkPV
=nullptr;
252 SdrPageView
* pPV
= GetSdrPageView();
254 if(pPV
&& pPV
->GetObjList() == pLst
)
257 ImpLimitToWorkArea( aPos
);
261 bool bUnmark
=(nOptions
&(SdrInsertFlags::DONTMARK
|SdrInsertFlags::ADDMARK
))==SdrInsertFlags::NONE
&& !IsTextEdit();
265 // Rescale, if the Model uses a different MapUnit.
266 // Calculate the necessary factors first.
267 MapUnit eSrcUnit
= pSrcMod
->GetScaleUnit();
268 MapUnit eDstUnit
= GetModel().GetScaleUnit();
269 bool bResize
=eSrcUnit
!=eDstUnit
;
270 Fraction aXResize
,aYResize
;
274 FrPair
aResize(GetMapFactor(eSrcUnit
,eDstUnit
));
275 aXResize
=aResize
.X();
276 aYResize
=aResize
.Y();
278 SdrObjList
* pDstLst
=pLst
;
279 sal_uInt16 nPg
,nPgCount
=pSrcMod
->GetPageCount();
280 for (nPg
=0; nPg
<nPgCount
; nPg
++)
282 const SdrPage
* pSrcPg
=pSrcMod
->GetPage(nPg
);
284 // Use SnapRect, not BoundRect here
285 tools::Rectangle aR
=pSrcPg
->GetAllObjSnapRect();
288 ResizeRect(aR
,aPt0
,aXResize
,aYResize
);
289 Point
aDist(aPos
-aR
.Center());
290 Size
aSiz(aDist
.X(),aDist
.Y());
291 size_t nCloneErrCnt
= 0;
292 const size_t nObjCount
= pSrcPg
->GetObjCount();
293 bool bMark
= pMarkPV
!=nullptr && !IsTextEdit() && (nOptions
&SdrInsertFlags::DONTMARK
)==SdrInsertFlags::NONE
;
296 // New mechanism to re-create the connections of cloned connectors
297 CloneList aCloneList
;
298 std::unordered_set
<rtl::OUString
> aNameSet
;
299 for (size_t nOb
=0; nOb
<nObjCount
; ++nOb
)
301 const SdrObject
* pSrcOb
=pSrcPg
->GetObj(nOb
);
303 rtl::Reference
<SdrObject
> pNewObj(pSrcOb
->CloneSdrObject(GetModel()));
305 if (pNewObj
!=nullptr)
309 pNewObj
->getSdrModelFromSdrObject().SetPasteResize(true);
310 pNewObj
->NbcResize(aPt0
,aXResize
,aYResize
);
311 pNewObj
->getSdrModelFromSdrObject().SetPasteResize(false);
315 pNewObj
->NbcMove(aSiz
);
317 const SdrPage
* pPg
= pDstLst
->getSdrPageFromSdrObjList();
322 const SdrLayerAdmin
& rAd
= pPg
->GetLayerAdmin();
323 SdrLayerID
nLayer(0);
325 if(dynamic_cast<const FmFormObj
*>( pNewObj
.get()) != nullptr)
327 // for FormControls, force to form layer
328 nLayer
= rAd
.GetLayerID(rAd
.GetControlLayerName());
332 nLayer
= rAd
.GetLayerID(maActualLayer
);
335 if(SDRLAYER_NOTFOUND
== nLayer
)
337 nLayer
= SdrLayerID(0);
340 pNewObj
->SetLayer(nLayer
);
343 pDstLst
->InsertObjectThenMakeNameUnique(pNewObj
.get(), aNameSet
);
346 AddUndo(getSdrModelFromSdrView().GetSdrUndoFactory().CreateUndoNewObject(*pNewObj
));
349 // Don't already set Markhandles!
350 // That is instead being done by ModelHasChanged in MarkView.
351 MarkObj(pNewObj
.get(),pMarkPV
,false,true);
355 aCloneList
.AddPair(pSrcOb
, pNewObj
.get());
364 // New mechanism to re-create the connections of cloned connectors
365 aCloneList
.CopyConnections();
367 if(0 != nCloneErrCnt
)
370 OStringBuffer
aStr("SdrExchangeView::Paste(): Error when cloning ");
372 if(nCloneErrCnt
== 1)
374 aStr
.append("a drawing object.");
378 aStr
.append(OString::number(static_cast<sal_Int32
>(nCloneErrCnt
))
379 + " drawing objects.");
382 aStr
.append(" Not copying object connectors.");
384 OSL_FAIL(aStr
.getStr());
395 void SdrExchangeView::ImpPasteObject(SdrObject
* pObj
, SdrObjList
& rLst
, const Point
& rCenter
, const Size
& rSiz
, const MapMode
& rMap
, SdrInsertFlags nOptions
)
397 BigInt
nSizX(rSiz
.Width());
398 BigInt
nSizY(rSiz
.Height());
399 MapUnit eSrcMU
=rMap
.GetMapUnit();
400 MapUnit eDstMU
= GetModel().GetScaleUnit();
401 FrPair
aMapFact(GetMapFactor(eSrcMU
,eDstMU
));
402 nSizX
*= double(aMapFact
.X() * rMap
.GetScaleX());
403 nSizY
*= double(aMapFact
.Y() * rMap
.GetScaleY());
404 tools::Long xs
=nSizX
;
405 tools::Long ys
=nSizY
;
406 // set the pos to 0, 0 for online case
407 bool isLOK
= comphelper::LibreOfficeKit::isActive();
408 Point
aPos(isLOK
? 0 : rCenter
.X()-xs
/2, isLOK
? 0 : rCenter
.Y()-ys
/2);
409 tools::Rectangle
aR(aPos
.X(),aPos
.Y(),aPos
.X()+xs
,aPos
.Y()+ys
);
410 pObj
->SetLogicRect(aR
);
411 rLst
.InsertObject(pObj
, SAL_MAX_SIZE
);
413 if( IsUndoEnabled() )
414 AddUndo(getSdrModelFromSdrView().GetSdrUndoFactory().CreateUndoNewObject(*pObj
));
416 SdrPageView
* pMarkPV
=nullptr;
417 SdrPageView
* pPV
= GetSdrPageView();
419 if(pPV
&& pPV
->GetObjList()==&rLst
)
422 bool bMark
= pMarkPV
!=nullptr && !IsTextEdit() && (nOptions
&SdrInsertFlags::DONTMARK
)==SdrInsertFlags::NONE
;
424 { // select object the first PageView we found
425 MarkObj(pObj
,pMarkPV
);
429 BitmapEx
SdrExchangeView::GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked
, const sal_uInt32 nMaximumQuadraticPixels
, const std::optional
<Size
>& rTargetDPI
) const
433 if( AreObjectsMarked() )
435 if(1 == GetMarkedObjectCount())
437 if(bNoVDevIfOneBmpMarked
)
439 SdrObject
* pGrafObjTmp
= GetMarkedObjectByIndex( 0 );
440 SdrGrafObj
* pGrafObj
= dynamic_cast<SdrGrafObj
*>( pGrafObjTmp
);
442 if( pGrafObj
&& ( pGrafObj
->GetGraphicType() == GraphicType::Bitmap
) )
444 aBmp
= pGrafObj
->GetTransformedGraphic().GetBitmapEx();
449 const SdrGrafObj
* pSdrGrafObj
= dynamic_cast< const SdrGrafObj
* >(GetMarkedObjectByIndex(0));
451 if(pSdrGrafObj
&& pSdrGrafObj
->isEmbeddedVectorGraphicData())
453 aBmp
= pSdrGrafObj
->GetGraphic().getVectorGraphicData()->getReplacement();
460 // choose conversion directly using primitives to bitmap to avoid
461 // rendering errors with tiled bitmap fills (these will be tiled in a
462 // in-between metafile, but tend to show 'gaps' since the target is *no*
464 ::std::vector
< SdrObject
* > aSdrObjects(GetMarkedObjects());
465 const sal_uInt32
nCount(aSdrObjects
.size());
469 // collect sub-primitives as group objects, thus no expensive append
470 // to existing sequence is needed
471 drawinglayer::primitive2d::Primitive2DContainer
xPrimitives(nCount
);
473 for(sal_uInt32
a(0); a
< nCount
; a
++)
475 SdrObject
* pCandidate
= aSdrObjects
[a
];
476 SdrGrafObj
* pSdrGrafObj
= dynamic_cast< SdrGrafObj
* >(pCandidate
);
480 // #122753# To ensure existence of graphic content, force swap in
481 pSdrGrafObj
->ForceSwapIn();
484 drawinglayer::primitive2d::Primitive2DContainer xRetval
;
485 pCandidate
->GetViewContact().getViewIndependentPrimitive2DContainer(xRetval
);
486 xPrimitives
[a
] = new drawinglayer::primitive2d::GroupPrimitive2D(
491 const drawinglayer::geometry::ViewInformation2D aViewInformation2D
;
492 const basegfx::B2DRange
aRange(xPrimitives
.getB2DRange(aViewInformation2D
));
494 if(!aRange
.isEmpty())
496 o3tl::Length eRangeUnit
= o3tl::Length::mm100
;
498 if (GetModel().IsWriter())
500 eRangeUnit
= o3tl::Length::twip
;
503 // if we have geometry and it has a range, convert to BitmapEx using
505 aBmp
= drawinglayer::convertPrimitive2DContainerToBitmapEx(
506 std::move(xPrimitives
),
508 nMaximumQuadraticPixels
,
520 GDIMetaFile
SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked
) const
524 if( AreObjectsMarked() )
526 tools::Rectangle
aBound( GetMarkedObjBoundRect() );
527 Size
aBoundSize( aBound
.GetWidth(), aBound
.GetHeight() );
528 MapMode
aMap(GetModel().GetScaleUnit());
530 if( bNoVDevIfOneMtfMarked
)
532 SdrObject
* pGrafObjTmp
= GetMarkedObjectByIndex( 0 );
533 SdrGrafObj
* pGrafObj
= ( GetMarkedObjectCount() ==1 ) ? dynamic_cast<SdrGrafObj
*>( pGrafObjTmp
) : nullptr;
537 Graphic
aGraphic( pGrafObj
->GetTransformedGraphic() );
539 // #119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
540 aMtf
= aGraphic
.GetGDIMetaFile();
544 if( !aMtf
.GetActionSize() )
546 ScopedVclPtrInstance
< VirtualDevice
> pOut
;
547 const Size
aDummySize(2, 2);
549 pOut
->SetOutputSizePixel(aDummySize
);
550 pOut
->EnableOutput(false);
551 pOut
->SetMapMode(aMap
);
555 DrawMarkedObj(*pOut
);
560 // moving the result is more reliable then setting a relative MapMode at the VDev (used
561 // before), also see #i99268# in GetObjGraphic() below. Some draw actions at
562 // the OutDev are simply not handled correctly when a MapMode is set at the
563 // target device, e.g. MetaFloatTransparentAction. Even the Move for this action
564 // was missing the manipulation of the embedded Metafile
565 aMtf
.Move(-aBound
.Left(), -aBound
.Top());
567 aMtf
.SetPrefMapMode( aMap
);
569 // removed PrefSize extension. It is principally wrong to set a reduced size at
570 // the created MetaFile. The mentioned errors occur at output time since the integer
571 // MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for
572 // primitives (and may later be done in breaking up a MetaFile to primitives)
573 aMtf
.SetPrefSize(aBoundSize
);
581 Graphic
SdrExchangeView::GetAllMarkedGraphic() const
585 if( AreObjectsMarked() )
587 if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) )
588 aRet
= SdrExchangeView::GetObjGraphic(*GetMarkedObjectByIndex(0));
590 aRet
= GetMarkedObjMetaFile();
597 // tdf#155479 bSVG: need to know it's SVG export, default is false
598 Graphic
SdrExchangeView::GetObjGraphic(const SdrObject
& rSdrObject
, bool bSVG
)
602 if (!rSdrObject
.HasText())
604 // try to get a graphic from the object first
605 const SdrGrafObj
* pSdrGrafObj(dynamic_cast<const SdrGrafObj
*>(&rSdrObject
));
606 const SdrOle2Obj
* pSdrOle2Obj(dynamic_cast<const SdrOle2Obj
*>(&rSdrObject
));
610 if (pSdrGrafObj
->isEmbeddedVectorGraphicData())
612 // get Metafile for Svg content
613 aRet
= pSdrGrafObj
->getMetafileFromEmbeddedVectorGraphicData();
617 // Make behaviour coherent with metafile
618 // recording below (which of course also takes
619 // view-transformed objects)
620 aRet
= pSdrGrafObj
->GetTransformedGraphic();
623 else if (pSdrOle2Obj
)
625 if (pSdrOle2Obj
->GetGraphic())
627 aRet
= *pSdrOle2Obj
->GetGraphic();
632 // Support extracting a snapshot from video media, if possible.
633 const SdrMediaObj
* pSdrMediaObj
= dynamic_cast<const SdrMediaObj
*>(&rSdrObject
);
636 const css::uno::Reference
<css::graphic::XGraphic
>& xGraphic
637 = pSdrMediaObj
->getSnapshot();
639 aRet
= Graphic(xGraphic
);
644 // if graphic could not be retrieved => go the hard way and create a MetaFile
645 if((GraphicType::NONE
== aRet
.GetType()) || (GraphicType::Default
== aRet
.GetType()))
647 ScopedVclPtrInstance
< VirtualDevice
> pOut
;
649 const tools::Rectangle
aBoundRect(rSdrObject
.GetCurrentBoundRect());
650 const MapMode
aMap(rSdrObject
.getSdrModelFromSdrObject().GetScaleUnit());
652 pOut
->EnableOutput(false);
653 pOut
->SetMapMode(aMap
);
656 rSdrObject
.SingleObjectPainter(*pOut
);
660 // #i99268# replace the original offset from using XOutDev's SetOffset
661 // NOT (as tried with #i92760#) with another MapMode which gets recorded
662 // by the Metafile itself (what always leads to problems), but by
663 // moving the result directly
664 aMtf
.Move(-aBoundRect
.Left(), -aBoundRect
.Top());
665 aMtf
.SetPrefMapMode(aMap
);
666 aMtf
.SetPrefSize(aBoundRect
.GetSize());
668 if(aMtf
.GetActionSize())
678 ::std::vector
< SdrObject
* > SdrExchangeView::GetMarkedObjects() const
681 ::std::vector
< SdrObject
* > aRetval
;
683 ::std::vector
< ::std::vector
< SdrMark
* > > aObjVectors( 2 );
684 ::std::vector
< SdrMark
* >& rObjVector1
= aObjVectors
[ 0 ];
685 ::std::vector
< SdrMark
* >& rObjVector2
= aObjVectors
[ 1 ];
686 const SdrLayerAdmin
& rLayerAdmin
= GetModel().GetLayerAdmin();
687 const SdrLayerID nControlLayerId
= rLayerAdmin
.GetLayerID( rLayerAdmin
.GetControlLayerName() );
689 for( size_t n
= 0, nCount
= GetMarkedObjectCount(); n
< nCount
; ++n
)
691 SdrMark
* pMark
= GetSdrMarkByIndex( n
);
693 // paint objects on control layer on top of all other objects
694 if( nControlLayerId
== pMark
->GetMarkedSdrObj()->GetLayer() )
695 rObjVector2
.push_back( pMark
);
697 rObjVector1
.push_back( pMark
);
700 for(const std::vector
<SdrMark
*> & rObjVector
: aObjVectors
)
702 for(SdrMark
* pMark
: rObjVector
)
704 aRetval
.push_back(pMark
->GetMarkedSdrObj());
712 void SdrExchangeView::DrawMarkedObj(OutputDevice
& rOut
) const
714 ::std::vector
< SdrObject
* > aSdrObjects(GetMarkedObjects());
716 if(!aSdrObjects
.empty())
718 sdr::contact::ObjectContactOfObjListPainter
aPainter(rOut
, std::move(aSdrObjects
), aSdrObjects
[0]->getSdrPageFromSdrObject());
719 sdr::contact::DisplayInfo aDisplayInfo
;
722 aPainter
.ProcessDisplay(aDisplayInfo
);
726 std::unique_ptr
<SdrModel
> SdrExchangeView::CreateMarkedObjModel() const
728 // Sorting the MarkList here might be problematic in the future, so
731 std::unique_ptr
<SdrModel
> pNewModel(GetModel().AllocModel());
732 rtl::Reference
<SdrPage
> pNewPage
= pNewModel
->AllocPage(false);
733 pNewModel
->InsertPage(pNewPage
.get());
734 ::std::vector
< SdrObject
* > aSdrObjects(GetMarkedObjects());
737 // New mechanism to re-create the connections of cloned connectors
738 CloneList aCloneList
;
740 for(SdrObject
* pObj
: aSdrObjects
)
742 rtl::Reference
<SdrObject
> pNewObj
;
744 if(nullptr != dynamic_cast< const SdrPageObj
* >(pObj
))
746 // convert SdrPageObj's to a graphic representation, because
747 // virtual connection to referenced page gets lost in new model
748 pNewObj
= new SdrGrafObj(
750 GetObjGraphic(*pObj
),
751 pObj
->GetLogicRect());
753 else if(nullptr != dynamic_cast< const sdr::table::SdrTableObj
* >(pObj
))
755 // check if we have a valid selection *different* from whole table
757 if(mxSelectionController
.is())
759 pNewObj
= mxSelectionController
->GetMarkedSdrObjClone(*pNewModel
);
766 if(pObj
->GetObjIdentifier() == SdrObjKind::OLE2
&& nullptr == GetModel().GetPersist())
768 // tdf#125520 - former fix was wrong, the SdrModel
769 // has to have a GetPersist() already, see task.
770 // We can still warn here when this is not the case
771 SAL_WARN( "svx", "OLE gets cloned Persist, EmbeddedObjectContainer will not be copied" );
775 pNewObj
= pObj
->CloneSdrObject(*pNewModel
);
780 pNewPage
->InsertObject(pNewObj
.get(), SAL_MAX_SIZE
);
783 aCloneList
.AddPair(pObj
, pNewObj
.get());
788 // New mechanism to re-create the connections of cloned connectors
789 aCloneList
.CopyConnections();
794 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */