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 <sdr/properties/emptyproperties.hxx>
22 #include <svx/svdovirt.hxx>
23 #include <svx/svdhdl.hxx>
24 #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
25 #include <svx/svdograf.hxx>
26 #include <svx/svddrgv.hxx>
27 #include <basegfx/matrix/b2dhommatrixtools.hxx>
29 sdr::properties::BaseProperties
& SdrVirtObj::GetProperties() const
31 return mxRefObj
->GetProperties();
35 std::unique_ptr
<sdr::properties::BaseProperties
> SdrVirtObj::CreateObjectSpecificProperties()
37 return std::make_unique
<sdr::properties::EmptyProperties
>(*this);
41 std::unique_ptr
<sdr::contact::ViewContact
> SdrVirtObj::CreateObjectSpecificViewContact()
43 return std::make_unique
<sdr::contact::ViewContactOfVirtObj
>(*this);
46 SdrVirtObj::SdrVirtObj(
49 : SdrObject(rSdrModel
),
52 m_bVirtObj
=true; // this is only a virtual object
53 mxRefObj
->AddReference(*this);
54 m_bClosedObj
= mxRefObj
->IsClosedObj();
57 SdrVirtObj::SdrVirtObj(
58 SdrModel
& rSdrModel
, SdrVirtObj
const & rSource
)
59 : SdrObject(rSdrModel
, rSource
),
60 mxRefObj(rSource
.mxRefObj
)
62 m_bVirtObj
=true; // this is only a virtual object
63 m_bClosedObj
= mxRefObj
->IsClosedObj();
65 mxRefObj
->AddReference(*this);
67 aSnapRect
= rSource
.aSnapRect
;
68 m_aAnchor
= rSource
.m_aAnchor
;
71 SdrVirtObj::~SdrVirtObj()
73 mxRefObj
->DelReference(*this);
76 const SdrObject
& SdrVirtObj::GetReferencedObj() const
81 SdrObject
& SdrVirtObj::ReferencedObj()
86 void SdrVirtObj::Notify(SfxBroadcaster
& /*rBC*/, const SfxHint
& /*rHint*/)
88 m_bClosedObj
= mxRefObj
->IsClosedObj();
89 SetBoundAndSnapRectsDirty(); // TODO: Optimize this.
91 // Only a repaint here, rRefObj may have changed and broadcasts
95 void SdrVirtObj::NbcSetAnchorPos(const Point
& rAnchorPos
)
100 bool SdrVirtObj::IsPrintable() const
102 return mxRefObj
->IsPrintable();
105 void SdrVirtObj::SetPrintable(bool const isPrintable
)
107 mxRefObj
->SetPrintable(isPrintable
);
110 bool SdrVirtObj::IsVisible() const
112 return mxRefObj
->IsVisible();
115 void SdrVirtObj::SetVisible(bool const isVisible
)
117 mxRefObj
->SetVisible(isVisible
);
120 void SdrVirtObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
122 mxRefObj
->TakeObjInfo(rInfo
);
125 SdrInventor
SdrVirtObj::GetObjInventor() const
127 return mxRefObj
->GetObjInventor();
130 SdrObjKind
SdrVirtObj::GetObjIdentifier() const
132 return mxRefObj
->GetObjIdentifier();
135 SdrObjList
* SdrVirtObj::GetSubList() const
137 return mxRefObj
->GetSubList();
140 void SdrVirtObj::SetName(const OUString
& rStr
, const bool bSetChanged
)
142 return mxRefObj
->SetName(rStr
, bSetChanged
);
145 const OUString
& SdrVirtObj::GetName() const
147 return mxRefObj
->GetName();
150 void SdrVirtObj::SetTitle(const OUString
& rStr
)
152 return mxRefObj
->SetTitle(rStr
);
155 OUString
SdrVirtObj::GetTitle() const
157 return mxRefObj
->GetTitle();
160 void SdrVirtObj::SetDescription(const OUString
& rStr
)
162 return mxRefObj
->SetDescription(rStr
);
165 OUString
SdrVirtObj::GetDescription() const
167 return mxRefObj
->GetDescription();
170 void SdrVirtObj::SetDecorative(bool const isDecorative
)
172 return mxRefObj
->SetDecorative(isDecorative
);
175 bool SdrVirtObj::IsDecorative() const
177 return mxRefObj
->IsDecorative();
180 const tools::Rectangle
& SdrVirtObj::GetCurrentBoundRect() const
182 auto aRectangle
= mxRefObj
->GetCurrentBoundRect(); // TODO: Optimize this.
183 aRectangle
+= m_aAnchor
;
184 setOutRectangleConst(aRectangle
);
185 return getOutRectangle();
188 const tools::Rectangle
& SdrVirtObj::GetLastBoundRect() const
190 auto aRectangle
= mxRefObj
->GetLastBoundRect(); // TODO: Optimize this.
191 aRectangle
+= m_aAnchor
;
192 setOutRectangleConst(aRectangle
);
193 return getOutRectangle();
196 void SdrVirtObj::RecalcBoundRect()
198 tools::Rectangle aRectangle
= mxRefObj
->GetCurrentBoundRect();
199 aRectangle
+= m_aAnchor
;
200 setOutRectangle(aRectangle
);
203 rtl::Reference
<SdrObject
> SdrVirtObj::CloneSdrObject(SdrModel
& rTargetModel
) const
205 return new SdrVirtObj(rTargetModel
, *this);
206 // TTTT not sure if the above works - how could SdrObjFactory::MakeNewObject
207 // create an object with correct rRefObj (?) OTOH VirtObj probably needs not
208 // to be cloned ever - only used in Writer for multiple instances e.g. Header/Footer
209 // return new SdrVirtObj(
210 // getSdrModelFromSdrObject(),
211 // rRefObj); // only a further reference
214 OUString
SdrVirtObj::TakeObjNameSingul() const
216 OUString sName
= "[" + mxRefObj
->TakeObjNameSingul() + "]";
218 OUString
aName(GetName());
219 if (!aName
.isEmpty())
220 sName
+= " '" + aName
+ "'";
225 OUString
SdrVirtObj::TakeObjNamePlural() const
227 return "[" + mxRefObj
->TakeObjNamePlural() + "]";
230 bool SdrVirtObj::HasLimitedRotation() const
232 // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation
233 return mxRefObj
->HasLimitedRotation();
236 basegfx::B2DPolyPolygon
SdrVirtObj::TakeXorPoly() const
238 basegfx::B2DPolyPolygon
aPolyPolygon(mxRefObj
->TakeXorPoly());
240 if(m_aAnchor
.X() || m_aAnchor
.Y())
242 aPolyPolygon
.transform(basegfx::utils::createTranslateB2DHomMatrix(m_aAnchor
.X(), m_aAnchor
.Y()));
249 sal_uInt32
SdrVirtObj::GetHdlCount() const
251 return mxRefObj
->GetHdlCount();
254 void SdrVirtObj::AddToHdlList(SdrHdlList
& rHdlList
) const
256 SdrHdlList
tempList(nullptr);
257 mxRefObj
->AddToHdlList(tempList
);
258 for (size_t i
=0; i
<tempList
.GetHdlCount(); ++i
)
260 SdrHdl
* pHdl
= tempList
.GetHdl(i
);
261 Point
aP(pHdl
->GetPos()+m_aAnchor
);
264 tempList
.MoveTo(rHdlList
);
267 void SdrVirtObj::AddToPlusHdlList(SdrHdlList
& rHdlList
, SdrHdl
& rHdl
) const
269 SdrHdlList
tempList(nullptr);
270 mxRefObj
->AddToPlusHdlList(tempList
, rHdl
);
271 for (size_t i
=0; i
<tempList
.GetHdlCount(); ++i
)
273 SdrHdl
* pHdl
= tempList
.GetHdl(i
);
274 Point
aP(pHdl
->GetPos()+m_aAnchor
);
277 tempList
.MoveTo(rHdlList
);
280 bool SdrVirtObj::hasSpecialDrag() const
282 return mxRefObj
->hasSpecialDrag();
285 bool SdrVirtObj::supportsFullDrag() const
290 rtl::Reference
<SdrObject
> SdrVirtObj::getFullDragClone() const
292 SdrObject
& rReferencedObject
= const_cast<SdrVirtObj
*>(this)->ReferencedObj();
293 return rtl::Reference
<SdrObject
>(new SdrGrafObj(
294 getSdrModelFromSdrObject(),
295 SdrDragView::GetObjGraphic(rReferencedObject
),
299 bool SdrVirtObj::beginSpecialDrag(SdrDragStat
& rDrag
) const
301 return mxRefObj
->beginSpecialDrag(rDrag
);
304 bool SdrVirtObj::applySpecialDrag(SdrDragStat
& rDrag
)
306 return mxRefObj
->applySpecialDrag(rDrag
);
309 basegfx::B2DPolyPolygon
SdrVirtObj::getSpecialDragPoly(const SdrDragStat
& rDrag
) const
311 return mxRefObj
->getSpecialDragPoly(rDrag
);
312 // TODO: we don't handle offsets yet!
315 OUString
SdrVirtObj::getSpecialDragComment(const SdrDragStat
& rDrag
) const
317 return mxRefObj
->getSpecialDragComment(rDrag
);
321 bool SdrVirtObj::BegCreate(SdrDragStat
& rStat
)
323 return mxRefObj
->BegCreate(rStat
);
326 bool SdrVirtObj::MovCreate(SdrDragStat
& rStat
)
328 return mxRefObj
->MovCreate(rStat
);
331 bool SdrVirtObj::EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
333 return mxRefObj
->EndCreate(rStat
,eCmd
);
336 bool SdrVirtObj::BckCreate(SdrDragStat
& rStat
)
338 return mxRefObj
->BckCreate(rStat
);
341 void SdrVirtObj::BrkCreate(SdrDragStat
& rStat
)
343 mxRefObj
->BrkCreate(rStat
);
346 basegfx::B2DPolyPolygon
SdrVirtObj::TakeCreatePoly(const SdrDragStat
& rDrag
) const
348 return mxRefObj
->TakeCreatePoly(rDrag
);
349 // TODO: we don't handle offsets yet!
353 void SdrVirtObj::NbcMove(const Size
& rSiz
)
355 m_aAnchor
.Move(rSiz
);
356 SetBoundAndSnapRectsDirty();
359 void SdrVirtObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
361 mxRefObj
->NbcResize(rRef
-m_aAnchor
,xFact
,yFact
);
362 SetBoundAndSnapRectsDirty();
365 void SdrVirtObj::NbcRotate(const Point
& rRef
, Degree100 nAngle
, double sn
, double cs
)
367 mxRefObj
->NbcRotate(rRef
-m_aAnchor
,nAngle
,sn
,cs
);
368 SetBoundAndSnapRectsDirty();
371 void SdrVirtObj::NbcMirror(const Point
& rRef1
, const Point
& rRef2
)
373 mxRefObj
->NbcMirror(rRef1
-m_aAnchor
,rRef2
-m_aAnchor
);
374 SetBoundAndSnapRectsDirty();
377 void SdrVirtObj::NbcShear(const Point
& rRef
, Degree100 nAngle
, double tn
, bool bVShear
)
379 mxRefObj
->NbcShear(rRef
-m_aAnchor
,nAngle
,tn
,bVShear
);
380 SetBoundAndSnapRectsDirty();
384 void SdrVirtObj::Move(const Size
& rSiz
)
386 if (!rSiz
.IsEmpty()) {
387 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
390 BroadcastObjectChange();
391 SendUserCall(SdrUserCallType::MoveOnly
,aBoundRect0
);
395 void SdrVirtObj::Resize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bUnsetRelative
)
397 if (xFact
.GetNumerator()!=xFact
.GetDenominator() || yFact
.GetNumerator()!=yFact
.GetDenominator()) {
398 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
399 mxRefObj
->Resize(rRef
-m_aAnchor
,xFact
,yFact
, bUnsetRelative
);
400 SetBoundAndSnapRectsDirty();
401 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
405 void SdrVirtObj::Rotate(const Point
& rRef
, Degree100 nAngle
, double sn
, double cs
)
408 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
409 mxRefObj
->Rotate(rRef
-m_aAnchor
,nAngle
,sn
,cs
);
410 SetBoundAndSnapRectsDirty();
411 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
415 void SdrVirtObj::Mirror(const Point
& rRef1
, const Point
& rRef2
)
417 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
418 mxRefObj
->Mirror(rRef1
-m_aAnchor
,rRef2
-m_aAnchor
);
419 SetBoundAndSnapRectsDirty();
420 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
423 void SdrVirtObj::Shear(const Point
& rRef
, Degree100 nAngle
, double tn
, bool bVShear
)
426 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
427 mxRefObj
->Shear(rRef
-m_aAnchor
,nAngle
,tn
,bVShear
);
428 SetBoundAndSnapRectsDirty();
429 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
434 void SdrVirtObj::RecalcSnapRect()
436 aSnapRect
=mxRefObj
->GetSnapRect();
437 aSnapRect
+=m_aAnchor
;
440 const tools::Rectangle
& SdrVirtObj::GetSnapRect() const
442 const_cast<SdrVirtObj
*>(this)->aSnapRect
=mxRefObj
->GetSnapRect();
443 const_cast<SdrVirtObj
*>(this)->aSnapRect
+=m_aAnchor
;
447 void SdrVirtObj::SetSnapRect(const tools::Rectangle
& rRect
)
449 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
450 tools::Rectangle
aR(rRect
);
452 mxRefObj
->SetSnapRect(aR
);
453 SetBoundAndSnapRectsDirty();
454 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
457 void SdrVirtObj::NbcSetSnapRect(const tools::Rectangle
& rRect
)
459 tools::Rectangle
aR(rRect
);
461 SetBoundAndSnapRectsDirty();
462 mxRefObj
->NbcSetSnapRect(aR
);
466 const tools::Rectangle
& SdrVirtObj::GetLogicRect() const
468 const_cast<SdrVirtObj
*>(this)->aSnapRect
=mxRefObj
->GetLogicRect(); // An abuse of aSnapRect!
469 const_cast<SdrVirtObj
*>(this)->aSnapRect
+=m_aAnchor
; // If there's trouble, we need another Rectangle Member (or a Heap).
473 void SdrVirtObj::SetLogicRect(const tools::Rectangle
& rRect
)
475 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
476 tools::Rectangle
aR(rRect
);
478 mxRefObj
->SetLogicRect(aR
);
479 SetBoundAndSnapRectsDirty();
480 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
483 void SdrVirtObj::NbcSetLogicRect(const tools::Rectangle
& rRect
, bool bAdaptTextMinSize
)
485 tools::Rectangle
aR(rRect
);
487 SetBoundAndSnapRectsDirty();
488 mxRefObj
->NbcSetLogicRect(aR
, bAdaptTextMinSize
);
492 Degree100
SdrVirtObj::GetRotateAngle() const
494 return mxRefObj
->GetRotateAngle();
497 Degree100
SdrVirtObj::GetShearAngle(bool bVertical
) const
499 return mxRefObj
->GetShearAngle(bVertical
);
503 sal_uInt32
SdrVirtObj::GetSnapPointCount() const
505 return mxRefObj
->GetSnapPointCount();
508 Point
SdrVirtObj::GetSnapPoint(sal_uInt32 i
) const
510 Point
aP(mxRefObj
->GetSnapPoint(i
));
515 bool SdrVirtObj::IsPolyObj() const
517 return mxRefObj
->IsPolyObj();
520 sal_uInt32
SdrVirtObj::GetPointCount() const
522 return mxRefObj
->GetPointCount();
525 Point
SdrVirtObj::GetPoint(sal_uInt32 i
) const
527 return mxRefObj
->GetPoint(i
) + m_aAnchor
;
530 void SdrVirtObj::NbcSetPoint(const Point
& rPnt
, sal_uInt32 i
)
534 mxRefObj
->SetPoint(aP
,i
);
535 SetBoundAndSnapRectsDirty();
539 std::unique_ptr
<SdrObjGeoData
> SdrVirtObj::NewGeoData() const
541 return mxRefObj
->NewGeoData();
544 void SdrVirtObj::SaveGeoData(SdrObjGeoData
& rGeo
) const
546 mxRefObj
->SaveGeoData(rGeo
);
549 void SdrVirtObj::RestoreGeoData(const SdrObjGeoData
& rGeo
)
551 mxRefObj
->RestoreGeoData(rGeo
);
552 SetBoundAndSnapRectsDirty();
556 std::unique_ptr
<SdrObjGeoData
> SdrVirtObj::GetGeoData() const
558 return mxRefObj
->GetGeoData();
561 void SdrVirtObj::SetGeoData(const SdrObjGeoData
& rGeo
)
563 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
564 mxRefObj
->SetGeoData(rGeo
);
565 SetBoundAndSnapRectsDirty();
566 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
570 void SdrVirtObj::NbcReformatText()
572 mxRefObj
->NbcReformatText();
575 bool SdrVirtObj::HasMacro() const
577 return mxRefObj
->HasMacro();
580 SdrObject
* SdrVirtObj::CheckMacroHit(const SdrObjMacroHitRec
& rRec
) const
582 return mxRefObj
->CheckMacroHit(rRec
); // TODO: positioning offset
585 PointerStyle
SdrVirtObj::GetMacroPointer(const SdrObjMacroHitRec
& rRec
) const
587 return mxRefObj
->GetMacroPointer(rRec
); // TODO: positioning offset
590 void SdrVirtObj::PaintMacro(OutputDevice
& rOut
, const tools::Rectangle
& rDirtyRect
, const SdrObjMacroHitRec
& rRec
) const
592 mxRefObj
->PaintMacro(rOut
,rDirtyRect
,rRec
); // TODO: positioning offset
595 bool SdrVirtObj::DoMacro(const SdrObjMacroHitRec
& rRec
)
597 return mxRefObj
->DoMacro(rRec
); // TODO: positioning offset
600 Point
SdrVirtObj::GetOffset() const
602 // #i73248# default offset of SdrVirtObj is aAnchor
606 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */