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
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>
27 #include <rtl/ustrbuf.hxx>
28
GetProperties() const29 sdr::properties::BaseProperties& SdrVirtObj::GetProperties() const
30 {
31 return rRefObj.GetProperties();
32 }
33
34
35 // #i27224#
CreateObjectSpecificViewContact()36 std::unique_ptr<sdr::contact::ViewContact> SdrVirtObj::CreateObjectSpecificViewContact()
37 {
38 return std::make_unique<sdr::contact::ViewContactOfVirtObj>(*this);
39 }
40
SdrVirtObj(SdrModel & rSdrModel,SdrObject & rNewObj)41 SdrVirtObj::SdrVirtObj(
42 SdrModel& rSdrModel,
43 SdrObject& rNewObj)
44 : SdrObject(rSdrModel),
45 rRefObj(rNewObj)
46 {
47 m_bVirtObj=true; // this is only a virtual object
48 rRefObj.AddReference(*this);
49 m_bClosedObj=rRefObj.IsClosedObj();
50 }
51
SdrVirtObj(SdrModel & rSdrModel,SdrVirtObj const & rSource)52 SdrVirtObj::SdrVirtObj(
53 SdrModel& rSdrModel, SdrVirtObj const & rSource)
54 : SdrObject(rSdrModel, rSource),
55 rRefObj(rSource.rRefObj)
56 {
57 m_bVirtObj=true; // this is only a virtual object
58 m_bClosedObj=rRefObj.IsClosedObj();
59
60 rRefObj.AddReference(*this);
61
62 aSnapRect = rSource.aSnapRect;
63 m_aAnchor = rSource.m_aAnchor;
64 }
65
~SdrVirtObj()66 SdrVirtObj::~SdrVirtObj()
67 {
68 rRefObj.DelReference(*this);
69 }
70
GetReferencedObj() const71 const SdrObject& SdrVirtObj::GetReferencedObj() const
72 {
73 return rRefObj;
74 }
75
ReferencedObj()76 SdrObject& SdrVirtObj::ReferencedObj()
77 {
78 return rRefObj;
79 }
80
Notify(SfxBroadcaster &,const SfxHint &)81 void SdrVirtObj::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& /*rHint*/)
82 {
83 m_bClosedObj=rRefObj.IsClosedObj();
84 SetRectsDirty(); // TODO: Optimize this.
85
86 // Only a repaint here, rRefObj may have changed and broadcasts
87 ActionChanged();
88 }
89
NbcSetAnchorPos(const Point & rAnchorPos)90 void SdrVirtObj::NbcSetAnchorPos(const Point& rAnchorPos)
91 {
92 m_aAnchor=rAnchorPos;
93 }
94
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const95 void SdrVirtObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
96 {
97 rRefObj.TakeObjInfo(rInfo);
98 }
99
GetObjInventor() const100 SdrInventor SdrVirtObj::GetObjInventor() const
101 {
102 return rRefObj.GetObjInventor();
103 }
104
GetObjIdentifier() const105 SdrObjKind SdrVirtObj::GetObjIdentifier() const
106 {
107 return rRefObj.GetObjIdentifier();
108 }
109
GetSubList() const110 SdrObjList* SdrVirtObj::GetSubList() const
111 {
112 return rRefObj.GetSubList();
113 }
114
GetCurrentBoundRect() const115 const tools::Rectangle& SdrVirtObj::GetCurrentBoundRect() const
116 {
117 m_aOutRect = rRefObj.GetCurrentBoundRect(); // TODO: Optimize this.
118 m_aOutRect += m_aAnchor;
119 return m_aOutRect;
120 }
121
GetLastBoundRect() const122 const tools::Rectangle& SdrVirtObj::GetLastBoundRect() const
123 {
124 m_aOutRect = rRefObj.GetLastBoundRect(); // TODO: Optimize this.
125 m_aOutRect += m_aAnchor;
126 return m_aOutRect;
127 }
128
RecalcBoundRect()129 void SdrVirtObj::RecalcBoundRect()
130 {
131 m_aOutRect=rRefObj.GetCurrentBoundRect();
132 m_aOutRect+=m_aAnchor;
133 }
134
CloneSdrObject(SdrModel & rTargetModel) const135 SdrVirtObj* SdrVirtObj::CloneSdrObject(SdrModel& rTargetModel) const
136 {
137 return new SdrVirtObj(rTargetModel, *this);
138 // TTTT not sure if the above works - how could SdrObjFactory::MakeNewObject
139 // create an object with correct rRefObj (?) OTOH VirtObj probably needs not
140 // to be cloned ever - only used in Writer for multiple instances e.g. Header/Footer
141 // return new SdrVirtObj(
142 // getSdrModelFromSdrObject(),
143 // rRefObj); // only a further reference
144 }
145
TakeObjNameSingul() const146 OUString SdrVirtObj::TakeObjNameSingul() const
147 {
148 OUString sName = "[" + rRefObj.TakeObjNameSingul() + "]";
149
150 OUString aName(GetName());
151 if (!aName.isEmpty())
152 sName += " '" + aName + "'";
153
154 return sName;
155 }
156
TakeObjNamePlural() const157 OUString SdrVirtObj::TakeObjNamePlural() const
158 {
159 return "[" + rRefObj.TakeObjNamePlural() + "]";
160 }
161
HasLimitedRotation() const162 bool SdrVirtObj::HasLimitedRotation() const
163 {
164 // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation
165 return rRefObj.HasLimitedRotation();
166 }
167
TakeXorPoly() const168 basegfx::B2DPolyPolygon SdrVirtObj::TakeXorPoly() const
169 {
170 basegfx::B2DPolyPolygon aPolyPolygon(rRefObj.TakeXorPoly());
171
172 if(m_aAnchor.X() || m_aAnchor.Y())
173 {
174 aPolyPolygon.transform(basegfx::utils::createTranslateB2DHomMatrix(m_aAnchor.X(), m_aAnchor.Y()));
175 }
176
177 return aPolyPolygon;
178 }
179
180
GetHdlCount() const181 sal_uInt32 SdrVirtObj::GetHdlCount() const
182 {
183 return rRefObj.GetHdlCount();
184 }
185
AddToHdlList(SdrHdlList & rHdlList) const186 void SdrVirtObj::AddToHdlList(SdrHdlList& rHdlList) const
187 {
188 SdrHdlList tempList(nullptr);
189 rRefObj.AddToHdlList(tempList);
190 for (size_t i=0; i<tempList.GetHdlCount(); ++i)
191 {
192 SdrHdl* pHdl = tempList.GetHdl(i);
193 Point aP(pHdl->GetPos()+m_aAnchor);
194 pHdl->SetPos(aP);
195 }
196 tempList.MoveTo(rHdlList);
197 }
198
AddToPlusHdlList(SdrHdlList & rHdlList,SdrHdl & rHdl) const199 void SdrVirtObj::AddToPlusHdlList(SdrHdlList& rHdlList, SdrHdl& rHdl) const
200 {
201 SdrHdlList tempList(nullptr);
202 rRefObj.AddToPlusHdlList(tempList, rHdl);
203 for (size_t i=0; i<tempList.GetHdlCount(); ++i)
204 {
205 SdrHdl* pHdl = tempList.GetHdl(i);
206 Point aP(pHdl->GetPos()+m_aAnchor);
207 pHdl->SetPos(aP);
208 }
209 tempList.MoveTo(rHdlList);
210 }
211
hasSpecialDrag() const212 bool SdrVirtObj::hasSpecialDrag() const
213 {
214 return rRefObj.hasSpecialDrag();
215 }
216
supportsFullDrag() const217 bool SdrVirtObj::supportsFullDrag() const
218 {
219 return false;
220 }
221
getFullDragClone() const222 SdrObjectUniquePtr SdrVirtObj::getFullDragClone() const
223 {
224 SdrObject& rReferencedObject = const_cast<SdrVirtObj*>(this)->ReferencedObj();
225 return SdrObjectUniquePtr(new SdrGrafObj(
226 getSdrModelFromSdrObject(),
227 SdrDragView::GetObjGraphic(rReferencedObject),
228 GetLogicRect()));
229 }
230
beginSpecialDrag(SdrDragStat & rDrag) const231 bool SdrVirtObj::beginSpecialDrag(SdrDragStat& rDrag) const
232 {
233 return rRefObj.beginSpecialDrag(rDrag);
234 }
235
applySpecialDrag(SdrDragStat & rDrag)236 bool SdrVirtObj::applySpecialDrag(SdrDragStat& rDrag)
237 {
238 return rRefObj.applySpecialDrag(rDrag);
239 }
240
getSpecialDragPoly(const SdrDragStat & rDrag) const241 basegfx::B2DPolyPolygon SdrVirtObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
242 {
243 return rRefObj.getSpecialDragPoly(rDrag);
244 // TODO: we don't handle offsets yet!
245 }
246
getSpecialDragComment(const SdrDragStat & rDrag) const247 OUString SdrVirtObj::getSpecialDragComment(const SdrDragStat& rDrag) const
248 {
249 return rRefObj.getSpecialDragComment(rDrag);
250 }
251
252
BegCreate(SdrDragStat & rStat)253 bool SdrVirtObj::BegCreate(SdrDragStat& rStat)
254 {
255 return rRefObj.BegCreate(rStat);
256 }
257
MovCreate(SdrDragStat & rStat)258 bool SdrVirtObj::MovCreate(SdrDragStat& rStat)
259 {
260 return rRefObj.MovCreate(rStat);
261 }
262
EndCreate(SdrDragStat & rStat,SdrCreateCmd eCmd)263 bool SdrVirtObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
264 {
265 return rRefObj.EndCreate(rStat,eCmd);
266 }
267
BckCreate(SdrDragStat & rStat)268 bool SdrVirtObj::BckCreate(SdrDragStat& rStat)
269 {
270 return rRefObj.BckCreate(rStat);
271 }
272
BrkCreate(SdrDragStat & rStat)273 void SdrVirtObj::BrkCreate(SdrDragStat& rStat)
274 {
275 rRefObj.BrkCreate(rStat);
276 }
277
TakeCreatePoly(const SdrDragStat & rDrag) const278 basegfx::B2DPolyPolygon SdrVirtObj::TakeCreatePoly(const SdrDragStat& rDrag) const
279 {
280 return rRefObj.TakeCreatePoly(rDrag);
281 // TODO: we don't handle offsets yet!
282 }
283
284
NbcMove(const Size & rSiz)285 void SdrVirtObj::NbcMove(const Size& rSiz)
286 {
287 m_aAnchor.Move(rSiz);
288 SetRectsDirty();
289 }
290
NbcResize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)291 void SdrVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
292 {
293 rRefObj.NbcResize(rRef-m_aAnchor,xFact,yFact);
294 SetRectsDirty();
295 }
296
NbcRotate(const Point & rRef,Degree100 nAngle,double sn,double cs)297 void SdrVirtObj::NbcRotate(const Point& rRef, Degree100 nAngle, double sn, double cs)
298 {
299 rRefObj.NbcRotate(rRef-m_aAnchor,nAngle,sn,cs);
300 SetRectsDirty();
301 }
302
NbcMirror(const Point & rRef1,const Point & rRef2)303 void SdrVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
304 {
305 rRefObj.NbcMirror(rRef1-m_aAnchor,rRef2-m_aAnchor);
306 SetRectsDirty();
307 }
308
NbcShear(const Point & rRef,Degree100 nAngle,double tn,bool bVShear)309 void SdrVirtObj::NbcShear(const Point& rRef, Degree100 nAngle, double tn, bool bVShear)
310 {
311 rRefObj.NbcShear(rRef-m_aAnchor,nAngle,tn,bVShear);
312 SetRectsDirty();
313 }
314
315
Move(const Size & rSiz)316 void SdrVirtObj::Move(const Size& rSiz)
317 {
318 if (!rSiz.IsEmpty()) {
319 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
320 NbcMove(rSiz);
321 SetChanged();
322 BroadcastObjectChange();
323 SendUserCall(SdrUserCallType::MoveOnly,aBoundRect0);
324 }
325 }
326
Resize(const Point & rRef,const Fraction & xFact,const Fraction & yFact,bool bUnsetRelative)327 void SdrVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
328 {
329 if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
330 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
331 rRefObj.Resize(rRef-m_aAnchor,xFact,yFact, bUnsetRelative);
332 SetRectsDirty();
333 SendUserCall(SdrUserCallType::Resize,aBoundRect0);
334 }
335 }
336
Rotate(const Point & rRef,Degree100 nAngle,double sn,double cs)337 void SdrVirtObj::Rotate(const Point& rRef, Degree100 nAngle, double sn, double cs)
338 {
339 if (nAngle) {
340 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
341 rRefObj.Rotate(rRef-m_aAnchor,nAngle,sn,cs);
342 SetRectsDirty();
343 SendUserCall(SdrUserCallType::Resize,aBoundRect0);
344 }
345 }
346
Mirror(const Point & rRef1,const Point & rRef2)347 void SdrVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
348 {
349 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
350 rRefObj.Mirror(rRef1-m_aAnchor,rRef2-m_aAnchor);
351 SetRectsDirty();
352 SendUserCall(SdrUserCallType::Resize,aBoundRect0);
353 }
354
Shear(const Point & rRef,Degree100 nAngle,double tn,bool bVShear)355 void SdrVirtObj::Shear(const Point& rRef, Degree100 nAngle, double tn, bool bVShear)
356 {
357 if (nAngle) {
358 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
359 rRefObj.Shear(rRef-m_aAnchor,nAngle,tn,bVShear);
360 SetRectsDirty();
361 SendUserCall(SdrUserCallType::Resize,aBoundRect0);
362 }
363 }
364
365
RecalcSnapRect()366 void SdrVirtObj::RecalcSnapRect()
367 {
368 aSnapRect=rRefObj.GetSnapRect();
369 aSnapRect+=m_aAnchor;
370 }
371
GetSnapRect() const372 const tools::Rectangle& SdrVirtObj::GetSnapRect() const
373 {
374 const_cast<SdrVirtObj*>(this)->aSnapRect=rRefObj.GetSnapRect();
375 const_cast<SdrVirtObj*>(this)->aSnapRect+=m_aAnchor;
376 return aSnapRect;
377 }
378
SetSnapRect(const tools::Rectangle & rRect)379 void SdrVirtObj::SetSnapRect(const tools::Rectangle& rRect)
380 {
381 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
382 tools::Rectangle aR(rRect);
383 aR-=m_aAnchor;
384 rRefObj.SetSnapRect(aR);
385 SetRectsDirty();
386 SendUserCall(SdrUserCallType::Resize,aBoundRect0);
387 }
388
NbcSetSnapRect(const tools::Rectangle & rRect)389 void SdrVirtObj::NbcSetSnapRect(const tools::Rectangle& rRect)
390 {
391 tools::Rectangle aR(rRect);
392 aR-=m_aAnchor;
393 SetRectsDirty();
394 rRefObj.NbcSetSnapRect(aR);
395 }
396
397
GetLogicRect() const398 const tools::Rectangle& SdrVirtObj::GetLogicRect() const
399 {
400 const_cast<SdrVirtObj*>(this)->aSnapRect=rRefObj.GetLogicRect(); // An abuse of aSnapRect!
401 const_cast<SdrVirtObj*>(this)->aSnapRect+=m_aAnchor; // If there's trouble, we need another Rectangle Member (or a Heap).
402 return aSnapRect;
403 }
404
SetLogicRect(const tools::Rectangle & rRect)405 void SdrVirtObj::SetLogicRect(const tools::Rectangle& rRect)
406 {
407 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
408 tools::Rectangle aR(rRect);
409 aR-=m_aAnchor;
410 rRefObj.SetLogicRect(aR);
411 SetRectsDirty();
412 SendUserCall(SdrUserCallType::Resize,aBoundRect0);
413 }
414
NbcSetLogicRect(const tools::Rectangle & rRect)415 void SdrVirtObj::NbcSetLogicRect(const tools::Rectangle& rRect)
416 {
417 tools::Rectangle aR(rRect);
418 aR-=m_aAnchor;
419 SetRectsDirty();
420 rRefObj.NbcSetLogicRect(aR);
421 }
422
423
GetRotateAngle() const424 Degree100 SdrVirtObj::GetRotateAngle() const
425 {
426 return rRefObj.GetRotateAngle();
427 }
428
GetShearAngle(bool bVertical) const429 Degree100 SdrVirtObj::GetShearAngle(bool bVertical) const
430 {
431 return rRefObj.GetShearAngle(bVertical);
432 }
433
434
GetSnapPointCount() const435 sal_uInt32 SdrVirtObj::GetSnapPointCount() const
436 {
437 return rRefObj.GetSnapPointCount();
438 }
439
GetSnapPoint(sal_uInt32 i) const440 Point SdrVirtObj::GetSnapPoint(sal_uInt32 i) const
441 {
442 Point aP(rRefObj.GetSnapPoint(i));
443 aP+=m_aAnchor;
444 return aP;
445 }
446
IsPolyObj() const447 bool SdrVirtObj::IsPolyObj() const
448 {
449 return rRefObj.IsPolyObj();
450 }
451
GetPointCount() const452 sal_uInt32 SdrVirtObj::GetPointCount() const
453 {
454 return rRefObj.GetPointCount();
455 }
456
GetPoint(sal_uInt32 i) const457 Point SdrVirtObj::GetPoint(sal_uInt32 i) const
458 {
459 return rRefObj.GetPoint(i) + m_aAnchor;
460 }
461
NbcSetPoint(const Point & rPnt,sal_uInt32 i)462 void SdrVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
463 {
464 Point aP(rPnt);
465 aP-=m_aAnchor;
466 rRefObj.SetPoint(aP,i);
467 SetRectsDirty();
468 }
469
470
NewGeoData() const471 std::unique_ptr<SdrObjGeoData> SdrVirtObj::NewGeoData() const
472 {
473 return rRefObj.NewGeoData();
474 }
475
SaveGeoData(SdrObjGeoData & rGeo) const476 void SdrVirtObj::SaveGeoData(SdrObjGeoData& rGeo) const
477 {
478 rRefObj.SaveGeoData(rGeo);
479 }
480
RestoreGeoData(const SdrObjGeoData & rGeo)481 void SdrVirtObj::RestoreGeoData(const SdrObjGeoData& rGeo)
482 {
483 rRefObj.RestoreGeoData(rGeo);
484 SetRectsDirty();
485 }
486
487
GetGeoData() const488 std::unique_ptr<SdrObjGeoData> SdrVirtObj::GetGeoData() const
489 {
490 return rRefObj.GetGeoData();
491 }
492
SetGeoData(const SdrObjGeoData & rGeo)493 void SdrVirtObj::SetGeoData(const SdrObjGeoData& rGeo)
494 {
495 tools::Rectangle aBoundRect0; if (m_pUserCall!=nullptr) aBoundRect0=GetLastBoundRect();
496 rRefObj.SetGeoData(rGeo);
497 SetRectsDirty();
498 SendUserCall(SdrUserCallType::Resize,aBoundRect0);
499 }
500
501
NbcReformatText()502 void SdrVirtObj::NbcReformatText()
503 {
504 rRefObj.NbcReformatText();
505 }
506
HasMacro() const507 bool SdrVirtObj::HasMacro() const
508 {
509 return rRefObj.HasMacro();
510 }
511
CheckMacroHit(const SdrObjMacroHitRec & rRec) const512 SdrObject* SdrVirtObj::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
513 {
514 return rRefObj.CheckMacroHit(rRec); // TODO: positioning offset
515 }
516
GetMacroPointer(const SdrObjMacroHitRec & rRec) const517 PointerStyle SdrVirtObj::GetMacroPointer(const SdrObjMacroHitRec& rRec) const
518 {
519 return rRefObj.GetMacroPointer(rRec); // TODO: positioning offset
520 }
521
PaintMacro(OutputDevice & rOut,const tools::Rectangle & rDirtyRect,const SdrObjMacroHitRec & rRec) const522 void SdrVirtObj::PaintMacro(OutputDevice& rOut, const tools::Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const
523 {
524 rRefObj.PaintMacro(rOut,rDirtyRect,rRec); // TODO: positioning offset
525 }
526
DoMacro(const SdrObjMacroHitRec & rRec)527 bool SdrVirtObj::DoMacro(const SdrObjMacroHitRec& rRec)
528 {
529 return rRefObj.DoMacro(rRec); // TODO: positioning offset
530 }
531
GetOffset() const532 Point SdrVirtObj::GetOffset() const
533 {
534 // #i73248# default offset of SdrVirtObj is aAnchor
535 return m_aAnchor;
536 }
537
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
539