xref: /trunk/main/svx/source/svdraw/svdovirt.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb) !
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/svdovirt.hxx>
32 #include <svx/xpool.hxx>
33 #include <svx/svdtrans.hxx>
34 #include <svx/svdetc.hxx>
35 #include <svx/svdhdl.hxx>
36 #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
37 #include <basegfx/matrix/b2dhommatrix.hxx>
38 #include <svx/svdograf.hxx>
39 #include <svx/svddrgv.hxx>
40 #include <basegfx/matrix/b2dhommatrixtools.hxx>
41 
42 ////////////////////////////////////////////////////////////////////////////////////////////////////
43 
44 sdr::properties::BaseProperties& SdrVirtObj::GetProperties() const
45 {
46     return rRefObj.GetProperties();
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////////////////////////
50 // AW, OD 2004-05-03 #i27224#
51 sdr::contact::ViewContact* SdrVirtObj::CreateObjectSpecificViewContact()
52 {
53     return new sdr::contact::ViewContactOfVirtObj(*this);
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////////////////////////
57 
58 TYPEINIT1(SdrVirtObj,SdrObject);
59 
60 SdrVirtObj::SdrVirtObj(SdrObject& rNewObj):
61     rRefObj(rNewObj)
62 {
63     bVirtObj=sal_True; // Ja, ich bin ein virtuelles Objekt
64     rRefObj.AddReference(*this);
65     bClosedObj=rRefObj.IsClosedObj();
66 }
67 
68 SdrVirtObj::SdrVirtObj(SdrObject& rNewObj, const Point& rAnchorPos):
69     rRefObj(rNewObj)
70 {
71     aAnchor=rAnchorPos;
72     bVirtObj=sal_True; // Ja, ich bin ein virtuelles Objekt
73     rRefObj.AddReference(*this);
74     bClosedObj=rRefObj.IsClosedObj();
75 }
76 
77 SdrVirtObj::~SdrVirtObj()
78 {
79     rRefObj.DelReference(*this);
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////////////////////////////
83 
84 const SdrObject& SdrVirtObj::GetReferencedObj() const
85 {
86     return rRefObj;
87 }
88 
89 SdrObject& SdrVirtObj::ReferencedObj()
90 {
91     return rRefObj;
92 }
93 
94 void __EXPORT SdrVirtObj::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& /*rHint*/)
95 {
96     bClosedObj=rRefObj.IsClosedObj();
97     SetRectsDirty(); // hier noch Optimieren.
98 
99     // Only a repaint here, rRefObj may have changed and broadcasts
100     ActionChanged();
101     // BroadcastObjectChange();
102 }
103 
104 void SdrVirtObj::NbcSetAnchorPos(const Point& rAnchorPos)
105 {
106     aAnchor=rAnchorPos;
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////////////////////////
110 
111 void SdrVirtObj::SetModel(SdrModel* pNewModel)
112 {
113     SdrObject::SetModel(pNewModel);
114     rRefObj.SetModel(pNewModel);
115 }
116 
117 void SdrVirtObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
118 {
119     rRefObj.TakeObjInfo(rInfo);
120 }
121 
122 sal_uInt32 SdrVirtObj::GetObjInventor() const
123 {
124     return rRefObj.GetObjInventor();
125 }
126 
127 sal_uInt16 SdrVirtObj::GetObjIdentifier() const
128 {
129     return rRefObj.GetObjIdentifier();
130 }
131 
132 SdrObjList* SdrVirtObj::GetSubList() const
133 {
134     return rRefObj.GetSubList();
135 }
136 
137 const Rectangle& SdrVirtObj::GetCurrentBoundRect() const
138 {
139     ((SdrVirtObj*)this)->aOutRect=rRefObj.GetCurrentBoundRect(); // Hier noch optimieren
140     ((SdrVirtObj*)this)->aOutRect+=aAnchor;
141     return aOutRect;
142 }
143 
144 const Rectangle& SdrVirtObj::GetLastBoundRect() const
145 {
146     ((SdrVirtObj*)this)->aOutRect=rRefObj.GetLastBoundRect(); // Hier noch optimieren
147     ((SdrVirtObj*)this)->aOutRect+=aAnchor;
148     return aOutRect;
149 }
150 
151 void SdrVirtObj::RecalcBoundRect()
152 {
153     aOutRect=rRefObj.GetCurrentBoundRect();
154     aOutRect+=aAnchor;
155 }
156 
157 void SdrVirtObj::SetChanged()
158 {
159     SdrObject::SetChanged();
160 }
161 
162 SdrObject* SdrVirtObj::Clone() const
163 {
164     SdrObject* pObj=new SdrVirtObj(((SdrVirtObj*)this)->rRefObj); // Nur eine weitere Referenz
165     return pObj;
166 }
167 
168 void SdrVirtObj::operator=(const SdrObject& rObj)
169 {   // ???anderes Objekt referenzieren???
170     SdrObject::operator=(rObj);
171     aAnchor=((SdrVirtObj&)rObj).aAnchor;
172 }
173 
174 void SdrVirtObj::TakeObjNameSingul(XubString& rName) const
175 {
176     rRefObj.TakeObjNameSingul(rName);
177     rName.Insert(sal_Unicode('['), 0);
178     rName += sal_Unicode(']');
179 
180     String aName( GetName() );
181     if(aName.Len())
182     {
183         rName += sal_Unicode(' ');
184         rName += sal_Unicode('\'');
185         rName += aName;
186         rName += sal_Unicode('\'');
187     }
188 }
189 
190 void SdrVirtObj::TakeObjNamePlural(XubString& rName) const
191 {
192     rRefObj.TakeObjNamePlural(rName);
193     rName.Insert(sal_Unicode('['), 0);
194     rName += sal_Unicode(']');
195 }
196 
197 void operator +=(PolyPolygon& rPoly, const Point& rOfs)
198 {
199     if (rOfs.X()!=0 || rOfs.Y()!=0) {
200         sal_uInt16 i,j;
201         for (j=0; j<rPoly.Count(); j++) {
202             Polygon aP1(rPoly.GetObject(j));
203             for (i=0; i<aP1.GetSize(); i++) {
204                  aP1[i]+=rOfs;
205             }
206             rPoly.Replace(aP1,j);
207         }
208     }
209 }
210 
211 basegfx::B2DPolyPolygon SdrVirtObj::TakeXorPoly() const
212 {
213     basegfx::B2DPolyPolygon aPolyPolygon(rRefObj.TakeXorPoly());
214 
215     if(aAnchor.X() || aAnchor.Y())
216     {
217         aPolyPolygon.transform(basegfx::tools::createTranslateB2DHomMatrix(aAnchor.X(), aAnchor.Y()));
218     }
219 
220     return aPolyPolygon;
221 }
222 
223 ////////////////////////////////////////////////////////////////////////////////////////////////////
224 
225 sal_uInt32 SdrVirtObj::GetHdlCount() const
226 {
227     return rRefObj.GetHdlCount();
228 }
229 
230 SdrHdl* SdrVirtObj::GetHdl(sal_uInt32 nHdlNum) const
231 {
232     SdrHdl* pHdl=rRefObj.GetHdl(nHdlNum);
233 
234     // #i73248#
235     // GetHdl() at SdrObject is not guaranteed to return an object
236     if(pHdl)
237     {
238         Point aP(pHdl->GetPos()+aAnchor);
239         pHdl->SetPos(aP);
240     }
241 
242     return pHdl;
243 }
244 
245 sal_uInt32 SdrVirtObj::GetPlusHdlCount(const SdrHdl& rHdl) const
246 {
247     return rRefObj.GetPlusHdlCount(rHdl);
248 }
249 
250 SdrHdl* SdrVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const
251 {
252     SdrHdl* pHdl=rRefObj.GetPlusHdl(rHdl,nPlNum);
253     pHdl->SetPos(pHdl->GetPos() + aAnchor);
254     return pHdl;
255 }
256 
257 void SdrVirtObj::AddToHdlList(SdrHdlList& rHdlList) const
258 {
259     // #i73248#
260     // SdrObject::AddToHdlList(rHdlList) is not a good thing to call
261     // since at SdrPathObj, only AddToHdlList may be used and the call
262     // will instead use the standard implementation which uses GetHdlCount()
263     // and GetHdl instead. This is not wrong, but may be much less effective
264     // and may not be prepared to GetHdl returning NULL
265 
266     // get handles using AddToHdlList from ref object
267     SdrHdlList aLocalList(0);
268     rRefObj.AddToHdlList(aLocalList);
269     const sal_uInt32 nHdlCount(aLocalList.GetHdlCount());
270 
271     if(nHdlCount)
272     {
273         // translate handles and add them to dest list. They are temporarily part of
274         // two lists then
275         const Point aOffset(GetOffset());
276 
277         for(sal_uInt32 a(0L); a < nHdlCount; a++)
278         {
279             SdrHdl* pCandidate = aLocalList.GetHdl(a);
280             pCandidate->SetPos(pCandidate->GetPos() + aOffset);
281             rHdlList.AddHdl(pCandidate);
282         }
283 
284         // remove them from source list, else they will be deleted when
285         // source list is deleted
286         while(aLocalList.GetHdlCount())
287         {
288             aLocalList.RemoveHdl(aLocalList.GetHdlCount() - 1L);
289         }
290     }
291 }
292 
293 ////////////////////////////////////////////////////////////////////////////////////////////////////
294 
295 bool SdrVirtObj::hasSpecialDrag() const
296 {
297     return rRefObj.hasSpecialDrag();
298 }
299 
300 bool SdrVirtObj::supportsFullDrag() const
301 {
302     return false;
303 }
304 
305 SdrObject* SdrVirtObj::getFullDragClone() const
306 {
307     static bool bSpecialHandling(false);
308     SdrObject* pRetval = 0;
309 
310     if(bSpecialHandling)
311     {
312         // special handling for VirtObj. Do not create another
313         // reference to rRefObj, this would allow to change that
314         // one on drag. Instead, create a SdrGrafObj for drag containing
315         // the graphical representation
316         pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), this), GetLogicRect());
317     }
318     else
319     {
320         SdrObject& rReferencedObject = ((SdrVirtObj*)this)->ReferencedObj();
321         pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), &rReferencedObject), GetLogicRect());
322     }
323 
324     return pRetval;
325 }
326 
327 bool SdrVirtObj::beginSpecialDrag(SdrDragStat& rDrag) const
328 {
329     return rRefObj.beginSpecialDrag(rDrag);
330 }
331 
332 bool SdrVirtObj::applySpecialDrag(SdrDragStat& rDrag)
333 {
334     return rRefObj.applySpecialDrag(rDrag);
335 }
336 
337 basegfx::B2DPolyPolygon SdrVirtObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
338 {
339     return rRefObj.getSpecialDragPoly(rDrag);
340     // Offset handlen !!!!!! fehlt noch !!!!!!!
341 }
342 
343 String SdrVirtObj::getSpecialDragComment(const SdrDragStat& rDrag) const
344 {
345     return rRefObj.getSpecialDragComment(rDrag);
346 }
347 
348 ////////////////////////////////////////////////////////////////////////////////////////////////////
349 
350 FASTBOOL SdrVirtObj::BegCreate(SdrDragStat& rStat)
351 {
352     return rRefObj.BegCreate(rStat);
353 }
354 
355 FASTBOOL SdrVirtObj::MovCreate(SdrDragStat& rStat)
356 {
357     return rRefObj.MovCreate(rStat);
358 }
359 
360 FASTBOOL SdrVirtObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
361 {
362     return rRefObj.EndCreate(rStat,eCmd);
363 }
364 
365 FASTBOOL SdrVirtObj::BckCreate(SdrDragStat& rStat)
366 {
367     return rRefObj.BckCreate(rStat);
368 }
369 
370 void SdrVirtObj::BrkCreate(SdrDragStat& rStat)
371 {
372     rRefObj.BrkCreate(rStat);
373 }
374 
375 basegfx::B2DPolyPolygon SdrVirtObj::TakeCreatePoly(const SdrDragStat& rDrag) const
376 {
377     return rRefObj.TakeCreatePoly(rDrag);
378     // Offset handlen !!!!!! fehlt noch !!!!!!!
379 }
380 
381 ////////////////////////////////////////////////////////////////////////////////////////////////////
382 
383 void SdrVirtObj::NbcMove(const Size& rSiz)
384 {
385     MovePoint(aAnchor,rSiz);
386     SetRectsDirty();
387 }
388 
389 void SdrVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
390 {
391     rRefObj.NbcResize(rRef-aAnchor,xFact,yFact);
392     SetRectsDirty();
393 }
394 
395 void SdrVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
396 {
397     rRefObj.NbcRotate(rRef-aAnchor,nWink,sn,cs);
398     SetRectsDirty();
399 }
400 
401 void SdrVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
402 {
403     rRefObj.NbcMirror(rRef1-aAnchor,rRef2-aAnchor);
404     SetRectsDirty();
405 }
406 
407 void SdrVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
408 {
409     rRefObj.NbcShear(rRef-aAnchor,nWink,tn,bVShear);
410     SetRectsDirty();
411 }
412 
413 ////////////////////////////////////////////////////////////////////////////////////////////////////
414 
415 void SdrVirtObj::Move(const Size& rSiz)
416 {
417     if (rSiz.Width()!=0 || rSiz.Height()!=0) {
418         Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
419         // #110094#-14 SendRepaintBroadcast();
420         NbcMove(rSiz);
421         SetChanged();
422         BroadcastObjectChange();
423         SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
424     }
425 }
426 
427 void SdrVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
428 {
429     if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
430         Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
431         rRefObj.Resize(rRef-aAnchor,xFact,yFact);
432         SetRectsDirty();
433         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
434     }
435 }
436 
437 void SdrVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs)
438 {
439     if (nWink!=0) {
440         Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
441         rRefObj.Rotate(rRef-aAnchor,nWink,sn,cs);
442         SetRectsDirty();
443         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
444     }
445 }
446 
447 void SdrVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
448 {
449     Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
450     rRefObj.Mirror(rRef1-aAnchor,rRef2-aAnchor);
451     SetRectsDirty();
452     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
453 }
454 
455 void SdrVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
456 {
457     if (nWink!=0) {
458         Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
459         rRefObj.Shear(rRef-aAnchor,nWink,tn,bVShear);
460         SetRectsDirty();
461         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
462     }
463 }
464 
465 ////////////////////////////////////////////////////////////////////////////////////////////////////
466 
467 void SdrVirtObj::RecalcSnapRect()
468 {
469     aSnapRect=rRefObj.GetSnapRect();
470     aSnapRect+=aAnchor;
471 }
472 
473 const Rectangle& SdrVirtObj::GetSnapRect() const
474 {
475     ((SdrVirtObj*)this)->aSnapRect=rRefObj.GetSnapRect();
476     ((SdrVirtObj*)this)->aSnapRect+=aAnchor;
477     return aSnapRect;
478 }
479 
480 void SdrVirtObj::SetSnapRect(const Rectangle& rRect)
481 {
482     {
483         Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
484         Rectangle aR(rRect);
485         aR-=aAnchor;
486         rRefObj.SetSnapRect(aR);
487         SetRectsDirty();
488         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
489     }
490 }
491 
492 void SdrVirtObj::NbcSetSnapRect(const Rectangle& rRect)
493 {
494     Rectangle aR(rRect);
495     aR-=aAnchor;
496     SetRectsDirty();
497     rRefObj.NbcSetSnapRect(aR);
498 }
499 
500 ////////////////////////////////////////////////////////////////////////////////////////////////////
501 
502 const Rectangle& SdrVirtObj::GetLogicRect() const
503 {
504     ((SdrVirtObj*)this)->aSnapRect=rRefObj.GetLogicRect();  // !!! Missbrauch von aSnapRect !!!
505     ((SdrVirtObj*)this)->aSnapRect+=aAnchor;                // Wenns mal Aerger gibt, muss ein weiteres Rectangle Member her (oder Heap)
506     return aSnapRect;
507 }
508 
509 void SdrVirtObj::SetLogicRect(const Rectangle& rRect)
510 {
511     Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
512     Rectangle aR(rRect);
513     aR-=aAnchor;
514     rRefObj.SetLogicRect(aR);
515     SetRectsDirty();
516     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
517 }
518 
519 void SdrVirtObj::NbcSetLogicRect(const Rectangle& rRect)
520 {
521     Rectangle aR(rRect);
522     aR-=aAnchor;
523     SetRectsDirty();
524     rRefObj.NbcSetLogicRect(aR);
525 }
526 
527 ////////////////////////////////////////////////////////////////////////////////////////////////////
528 
529 long SdrVirtObj::GetRotateAngle() const
530 {
531     return rRefObj.GetRotateAngle();
532 }
533 
534 long SdrVirtObj::GetShearAngle(FASTBOOL bVertical) const
535 {
536     return rRefObj.GetShearAngle(bVertical);
537 }
538 
539 ////////////////////////////////////////////////////////////////////////////////////////////////////
540 
541 sal_uInt32 SdrVirtObj::GetSnapPointCount() const
542 {
543     return rRefObj.GetSnapPointCount();
544 }
545 
546 Point SdrVirtObj::GetSnapPoint(sal_uInt32 i) const
547 {
548     Point aP(rRefObj.GetSnapPoint(i));
549     aP+=aAnchor;
550     return aP;
551 }
552 
553 sal_Bool SdrVirtObj::IsPolyObj() const
554 {
555     return rRefObj.IsPolyObj();
556 }
557 
558 sal_uInt32 SdrVirtObj::GetPointCount() const
559 {
560     return rRefObj.GetPointCount();
561 }
562 
563 Point SdrVirtObj::GetPoint(sal_uInt32 i) const
564 {
565     return Point(rRefObj.GetPoint(i) + aAnchor);
566 }
567 
568 void SdrVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
569 {
570     Point aP(rPnt);
571     aP-=aAnchor;
572     rRefObj.SetPoint(aP,i);
573     SetRectsDirty();
574 }
575 
576 ////////////////////////////////////////////////////////////////////////////////////////////////////
577 
578 SdrObjGeoData* SdrVirtObj::NewGeoData() const
579 {
580     return rRefObj.NewGeoData();
581 }
582 
583 void SdrVirtObj::SaveGeoData(SdrObjGeoData& rGeo) const
584 {
585     rRefObj.SaveGeoData(rGeo);
586 }
587 
588 void SdrVirtObj::RestGeoData(const SdrObjGeoData& rGeo)
589 {
590     rRefObj.RestGeoData(rGeo);
591     SetRectsDirty();
592 }
593 
594 ////////////////////////////////////////////////////////////////////////////////////////////////////
595 
596 SdrObjGeoData* SdrVirtObj::GetGeoData() const
597 {
598     return rRefObj.GetGeoData();
599 }
600 
601 void SdrVirtObj::SetGeoData(const SdrObjGeoData& rGeo)
602 {
603     Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
604     rRefObj.SetGeoData(rGeo);
605     SetRectsDirty();
606     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
607 }
608 
609 ////////////////////////////////////////////////////////////////////////////////////////////////////
610 
611 void SdrVirtObj::NbcReformatText()
612 {
613     rRefObj.NbcReformatText();
614 }
615 
616 void SdrVirtObj::ReformatText()
617 {
618     rRefObj.ReformatText();
619 }
620 
621 ////////////////////////////////////////////////////////////////////////////////////////////////////
622 
623 FASTBOOL SdrVirtObj::HasMacro() const
624 {
625     return rRefObj.HasMacro();
626 }
627 
628 SdrObject* SdrVirtObj::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
629 {
630     return rRefObj.CheckMacroHit(rRec); // Todo: Positionsversatz
631 }
632 
633 Pointer SdrVirtObj::GetMacroPointer(const SdrObjMacroHitRec& rRec) const
634 {
635     return rRefObj.GetMacroPointer(rRec); // Todo: Positionsversatz
636 }
637 
638 void SdrVirtObj::PaintMacro(OutputDevice& rOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const
639 {
640     rRefObj.PaintMacro(rOut,rDirtyRect,rRec); // Todo: Positionsversatz
641 }
642 
643 FASTBOOL SdrVirtObj::DoMacro(const SdrObjMacroHitRec& rRec)
644 {
645     return rRefObj.DoMacro(rRec); // Todo: Positionsversatz
646 }
647 
648 XubString SdrVirtObj::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const
649 {
650     return rRefObj.GetMacroPopupComment(rRec); // Todo: Positionsversatz
651 }
652 
653 const Point SdrVirtObj::GetOffset() const
654 {
655     // #i73248# default offset of SdrVirtObj is aAnchor
656     return aAnchor;
657 }
658 
659 // eof
660