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 <svx/svdovirt.hxx>
22 #include <svx/svdhdl.hxx>
23 #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
24 #include <svx/svdograf.hxx>
25 #include <svx/svddrgv.hxx>
26 #include <basegfx/matrix/b2dhommatrixtools.hxx>
28 sdr::properties::BaseProperties
& SdrVirtObj::GetProperties() const
30 return mxRefObj
->GetProperties();
35 std::unique_ptr
<sdr::contact::ViewContact
> SdrVirtObj::CreateObjectSpecificViewContact()
37 return std::make_unique
<sdr::contact::ViewContactOfVirtObj
>(*this);
40 SdrVirtObj::SdrVirtObj(
43 : SdrObject(rSdrModel
),
46 m_bVirtObj
=true; // this is only a virtual object
47 mxRefObj
->AddReference(*this);
48 m_bClosedObj
= mxRefObj
->IsClosedObj();
51 SdrVirtObj::SdrVirtObj(
52 SdrModel
& rSdrModel
, SdrVirtObj
const & rSource
)
53 : SdrObject(rSdrModel
, rSource
),
54 mxRefObj(rSource
.mxRefObj
)
56 m_bVirtObj
=true; // this is only a virtual object
57 m_bClosedObj
= mxRefObj
->IsClosedObj();
59 mxRefObj
->AddReference(*this);
61 aSnapRect
= rSource
.aSnapRect
;
62 m_aAnchor
= rSource
.m_aAnchor
;
65 SdrVirtObj::~SdrVirtObj()
67 mxRefObj
->DelReference(*this);
70 const SdrObject
& SdrVirtObj::GetReferencedObj() const
75 SdrObject
& SdrVirtObj::ReferencedObj()
80 void SdrVirtObj::Notify(SfxBroadcaster
& /*rBC*/, const SfxHint
& /*rHint*/)
82 m_bClosedObj
= mxRefObj
->IsClosedObj();
83 SetBoundAndSnapRectsDirty(); // TODO: Optimize this.
85 // Only a repaint here, rRefObj may have changed and broadcasts
89 void SdrVirtObj::NbcSetAnchorPos(const Point
& rAnchorPos
)
94 void SdrVirtObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
96 mxRefObj
->TakeObjInfo(rInfo
);
99 SdrInventor
SdrVirtObj::GetObjInventor() const
101 return mxRefObj
->GetObjInventor();
104 SdrObjKind
SdrVirtObj::GetObjIdentifier() const
106 return mxRefObj
->GetObjIdentifier();
109 SdrObjList
* SdrVirtObj::GetSubList() const
111 return mxRefObj
->GetSubList();
114 void SdrVirtObj::SetName(const OUString
& rStr
, const bool bSetChanged
)
116 return mxRefObj
->SetName(rStr
, bSetChanged
);
119 const OUString
& SdrVirtObj::GetName() const
121 return mxRefObj
->GetName();
124 void SdrVirtObj::SetTitle(const OUString
& rStr
)
126 return mxRefObj
->SetTitle(rStr
);
129 OUString
SdrVirtObj::GetTitle() const
131 return mxRefObj
->GetTitle();
134 void SdrVirtObj::SetDescription(const OUString
& rStr
)
136 return mxRefObj
->SetDescription(rStr
);
139 OUString
SdrVirtObj::GetDescription() const
141 return mxRefObj
->GetDescription();
144 void SdrVirtObj::SetDecorative(bool const isDecorative
)
146 return mxRefObj
->SetDecorative(isDecorative
);
149 bool SdrVirtObj::IsDecorative() const
151 return mxRefObj
->IsDecorative();
154 const tools::Rectangle
& SdrVirtObj::GetCurrentBoundRect() const
156 auto aRectangle
= mxRefObj
->GetCurrentBoundRect(); // TODO: Optimize this.
157 aRectangle
+= m_aAnchor
;
158 setOutRectangleConst(aRectangle
);
159 return getOutRectangle();
162 const tools::Rectangle
& SdrVirtObj::GetLastBoundRect() const
164 auto aRectangle
= mxRefObj
->GetLastBoundRect(); // TODO: Optimize this.
165 aRectangle
+= m_aAnchor
;
166 setOutRectangleConst(aRectangle
);
167 return getOutRectangle();
170 void SdrVirtObj::RecalcBoundRect()
172 tools::Rectangle aRectangle
= mxRefObj
->GetCurrentBoundRect();
173 aRectangle
+= m_aAnchor
;
174 setOutRectangle(aRectangle
);
177 rtl::Reference
<SdrObject
> SdrVirtObj::CloneSdrObject(SdrModel
& rTargetModel
) const
179 return new SdrVirtObj(rTargetModel
, *this);
180 // TTTT not sure if the above works - how could SdrObjFactory::MakeNewObject
181 // create an object with correct rRefObj (?) OTOH VirtObj probably needs not
182 // to be cloned ever - only used in Writer for multiple instances e.g. Header/Footer
183 // return new SdrVirtObj(
184 // getSdrModelFromSdrObject(),
185 // rRefObj); // only a further reference
188 OUString
SdrVirtObj::TakeObjNameSingul() const
190 OUString sName
= "[" + mxRefObj
->TakeObjNameSingul() + "]";
192 OUString
aName(GetName());
193 if (!aName
.isEmpty())
194 sName
+= " '" + aName
+ "'";
199 OUString
SdrVirtObj::TakeObjNamePlural() const
201 return "[" + mxRefObj
->TakeObjNamePlural() + "]";
204 bool SdrVirtObj::HasLimitedRotation() const
206 // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation
207 return mxRefObj
->HasLimitedRotation();
210 basegfx::B2DPolyPolygon
SdrVirtObj::TakeXorPoly() const
212 basegfx::B2DPolyPolygon
aPolyPolygon(mxRefObj
->TakeXorPoly());
214 if(m_aAnchor
.X() || m_aAnchor
.Y())
216 aPolyPolygon
.transform(basegfx::utils::createTranslateB2DHomMatrix(m_aAnchor
.X(), m_aAnchor
.Y()));
223 sal_uInt32
SdrVirtObj::GetHdlCount() const
225 return mxRefObj
->GetHdlCount();
228 void SdrVirtObj::AddToHdlList(SdrHdlList
& rHdlList
) const
230 SdrHdlList
tempList(nullptr);
231 mxRefObj
->AddToHdlList(tempList
);
232 for (size_t i
=0; i
<tempList
.GetHdlCount(); ++i
)
234 SdrHdl
* pHdl
= tempList
.GetHdl(i
);
235 Point
aP(pHdl
->GetPos()+m_aAnchor
);
238 tempList
.MoveTo(rHdlList
);
241 void SdrVirtObj::AddToPlusHdlList(SdrHdlList
& rHdlList
, SdrHdl
& rHdl
) const
243 SdrHdlList
tempList(nullptr);
244 mxRefObj
->AddToPlusHdlList(tempList
, rHdl
);
245 for (size_t i
=0; i
<tempList
.GetHdlCount(); ++i
)
247 SdrHdl
* pHdl
= tempList
.GetHdl(i
);
248 Point
aP(pHdl
->GetPos()+m_aAnchor
);
251 tempList
.MoveTo(rHdlList
);
254 bool SdrVirtObj::hasSpecialDrag() const
256 return mxRefObj
->hasSpecialDrag();
259 bool SdrVirtObj::supportsFullDrag() const
264 rtl::Reference
<SdrObject
> SdrVirtObj::getFullDragClone() const
266 SdrObject
& rReferencedObject
= const_cast<SdrVirtObj
*>(this)->ReferencedObj();
267 return rtl::Reference
<SdrObject
>(new SdrGrafObj(
268 getSdrModelFromSdrObject(),
269 SdrDragView::GetObjGraphic(rReferencedObject
),
273 bool SdrVirtObj::beginSpecialDrag(SdrDragStat
& rDrag
) const
275 return mxRefObj
->beginSpecialDrag(rDrag
);
278 bool SdrVirtObj::applySpecialDrag(SdrDragStat
& rDrag
)
280 return mxRefObj
->applySpecialDrag(rDrag
);
283 basegfx::B2DPolyPolygon
SdrVirtObj::getSpecialDragPoly(const SdrDragStat
& rDrag
) const
285 return mxRefObj
->getSpecialDragPoly(rDrag
);
286 // TODO: we don't handle offsets yet!
289 OUString
SdrVirtObj::getSpecialDragComment(const SdrDragStat
& rDrag
) const
291 return mxRefObj
->getSpecialDragComment(rDrag
);
295 bool SdrVirtObj::BegCreate(SdrDragStat
& rStat
)
297 return mxRefObj
->BegCreate(rStat
);
300 bool SdrVirtObj::MovCreate(SdrDragStat
& rStat
)
302 return mxRefObj
->MovCreate(rStat
);
305 bool SdrVirtObj::EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
307 return mxRefObj
->EndCreate(rStat
,eCmd
);
310 bool SdrVirtObj::BckCreate(SdrDragStat
& rStat
)
312 return mxRefObj
->BckCreate(rStat
);
315 void SdrVirtObj::BrkCreate(SdrDragStat
& rStat
)
317 mxRefObj
->BrkCreate(rStat
);
320 basegfx::B2DPolyPolygon
SdrVirtObj::TakeCreatePoly(const SdrDragStat
& rDrag
) const
322 return mxRefObj
->TakeCreatePoly(rDrag
);
323 // TODO: we don't handle offsets yet!
327 void SdrVirtObj::NbcMove(const Size
& rSiz
)
329 m_aAnchor
.Move(rSiz
);
330 SetBoundAndSnapRectsDirty();
333 void SdrVirtObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
335 mxRefObj
->NbcResize(rRef
-m_aAnchor
,xFact
,yFact
);
336 SetBoundAndSnapRectsDirty();
339 void SdrVirtObj::NbcRotate(const Point
& rRef
, Degree100 nAngle
, double sn
, double cs
)
341 mxRefObj
->NbcRotate(rRef
-m_aAnchor
,nAngle
,sn
,cs
);
342 SetBoundAndSnapRectsDirty();
345 void SdrVirtObj::NbcMirror(const Point
& rRef1
, const Point
& rRef2
)
347 mxRefObj
->NbcMirror(rRef1
-m_aAnchor
,rRef2
-m_aAnchor
);
348 SetBoundAndSnapRectsDirty();
351 void SdrVirtObj::NbcShear(const Point
& rRef
, Degree100 nAngle
, double tn
, bool bVShear
)
353 mxRefObj
->NbcShear(rRef
-m_aAnchor
,nAngle
,tn
,bVShear
);
354 SetBoundAndSnapRectsDirty();
358 void SdrVirtObj::Move(const Size
& rSiz
)
360 if (!rSiz
.IsEmpty()) {
361 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
364 BroadcastObjectChange();
365 SendUserCall(SdrUserCallType::MoveOnly
,aBoundRect0
);
369 void SdrVirtObj::Resize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bUnsetRelative
)
371 if (xFact
.GetNumerator()!=xFact
.GetDenominator() || yFact
.GetNumerator()!=yFact
.GetDenominator()) {
372 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
373 mxRefObj
->Resize(rRef
-m_aAnchor
,xFact
,yFact
, bUnsetRelative
);
374 SetBoundAndSnapRectsDirty();
375 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
379 void SdrVirtObj::Rotate(const Point
& rRef
, Degree100 nAngle
, double sn
, double cs
)
382 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
383 mxRefObj
->Rotate(rRef
-m_aAnchor
,nAngle
,sn
,cs
);
384 SetBoundAndSnapRectsDirty();
385 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
389 void SdrVirtObj::Mirror(const Point
& rRef1
, const Point
& rRef2
)
391 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
392 mxRefObj
->Mirror(rRef1
-m_aAnchor
,rRef2
-m_aAnchor
);
393 SetBoundAndSnapRectsDirty();
394 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
397 void SdrVirtObj::Shear(const Point
& rRef
, Degree100 nAngle
, double tn
, bool bVShear
)
400 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
401 mxRefObj
->Shear(rRef
-m_aAnchor
,nAngle
,tn
,bVShear
);
402 SetBoundAndSnapRectsDirty();
403 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
408 void SdrVirtObj::RecalcSnapRect()
410 aSnapRect
=mxRefObj
->GetSnapRect();
411 aSnapRect
+=m_aAnchor
;
414 const tools::Rectangle
& SdrVirtObj::GetSnapRect() const
416 const_cast<SdrVirtObj
*>(this)->aSnapRect
=mxRefObj
->GetSnapRect();
417 const_cast<SdrVirtObj
*>(this)->aSnapRect
+=m_aAnchor
;
421 void SdrVirtObj::SetSnapRect(const tools::Rectangle
& rRect
)
423 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
424 tools::Rectangle
aR(rRect
);
426 mxRefObj
->SetSnapRect(aR
);
427 SetBoundAndSnapRectsDirty();
428 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
431 void SdrVirtObj::NbcSetSnapRect(const tools::Rectangle
& rRect
)
433 tools::Rectangle
aR(rRect
);
435 SetBoundAndSnapRectsDirty();
436 mxRefObj
->NbcSetSnapRect(aR
);
440 const tools::Rectangle
& SdrVirtObj::GetLogicRect() const
442 const_cast<SdrVirtObj
*>(this)->aSnapRect
=mxRefObj
->GetLogicRect(); // An abuse of aSnapRect!
443 const_cast<SdrVirtObj
*>(this)->aSnapRect
+=m_aAnchor
; // If there's trouble, we need another Rectangle Member (or a Heap).
447 void SdrVirtObj::SetLogicRect(const tools::Rectangle
& rRect
)
449 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
450 tools::Rectangle
aR(rRect
);
452 mxRefObj
->SetLogicRect(aR
);
453 SetBoundAndSnapRectsDirty();
454 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
457 void SdrVirtObj::NbcSetLogicRect(const tools::Rectangle
& rRect
)
459 tools::Rectangle
aR(rRect
);
461 SetBoundAndSnapRectsDirty();
462 mxRefObj
->NbcSetLogicRect(aR
);
466 Degree100
SdrVirtObj::GetRotateAngle() const
468 return mxRefObj
->GetRotateAngle();
471 Degree100
SdrVirtObj::GetShearAngle(bool bVertical
) const
473 return mxRefObj
->GetShearAngle(bVertical
);
477 sal_uInt32
SdrVirtObj::GetSnapPointCount() const
479 return mxRefObj
->GetSnapPointCount();
482 Point
SdrVirtObj::GetSnapPoint(sal_uInt32 i
) const
484 Point
aP(mxRefObj
->GetSnapPoint(i
));
489 bool SdrVirtObj::IsPolyObj() const
491 return mxRefObj
->IsPolyObj();
494 sal_uInt32
SdrVirtObj::GetPointCount() const
496 return mxRefObj
->GetPointCount();
499 Point
SdrVirtObj::GetPoint(sal_uInt32 i
) const
501 return mxRefObj
->GetPoint(i
) + m_aAnchor
;
504 void SdrVirtObj::NbcSetPoint(const Point
& rPnt
, sal_uInt32 i
)
508 mxRefObj
->SetPoint(aP
,i
);
509 SetBoundAndSnapRectsDirty();
513 std::unique_ptr
<SdrObjGeoData
> SdrVirtObj::NewGeoData() const
515 return mxRefObj
->NewGeoData();
518 void SdrVirtObj::SaveGeoData(SdrObjGeoData
& rGeo
) const
520 mxRefObj
->SaveGeoData(rGeo
);
523 void SdrVirtObj::RestoreGeoData(const SdrObjGeoData
& rGeo
)
525 mxRefObj
->RestoreGeoData(rGeo
);
526 SetBoundAndSnapRectsDirty();
530 std::unique_ptr
<SdrObjGeoData
> SdrVirtObj::GetGeoData() const
532 return mxRefObj
->GetGeoData();
535 void SdrVirtObj::SetGeoData(const SdrObjGeoData
& rGeo
)
537 tools::Rectangle aBoundRect0
; if (m_pUserCall
!=nullptr) aBoundRect0
=GetLastBoundRect();
538 mxRefObj
->SetGeoData(rGeo
);
539 SetBoundAndSnapRectsDirty();
540 SendUserCall(SdrUserCallType::Resize
,aBoundRect0
);
544 void SdrVirtObj::NbcReformatText()
546 mxRefObj
->NbcReformatText();
549 bool SdrVirtObj::HasMacro() const
551 return mxRefObj
->HasMacro();
554 SdrObject
* SdrVirtObj::CheckMacroHit(const SdrObjMacroHitRec
& rRec
) const
556 return mxRefObj
->CheckMacroHit(rRec
); // TODO: positioning offset
559 PointerStyle
SdrVirtObj::GetMacroPointer(const SdrObjMacroHitRec
& rRec
) const
561 return mxRefObj
->GetMacroPointer(rRec
); // TODO: positioning offset
564 void SdrVirtObj::PaintMacro(OutputDevice
& rOut
, const tools::Rectangle
& rDirtyRect
, const SdrObjMacroHitRec
& rRec
) const
566 mxRefObj
->PaintMacro(rOut
,rDirtyRect
,rRec
); // TODO: positioning offset
569 bool SdrVirtObj::DoMacro(const SdrObjMacroHitRec
& rRec
)
571 return mxRefObj
->DoMacro(rRec
); // TODO: positioning offset
574 Point
SdrVirtObj::GetOffset() const
576 // #i73248# default offset of SdrVirtObj is aAnchor
580 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */