remove SdrObject::GetHdl in favour of AddToHdlList

the code already says that using GetHdl is inefficient, and client code
should be using AddToHdlList, so just drop the bad one

Change-Id: I88c43154c8cc0988127b9292e4cda28917f54eb9
Reviewed-on: https://gerrit.libreoffice.org/60792
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/include/svx/svdhdl.hxx b/include/svx/svdhdl.hxx
index 0e954c1..5416ec7 100644
--- a/include/svx/svdhdl.hxx
+++ b/include/svx/svdhdl.hxx
@@ -461,6 +461,9 @@ public:
    SdrHdl* RemoveHdl(size_t nNum);
    void RemoveAllByKind(SdrHdlKind eKind);

    // move the ownership of all the SdrHdl to rOther
    void MoveTo(SdrHdlList& rOther);

    // Last inserted handles are likely hit (if the handles are above each other)
    SdrHdl* IsHdlListHit(const Point& rPnt) const;
    SdrHdl* GetHdl(SdrHdlKind eKind1) const;
diff --git a/include/svx/svdoashp.hxx b/include/svx/svdoashp.hxx
index ed90a91..e7f9159 100644
--- a/include/svx/svdoashp.hxx
+++ b/include/svx/svdoashp.hxx
@@ -240,7 +240,7 @@ public:
    virtual SdrGluePointList* ForceGluePointList() override;

    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl( sal_uInt32 nHdlNum ) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // #i33136#
    static bool doConstructOrthogonal(const OUString& rName);
diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index d01031c..5c5fb75 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -521,7 +521,6 @@ public:
    /// An object that returns true from HasSpacialDrag() must provide these
    /// methods (incl. FillHdlList()).
    virtual sal_uInt32 GetHdlCount() const;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const;
    virtual sal_uInt32 GetPlusHdlCount(const SdrHdl& rHdl) const;
    virtual SdrHdl* GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const;
diff --git a/include/svx/svdocapt.hxx b/include/svx/svdocapt.hxx
index 124e83c..68bc32a5 100644
--- a/include/svx/svdocapt.hxx
+++ b/include/svx/svdocapt.hxx
@@ -106,7 +106,7 @@ public:
    virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;

    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // special drag methods
    virtual bool hasSpecialDrag() const override;
diff --git a/include/svx/svdocirc.hxx b/include/svx/svdocirc.hxx
index 8ce5681..b681ad5 100644
--- a/include/svx/svdocirc.hxx
+++ b/include/svx/svdocirc.hxx
@@ -109,7 +109,7 @@ public:
    virtual Point GetSnapPoint(sal_uInt32 i) const override;

    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // special drag methods
    virtual bool hasSpecialDrag() const override;
diff --git a/include/svx/svdoedge.hxx b/include/svx/svdoedge.hxx
index 61b5341..0a68d6f 100644
--- a/include/svx/svdoedge.hxx
+++ b/include/svx/svdoedge.hxx
@@ -227,7 +227,7 @@ public:

    virtual basegfx::B2DPolyPolygon TakeXorPoly() const override;
    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // special drag methods
    virtual bool hasSpecialDrag() const override;
diff --git a/include/svx/svdograf.hxx b/include/svx/svdograf.hxx
index 42cc1a3..8cc7395 100644
--- a/include/svx/svdograf.hxx
+++ b/include/svx/svdograf.hxx
@@ -179,7 +179,7 @@ public:
    SdrGrafObj&             operator=(const SdrGrafObj& rObj);

    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    virtual void            NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) override;
    virtual void            NbcMirror(const Point& rRef1, const Point& rRef2) override;
diff --git a/include/svx/svdomeas.hxx b/include/svx/svdomeas.hxx
index 409dbbf..374cdff 100644
--- a/include/svx/svdomeas.hxx
+++ b/include/svx/svdomeas.hxx
@@ -95,7 +95,7 @@ public:

    virtual basegfx::B2DPolyPolygon TakeXorPoly() const override;
    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // special drag methods
    virtual bool hasSpecialDrag() const override;
diff --git a/include/svx/svdopath.hxx b/include/svx/svdopath.hxx
index 0f58f1f..66c3b04 100644
--- a/include/svx/svdopath.hxx
+++ b/include/svx/svdopath.hxx
@@ -86,10 +86,9 @@ public:
    virtual void RecalcSnapRect() override;
    virtual void NbcSetSnapRect(const tools::Rectangle& rRect) override;
    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
    virtual sal_uInt32 GetPlusHdlCount(const SdrHdl& rHdl) const override;
    virtual SdrHdl* GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // special drag methods
    virtual bool hasSpecialDrag() const override;
diff --git a/include/svx/svdorect.hxx b/include/svx/svdorect.hxx
index 15d5c36..00f1b48 100644
--- a/include/svx/svdorect.hxx
+++ b/include/svx/svdorect.hxx
@@ -99,7 +99,7 @@ public:
    virtual basegfx::B2DPolyPolygon TakeXorPoly() const override;

    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // Special drag methods
    virtual bool hasSpecialDrag() const override;
diff --git a/include/svx/svdotable.hxx b/include/svx/svdotable.hxx
index 6f52fde..72d5f25 100644
--- a/include/svx/svdotable.hxx
+++ b/include/svx/svdotable.hxx
@@ -211,7 +211,6 @@ public:
    virtual void AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool bShrinkOnly = false ) override;

    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // Special drag methods
diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index deb8e74..9bca148 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -459,7 +459,7 @@ public:
    virtual Point GetSnapPoint(sal_uInt32 i) const override;

    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;

    // special drag methods
    virtual bool hasSpecialDrag() const override;
diff --git a/include/svx/svdovirt.hxx b/include/svx/svdovirt.hxx
index 45c04cc..5d562a7 100644
--- a/include/svx/svdovirt.hxx
+++ b/include/svx/svdovirt.hxx
@@ -77,7 +77,6 @@ public:

    virtual basegfx::B2DPolyPolygon TakeXorPoly() const override;
    virtual sal_uInt32 GetHdlCount() const override;
    virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
    virtual sal_uInt32 GetPlusHdlCount(const SdrHdl& rHdl) const override;
    virtual SdrHdl* GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const override;
    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index d629152..f46b8ca0 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -486,10 +486,12 @@ void SdTiledRenderingTest::testSetGraphicSelection()
    sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
    SdPage* pPage = pViewShell->GetActualPage();
    SdrObject* pObject = pPage->GetObj(0);
    SdrHdlList handleList(nullptr);
    pObject->AddToHdlList(handleList);
    // Make sure the rectangle has 8 handles: at each corner and at the center of each edge.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(8), pObject->GetHdlCount());
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(8), handleList.GetHdlCount());
    // Take the bottom center one.
    SdrHdl* pHdl = pObject->GetHdl(6);
    SdrHdl* pHdl = handleList.GetHdl(6);
    CPPUNIT_ASSERT_EQUAL(int(SdrHdlKind::Lower), static_cast<int>(pHdl->GetKind()));
    ::tools::Rectangle aShapeBefore = pObject->GetSnapRect();
    // Resize.
diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx
index 510b58d..31f232d 100644
--- a/svx/source/svdraw/svdhdl.cxx
+++ b/svx/source/svdraw/svdhdl.cxx
@@ -2251,11 +2251,9 @@ size_t SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const

void SdrHdlList::AddHdl(SdrHdl* pHdl)
{
    if (pHdl!=nullptr)
    {
        aList.push_back(pHdl);
        pHdl->SetHdlList(this);
    }
    assert(pHdl);
    aList.push_back(pHdl);
    pHdl->SetHdlList(this);
}

SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt) const
@@ -2285,6 +2283,12 @@ SdrHdl* SdrHdlList::GetHdl(SdrHdlKind eKind1) const
    return pRet;
}

void SdrHdlList::MoveTo(SdrHdlList& rOther)
{
    rOther.aList.insert(rOther.aList.end(), aList.begin(), aList.end());
    aList.clear();
}

SdrCropHdl::SdrCropHdl(
    const Point& rPnt,
    SdrHdlKind eNewKind,
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 476d4de..c944324 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -1801,43 +1801,34 @@ SdrGluePointList* SdrObjCustomShape::ForceGluePointList()
sal_uInt32 SdrObjCustomShape::GetHdlCount() const
{
    const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
    std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
    return ( aInteractionHandles.size() + nBasicHdlCount );
    return ( GetInteractionHandles().size() + nBasicHdlCount );
}

SdrHdl* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum ) const
void SdrObjCustomShape::AddToHdlList(SdrHdlList& rHdlList) const
{
    SdrHdl* pH = nullptr;
    const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
    SdrTextObj::AddToHdlList(rHdlList);

    if ( nHdlNum < nBasicHdlCount )
        pH = SdrTextObj::GetHdl( nHdlNum );
    else
    int nCustomShapeHdlNum = 0;
    for (SdrCustomShapeInteraction const & rInteraction : GetInteractionHandles())
    {
        std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
        const sal_uInt32 nCustomShapeHdlNum(nHdlNum - nBasicHdlCount);

        if ( nCustomShapeHdlNum < aInteractionHandles.size() )
        if ( rInteraction.xInteraction.is() )
        {
            if ( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction.is() )
            try
            {
                try
                {
                    css::awt::Point aPosition( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction->getPosition() );
                    pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), SdrHdlKind::CustomShape1 );
                    pH->SetPointNum( nCustomShapeHdlNum );
                    pH->SetObj( const_cast<SdrObjCustomShape*>(this) );
                }
                catch ( const uno::RuntimeException& )
                {
                }
                css::awt::Point aPosition( rInteraction.xInteraction->getPosition() );
                SdrHdl* pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), SdrHdlKind::CustomShape1 );
                pH->SetPointNum( nCustomShapeHdlNum );
                pH->SetObj( const_cast<SdrObjCustomShape*>(this) );
                rHdlList.AddHdl(pH);
            }
            catch ( const uno::RuntimeException& )
            {
            }
        }
        ++nCustomShapeHdlNum;
    }
    return pH;
}


bool SdrObjCustomShape::hasSpecialDrag() const
{
    return true;
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 5a705b9..9e37ca8 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1174,21 +1174,24 @@ sal_uInt32 SdrObject::GetHdlCount() const
    return 8L;
}

SdrHdl* SdrObject::GetHdl(sal_uInt32 nHdlNum) const
void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const
{
    SdrHdl* pH=nullptr;
    const tools::Rectangle& rR=GetSnapRect();
    switch (nHdlNum) {
        case 0: pH=new SdrHdl(rR.TopLeft(),     SdrHdlKind::UpperLeft); break;
        case 1: pH=new SdrHdl(rR.TopCenter(),   SdrHdlKind::Upper); break;
        case 2: pH=new SdrHdl(rR.TopRight(),    SdrHdlKind::UpperRight); break;
        case 3: pH=new SdrHdl(rR.LeftCenter(),  SdrHdlKind::Left ); break;
        case 4: pH=new SdrHdl(rR.RightCenter(), SdrHdlKind::Right); break;
        case 5: pH=new SdrHdl(rR.BottomLeft(),  SdrHdlKind::LowerLeft); break;
        case 6: pH=new SdrHdl(rR.BottomCenter(),SdrHdlKind::Lower); break;
        case 7: pH=new SdrHdl(rR.BottomRight(), SdrHdlKind::LowerRight); break;
    for (sal_uInt32 nHdlNum=0; nHdlNum<8; ++nHdlNum)
    {
        SdrHdl* pH=nullptr;
        switch (nHdlNum) {
            case 0: pH=new SdrHdl(rR.TopLeft(),     SdrHdlKind::UpperLeft); break;
            case 1: pH=new SdrHdl(rR.TopCenter(),   SdrHdlKind::Upper); break;
            case 2: pH=new SdrHdl(rR.TopRight(),    SdrHdlKind::UpperRight); break;
            case 3: pH=new SdrHdl(rR.LeftCenter(),  SdrHdlKind::Left ); break;
            case 4: pH=new SdrHdl(rR.RightCenter(), SdrHdlKind::Right); break;
            case 5: pH=new SdrHdl(rR.BottomLeft(),  SdrHdlKind::LowerLeft); break;
            case 6: pH=new SdrHdl(rR.BottomCenter(),SdrHdlKind::Lower); break;
            case 7: pH=new SdrHdl(rR.BottomRight(), SdrHdlKind::LowerRight); break;
        }
        rHdlList.AddHdl(pH);
    }
    return pH;
}

sal_uInt32 SdrObject::GetPlusHdlCount(const SdrHdl& /*rHdl*/) const
@@ -1201,17 +1204,6 @@ SdrHdl* SdrObject::GetPlusHdl(const SdrHdl& /*rHdl*/, sal_uInt32 /*nPlNum*/) con
    return nullptr;
}

void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const
{
    sal_uInt32 nCount=GetHdlCount();
    for (sal_uInt32 i=0; i<nCount; i++) {
        SdrHdl* pHdl=GetHdl(i);
        if (pHdl!=nullptr) {
            rHdlList.AddHdl(pHdl);
        }
    }
}

void SdrObject::addCropHandles(SdrHdlList& /*rTarget*/) const
{
    // Default implementation, does nothing. Overloaded in
diff --git a/svx/source/svdraw/svdocapt.cxx b/svx/source/svdraw/svdocapt.cxx
index 7acb0bd..4be0d66 100644
--- a/svx/source/svdraw/svdocapt.cxx
+++ b/svx/source/svdraw/svdocapt.cxx
@@ -294,34 +294,21 @@ sal_uInt32 SdrCaptionObj::GetHdlCount() const
    return nCount1 + 1;
}

SdrHdl* SdrCaptionObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrCaptionObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    const sal_uInt32 nRectHdlCnt(SdrRectObj::GetHdlCount());
    SdrRectObj::AddToHdlList(rHdlList);
    const sal_uInt32 nRectHdlCnt(rHdlList.GetHdlCount());

    if(nHdlNum < nRectHdlCnt)
    sal_uInt32 nCnt = aTailPoly.GetSize();
    for(sal_uInt32 i = 0; i<nCnt; ++i)
    {
        return SdrRectObj::GetHdl(nHdlNum);
    }
    else
    {
        sal_uInt32 nPntNum(nHdlNum);
        nPntNum -= nRectHdlCnt;

        if(nPntNum < aTailPoly.GetSize())
        {
            SdrHdl* pHdl = new SdrHdl(aTailPoly.GetPoint(static_cast<sal_uInt16>(nPntNum)), SdrHdlKind::Poly);
            pHdl->SetPolyNum(1);
            pHdl->SetPointNum(nPntNum);
            return pHdl;
        }
        else
        {
            return nullptr;
        }
        SdrHdl* pHdl = new SdrHdl(aTailPoly.GetPoint(i), SdrHdlKind::Poly);
        pHdl->SetPolyNum(1);
        pHdl->SetPointNum(nRectHdlCnt + i);
        rHdlList.AddHdl(pHdl);
    }
}


bool SdrCaptionObj::hasSpecialDrag() const
{
    return true;
diff --git a/svx/source/svdraw/svdocirc.cxx b/svx/source/svdraw/svdocirc.cxx
index 5f80317..10272e0 100644
--- a/svx/source/svdraw/svdocirc.cxx
+++ b/svx/source/svdraw/svdocirc.cxx
@@ -406,83 +406,81 @@ sal_uInt32 SdrCircObj::GetHdlCount() const
    }
}

SdrHdl* SdrCircObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrCircObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    sal_uInt32 nHdlCnt = 8;
    if (meCircleKind==OBJ_CIRC)
    {
        nHdlNum += 2;
    }
        nHdlCnt += 2;

    SdrHdl* pH = nullptr;
    Point aPnt;
    SdrHdlKind eLocalKind(SdrHdlKind::Move);
    sal_uInt32 nPNum(0);

    switch (nHdlNum)
    for (sal_uInt32 nHdlNum=0; nHdlNum<nHdlCnt; ++nHdlNum)
    {
        case 0:
            aPnt = GetAnglePnt(maRect,nStartAngle);
            eLocalKind = SdrHdlKind::Circle;
            nPNum = 1;
            break;
        case 1:
            aPnt = GetAnglePnt(maRect,nEndAngle);
            eLocalKind = SdrHdlKind::Circle;
            nPNum = 2;
            break;
        case 2:
            aPnt = maRect.TopLeft();
            eLocalKind = SdrHdlKind::UpperLeft;
            break;
        case 3:
            aPnt = maRect.TopCenter();
            eLocalKind = SdrHdlKind::Upper;
            break;
        case 4:
            aPnt = maRect.TopRight();
            eLocalKind = SdrHdlKind::UpperRight;
            break;
        case 5:
            aPnt = maRect.LeftCenter();
            eLocalKind = SdrHdlKind::Left;
            break;
        case 6:
            aPnt = maRect.RightCenter();
            eLocalKind = SdrHdlKind::Right;
            break;
        case 7:
            aPnt = maRect.BottomLeft();
            eLocalKind = SdrHdlKind::LowerLeft;
            break;
        case 8:
            aPnt = maRect.BottomCenter();
            eLocalKind = SdrHdlKind::Lower;
            break;
        case 9:
            aPnt = maRect.BottomRight();
            eLocalKind = SdrHdlKind::LowerRight;
            break;
    }
        SdrHdl* pH = nullptr;
        Point aPnt;
        SdrHdlKind eLocalKind(SdrHdlKind::Move);
        sal_uInt32 nPNum(0);

    if (aGeo.nShearAngle)
    {
        ShearPoint(aPnt,maRect.TopLeft(),aGeo.nTan);
    }
        switch (nHdlNum)
        {
            case 0:
                aPnt = GetAnglePnt(maRect,nStartAngle);
                eLocalKind = SdrHdlKind::Circle;
                nPNum = 1;
                break;
            case 1:
                aPnt = GetAnglePnt(maRect,nEndAngle);
                eLocalKind = SdrHdlKind::Circle;
                nPNum = 2;
                break;
            case 2:
                aPnt = maRect.TopLeft();
                eLocalKind = SdrHdlKind::UpperLeft;
                break;
            case 3:
                aPnt = maRect.TopCenter();
                eLocalKind = SdrHdlKind::Upper;
                break;
            case 4:
                aPnt = maRect.TopRight();
                eLocalKind = SdrHdlKind::UpperRight;
                break;
            case 5:
                aPnt = maRect.LeftCenter();
                eLocalKind = SdrHdlKind::Left;
                break;
            case 6:
                aPnt = maRect.RightCenter();
                eLocalKind = SdrHdlKind::Right;
                break;
            case 7:
                aPnt = maRect.BottomLeft();
                eLocalKind = SdrHdlKind::LowerLeft;
                break;
            case 8:
                aPnt = maRect.BottomCenter();
                eLocalKind = SdrHdlKind::Lower;
                break;
            case 9:
                aPnt = maRect.BottomRight();
                eLocalKind = SdrHdlKind::LowerRight;
                break;
        }

    if (aGeo.nRotationAngle)
    {
        RotatePoint(aPnt,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
    }
        if (aGeo.nShearAngle)
        {
            ShearPoint(aPnt,maRect.TopLeft(),aGeo.nTan);
        }

    if (eLocalKind != SdrHdlKind::Move)
    {
        if (aGeo.nRotationAngle)
        {
            RotatePoint(aPnt,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
        }

        pH = new SdrHdl(aPnt,eLocalKind);
        pH->SetPointNum(nPNum);
        pH->SetObj(const_cast<SdrCircObj*>(this));
        pH->SetRotationAngle(aGeo.nRotationAngle);
        rHdlList.AddHdl(pH);
    }

    return pH;
}


diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx
index 605ed18..8c9ef41 100644
--- a/svx/source/svdraw/svdoedge.cxx
+++ b/svx/source/svdraw/svdoedge.cxx
@@ -1747,13 +1747,12 @@ sal_uInt32 SdrEdgeObj::GetHdlCount() const
    if(nPointCount)
    {
        nHdlCnt = 2;

        if ((eKind==SdrEdgeKind::OrthoLines || eKind==SdrEdgeKind::Bezier) && nPointCount >= 4)
        {
            sal_uInt32 nO1(aEdgeInfo.nObj1Lines > 0 ? aEdgeInfo.nObj1Lines - 1 : 0);
            sal_uInt32 nO2(aEdgeInfo.nObj2Lines > 0 ? aEdgeInfo.nObj2Lines - 1 : 0);
            sal_uInt32 nM(aEdgeInfo.nMiddleLine != 0xFFFF ? 1 : 0);
            nHdlCnt += nO1 + nO2 + nM;
             sal_uInt32 nO1(aEdgeInfo.nObj1Lines > 0 ? aEdgeInfo.nObj1Lines - 1 : 0);
             sal_uInt32 nO2(aEdgeInfo.nObj2Lines > 0 ? aEdgeInfo.nObj2Lines - 1 : 0);
             sal_uInt32 nM(aEdgeInfo.nMiddleLine != 0xFFFF ? 1 : 0);
             nHdlCnt += nO1 + nO2 + nM;
        }
        else if (eKind==SdrEdgeKind::ThreeLines && nPointCount == 4)
        {
@@ -1768,41 +1767,50 @@ sal_uInt32 SdrEdgeObj::GetHdlCount() const
    return nHdlCnt;
}

SdrHdl* SdrEdgeObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrEdgeObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    SdrHdl* pHdl=nullptr;
    sal_uInt32 nPointCount(pEdgeTrack->GetPointCount());
    if (nPointCount!=0) {
        if (nHdlNum==0) {
            pHdl=new ImpEdgeHdl((*pEdgeTrack)[0],SdrHdlKind::Poly);
            if (aCon1.pObj!=nullptr && aCon1.bBestVertex) pHdl->Set1PixMore();
        } else if (nHdlNum==1) {
            pHdl=new ImpEdgeHdl((*pEdgeTrack)[sal_uInt16(nPointCount-1)],SdrHdlKind::Poly);
            if (aCon2.pObj!=nullptr && aCon2.bBestVertex) pHdl->Set1PixMore();
        } else {
            SdrEdgeKind eKind=GetObjectItem(SDRATTR_EDGEKIND).GetValue();
            if (eKind==SdrEdgeKind::OrthoLines || eKind==SdrEdgeKind::Bezier) {
                sal_uInt32 nO1(aEdgeInfo.nObj1Lines > 0 ? aEdgeInfo.nObj1Lines - 1 : 0);
                sal_uInt32 nO2(aEdgeInfo.nObj2Lines > 0 ? aEdgeInfo.nObj2Lines - 1 : 0);
                sal_uInt32 nM(aEdgeInfo.nMiddleLine != 0xFFFF ? 1 : 0);
                sal_uInt32 nNum(nHdlNum - 2);
    if (nPointCount==0)
        return;

    {
        SdrHdl* pHdl=new ImpEdgeHdl((*pEdgeTrack)[0],SdrHdlKind::Poly);
        if (aCon1.pObj!=nullptr && aCon1.bBestVertex) pHdl->Set1PixMore();
        pHdl->SetPointNum(0);
        rHdlList.AddHdl(pHdl);
    }
    {
        SdrHdl* pHdl=new ImpEdgeHdl((*pEdgeTrack)[sal_uInt16(nPointCount-1)],SdrHdlKind::Poly);
        if (aCon2.pObj!=nullptr && aCon2.bBestVertex) pHdl->Set1PixMore();
        pHdl->SetPointNum(1);
        rHdlList.AddHdl(pHdl);
    }
    {
        SdrEdgeKind eKind=GetObjectItem(SDRATTR_EDGEKIND).GetValue();
        if ((eKind==SdrEdgeKind::OrthoLines || eKind==SdrEdgeKind::Bezier) && nPointCount >= 4)
        {
            sal_uInt32 nO1(aEdgeInfo.nObj1Lines > 0 ? aEdgeInfo.nObj1Lines - 1 : 0);
            sal_uInt32 nO2(aEdgeInfo.nObj2Lines > 0 ? aEdgeInfo.nObj2Lines - 1 : 0);
            sal_uInt32 nM(aEdgeInfo.nMiddleLine != 0xFFFF ? 1 : 0);
            for(sal_uInt32 nNum = 0; nNum < (nO1 + nO2 + nM); ++nNum)
            {
                sal_Int32 nPt(0);
                pHdl=new ImpEdgeHdl(Point(),SdrHdlKind::Poly);
                ImpEdgeHdl* pHdl=new ImpEdgeHdl(Point(),SdrHdlKind::Poly);
                if (nNum<nO1) {
                    nPt=nNum+1;
                    if (nNum==0) static_cast<ImpEdgeHdl*>(pHdl)->SetLineCode(SdrEdgeLineCode::Obj1Line2);
                    if (nNum==1) static_cast<ImpEdgeHdl*>(pHdl)->SetLineCode(SdrEdgeLineCode::Obj1Line3);
                    if (nNum==0) pHdl->SetLineCode(SdrEdgeLineCode::Obj1Line2);
                    if (nNum==1) pHdl->SetLineCode(SdrEdgeLineCode::Obj1Line3);
                } else {
                    nNum=nNum-nO1;
                    if (nNum<nO2) {
                        nPt=nPointCount-3-nNum;
                        if (nNum==0) static_cast<ImpEdgeHdl*>(pHdl)->SetLineCode(SdrEdgeLineCode::Obj2Line2);
                        if (nNum==1) static_cast<ImpEdgeHdl*>(pHdl)->SetLineCode(SdrEdgeLineCode::Obj2Line3);
                        if (nNum==0) pHdl->SetLineCode(SdrEdgeLineCode::Obj2Line2);
                        if (nNum==1) pHdl->SetLineCode(SdrEdgeLineCode::Obj2Line3);
                    } else {
                        nNum=nNum-nO2;
                        if (nNum<nM) {
                            nPt=aEdgeInfo.nMiddleLine;
                            static_cast<ImpEdgeHdl*>(pHdl)->SetLineCode(SdrEdgeLineCode::MiddleLine);
                            pHdl->SetLineCode(SdrEdgeLineCode::MiddleLine);
                        }
                    }
                }
@@ -1812,27 +1820,36 @@ SdrHdl* SdrEdgeObj::GetHdl(sal_uInt32 nHdlNum) const
                    aPos.setX( aPos.X() / 2 );
                    aPos.setY( aPos.Y() / 2 );
                    pHdl->SetPos(aPos);
                    pHdl->SetPointNum(nNum + 2);
                    rHdlList.AddHdl(pHdl);
                } else {
                    delete pHdl;
                    pHdl=nullptr;
                }
            } else if (eKind==SdrEdgeKind::ThreeLines) {
                sal_uInt32 nNum(nHdlNum);
                if (GetConnectedNode(true)==nullptr) nNum++;
                Point aPos((*pEdgeTrack)[static_cast<sal_uInt16>(nNum)-1]);
                pHdl=new ImpEdgeHdl(aPos,SdrHdlKind::Poly);
                if (nNum==2) static_cast<ImpEdgeHdl*>(pHdl)->SetLineCode(SdrEdgeLineCode::Obj1Line2);
                if (nNum==3) static_cast<ImpEdgeHdl*>(pHdl)->SetLineCode(SdrEdgeLineCode::Obj2Line2);
            }
        }
        if (pHdl!=nullptr) {
            pHdl->SetPointNum(nHdlNum);
        else if (eKind==SdrEdgeKind::ThreeLines && nPointCount == 4)
        {
            if(GetConnectedNode(true))
            {
                Point aPos((*pEdgeTrack)[1]);
                ImpEdgeHdl* pHdl=new ImpEdgeHdl(aPos,SdrHdlKind::Poly);
                pHdl->SetLineCode(SdrEdgeLineCode::Obj1Line2);
                pHdl->SetPointNum(2);
                rHdlList.AddHdl(pHdl);
            }
            if(GetConnectedNode(false))
            {
                Point aPos((*pEdgeTrack)[2]);
                ImpEdgeHdl* pHdl=new ImpEdgeHdl(aPos,SdrHdlKind::Poly);
                pHdl->SetLineCode(SdrEdgeLineCode::Obj2Line2);
                pHdl->SetPointNum(3);
                rHdlList.AddHdl(pHdl);
            }
        }
    }
    return pHdl;
}


bool SdrEdgeObj::hasSpecialDrag() const
{
    return true;
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index 2a6463d..27b1e4d 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -751,9 +751,12 @@ sal_uInt32 SdrGrafObj::GetHdlCount() const
    return 8L;
}

SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrGrafObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    return SdrRectObj::GetHdl( nHdlNum + 1 );
    SdrHdlList tempList(nullptr);
    SdrRectObj::AddToHdlList( tempList );
    tempList.RemoveHdl(0);
    tempList.MoveTo(rHdlList);
}

void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
diff --git a/svx/source/svdraw/svdomeas.cxx b/svx/source/svdraw/svdomeas.cxx
index c7add74..70b4a9f 100644
--- a/svx/source/svdraw/svdomeas.cxx
+++ b/svx/source/svdraw/svdomeas.cxx
@@ -751,27 +751,30 @@ sal_uInt32 SdrMeasureObj::GetHdlCount() const
    return 6L;
}

SdrHdl* SdrMeasureObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrMeasureObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    ImpMeasureRec aRec;
    ImpMeasurePoly aMPol;
    ImpTakeAttr(aRec);
    aRec.nHelplineDist=0;
    ImpCalcGeometrics(aRec,aMPol);
    Point aPt;

    switch (nHdlNum) {
        case 0: aPt=aMPol.aHelpline1.aP1; break;
        case 1: aPt=aMPol.aHelpline2.aP1; break;
        case 2: aPt=aPt1;       break;
        case 3: aPt=aPt2;       break;
        case 4: aPt=aMPol.aHelpline1.aP2; break;
        case 5: aPt=aMPol.aHelpline2.aP2; break;
    } // switch
    SdrHdl* pHdl=new ImpMeasureHdl(aPt,SdrHdlKind::User);
    pHdl->SetObjHdlNum(nHdlNum);
    pHdl->SetRotationAngle(aMPol.nLineAngle);
    return pHdl;
    for (sal_uInt32 nHdlNum=0; nHdlNum<6; ++nHdlNum)
    {
        Point aPt;
        switch (nHdlNum) {
            case 0: aPt=aMPol.aHelpline1.aP1; break;
            case 1: aPt=aMPol.aHelpline2.aP1; break;
            case 2: aPt=aPt1;       break;
            case 3: aPt=aPt2;       break;
            case 4: aPt=aMPol.aHelpline1.aP2; break;
            case 5: aPt=aMPol.aHelpline2.aP2; break;
        } // switch
        SdrHdl* pHdl=new ImpMeasureHdl(aPt,SdrHdlKind::User);
        pHdl->SetObjHdlNum(nHdlNum);
        pHdl->SetRotationAngle(aMPol.nLineAngle);
        rHdlList.AddHdl(pHdl);
    }
}


diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx
index 3dd12b6..55a66ab 100644
--- a/svx/source/svdraw/svdopath.cxx
+++ b/svx/source/svdraw/svdopath.cxx
@@ -1984,28 +1984,6 @@ sal_uInt32 SdrPathObj::GetHdlCount() const
    return nRetval;
}

SdrHdl* SdrPathObj::GetHdl(sal_uInt32 nHdlNum) const
{
    // #i73248#
    // Warn the user that this is ineffective and show alternatives. Should not be used at all.
    OSL_FAIL("SdrPathObj::GetHdl(): ineffective, use AddToHdlList instead (!)");

    // to have an alternative, get single handle using the ineffective way
    SdrHdl* pRetval = nullptr;
    SdrHdlList aLocalList(nullptr);
    AddToHdlList(aLocalList);
    const sal_uInt32 nHdlCount(aLocalList.GetHdlCount());

    if(nHdlCount && nHdlNum < nHdlCount)
    {
        // remove and remember. The other created handles will be deleted again with the
        // destruction of the local list
        pRetval = aLocalList.RemoveHdl(nHdlNum);
    }

    return pRetval;
}

void SdrPathObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    // keep old stuff to be able to keep old SdrHdl stuff, too
diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx
index c961d04..fe727ae 100644
--- a/svx/source/svdraw/svdorect.cxx
+++ b/svx/source/svdraw/svdorect.cxx
@@ -310,71 +310,68 @@ sal_uInt32 SdrRectObj::GetHdlCount() const
    return IsTextFrame() ? 10 : 9;
}

SdrHdl* SdrRectObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrRectObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    SdrHdl* pH = nullptr;
    Point aPnt;
    SdrHdlKind eKind = SdrHdlKind::Move;

    if(!IsTextFrame())
    sal_Int32 nCount = IsTextFrame() ? 10 : 9;
    for(sal_Int32 nHdlNum = 0; nHdlNum < nCount; ++nHdlNum)
    {
        nHdlNum++;
    }
        SdrHdl* pH = nullptr;
        Point aPnt;
        SdrHdlKind eKind = SdrHdlKind::Move;

    switch(nHdlNum)
    {
        case 0:
        switch(nHdlNum)
        {
            OSL_ENSURE(!IsTextEditActive(), "Do not use a ImpTextframeHdl for highlighting text in active text edit, this will collide with EditEngine paints (!)");
            // hack for calc grid sync to ensure the hatched area
            // for a textbox is displayed at correct position
            pH = new ImpTextframeHdl(maRect + GetGridOffset() );
            case 0:
            {
                OSL_ENSURE(!IsTextEditActive(), "Do not use a ImpTextframeHdl for highlighting text in active text edit, this will collide with EditEngine paints (!)");
                // hack for calc grid sync to ensure the hatched area
                // for a textbox is displayed at correct position
                pH = new ImpTextframeHdl(maRect + GetGridOffset() );
                pH->SetObj(const_cast<SdrRectObj*>(this));
                pH->SetRotationAngle(aGeo.nRotationAngle);
                break;
            }
            case 1:
            {
                long a = GetEckenradius();
                long b = std::max(maRect.GetWidth(),maRect.GetHeight())/2; // rounded up, because GetWidth() adds 1
                if (a>b) a=b;
                if (a<0) a=0;
                aPnt=maRect.TopLeft();
                aPnt.AdjustX(a );
                eKind = SdrHdlKind::Circle;
                break;
            }
            case 2: aPnt=maRect.TopLeft();      eKind = SdrHdlKind::UpperLeft; break;
            case 3: aPnt=maRect.TopCenter();    eKind = SdrHdlKind::Upper; break;
            case 4: aPnt=maRect.TopRight();     eKind = SdrHdlKind::UpperRight; break;
            case 5: aPnt=maRect.LeftCenter();   eKind = SdrHdlKind::Left ; break;
            case 6: aPnt=maRect.RightCenter();  eKind = SdrHdlKind::Right; break;
            case 7: aPnt=maRect.BottomLeft();   eKind = SdrHdlKind::LowerLeft; break;
            case 8: aPnt=maRect.BottomCenter(); eKind = SdrHdlKind::Lower; break;
            case 9: aPnt=maRect.BottomRight();  eKind = SdrHdlKind::LowerRight; break;
        }

        if(!pH)
        {
            if(aGeo.nShearAngle)
            {
                ShearPoint(aPnt,maRect.TopLeft(),aGeo.nTan);
            }

            if(aGeo.nRotationAngle)
            {
                RotatePoint(aPnt,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
            }

            pH = new SdrHdl(aPnt,eKind);
            pH->SetObj(const_cast<SdrRectObj*>(this));
            pH->SetRotationAngle(aGeo.nRotationAngle);
            break;
        }
        case 1:
        {
            long a = GetEckenradius();
            long b = std::max(maRect.GetWidth(),maRect.GetHeight())/2; // rounded up, because GetWidth() adds 1
            if (a>b) a=b;
            if (a<0) a=0;
            aPnt=maRect.TopLeft();
            aPnt.AdjustX(a );
            eKind = SdrHdlKind::Circle;
            break;
        }
        case 2: aPnt=maRect.TopLeft();      eKind = SdrHdlKind::UpperLeft; break;
        case 3: aPnt=maRect.TopCenter();    eKind = SdrHdlKind::Upper; break;
        case 4: aPnt=maRect.TopRight();     eKind = SdrHdlKind::UpperRight; break;
        case 5: aPnt=maRect.LeftCenter();   eKind = SdrHdlKind::Left ; break;
        case 6: aPnt=maRect.RightCenter();  eKind = SdrHdlKind::Right; break;
        case 7: aPnt=maRect.BottomLeft();   eKind = SdrHdlKind::LowerLeft; break;
        case 8: aPnt=maRect.BottomCenter(); eKind = SdrHdlKind::Lower; break;
        case 9: aPnt=maRect.BottomRight();  eKind = SdrHdlKind::LowerRight; break;
        rHdlList.AddHdl(pH);
    }

    if(!pH)
    {
        if(aGeo.nShearAngle)
        {
            ShearPoint(aPnt,maRect.TopLeft(),aGeo.nTan);
        }

        if(aGeo.nRotationAngle)
        {
            RotatePoint(aPnt,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
        }

        pH = new SdrHdl(aPnt,eKind);
        pH->SetObj(const_cast<SdrRectObj*>(this));
        pH->SetRotationAngle(aGeo.nRotationAngle);
    }

    return pH;
}


bool SdrRectObj::hasSpecialDrag() const
{
    return true;
diff --git a/svx/source/svdraw/svdotxdr.cxx b/svx/source/svdraw/svdotxdr.cxx
index 635d002..5ce1e60 100644
--- a/svx/source/svdraw/svdotxdr.cxx
+++ b/svx/source/svdraw/svdotxdr.cxx
@@ -36,29 +36,30 @@ sal_uInt32 SdrTextObj::GetHdlCount() const
    return 8L;
}

SdrHdl* SdrTextObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrTextObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    SdrHdl* pH=nullptr;
    Point aPnt;
    SdrHdlKind eKind=SdrHdlKind::Move;
    switch (nHdlNum) {
        case 0: aPnt=maRect.TopLeft();      eKind=SdrHdlKind::UpperLeft; break;
        case 1: aPnt=maRect.TopCenter();    eKind=SdrHdlKind::Upper; break;
        case 2: aPnt=maRect.TopRight();     eKind=SdrHdlKind::UpperRight; break;
        case 3: aPnt=maRect.LeftCenter();   eKind=SdrHdlKind::Left ; break;
        case 4: aPnt=maRect.RightCenter();  eKind=SdrHdlKind::Right; break;
        case 5: aPnt=maRect.BottomLeft();   eKind=SdrHdlKind::LowerLeft; break;
        case 6: aPnt=maRect.BottomCenter(); eKind=SdrHdlKind::Lower; break;
        case 7: aPnt=maRect.BottomRight();  eKind=SdrHdlKind::LowerRight; break;
    }
    if (aGeo.nShearAngle!=0) ShearPoint(aPnt,maRect.TopLeft(),aGeo.nTan);
    if (aGeo.nRotationAngle!=0) RotatePoint(aPnt,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
    if (eKind!=SdrHdlKind::Move) {
    for(sal_uInt32 nHdlNum=0; nHdlNum<8; ++nHdlNum)
    {
        SdrHdl* pH=nullptr;
        Point aPnt;
        SdrHdlKind eKind = SdrHdlKind::UpperLeft;
        switch (nHdlNum) {
            case 0: aPnt=maRect.TopLeft();      eKind=SdrHdlKind::UpperLeft; break;
            case 1: aPnt=maRect.TopCenter();    eKind=SdrHdlKind::Upper; break;
            case 2: aPnt=maRect.TopRight();     eKind=SdrHdlKind::UpperRight; break;
            case 3: aPnt=maRect.LeftCenter();   eKind=SdrHdlKind::Left ; break;
            case 4: aPnt=maRect.RightCenter();  eKind=SdrHdlKind::Right; break;
            case 5: aPnt=maRect.BottomLeft();   eKind=SdrHdlKind::LowerLeft; break;
            case 6: aPnt=maRect.BottomCenter(); eKind=SdrHdlKind::Lower; break;
            case 7: aPnt=maRect.BottomRight();  eKind=SdrHdlKind::LowerRight; break;
        }
        if (aGeo.nShearAngle!=0) ShearPoint(aPnt,maRect.TopLeft(),aGeo.nTan);
        if (aGeo.nRotationAngle!=0) RotatePoint(aPnt,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
        pH=new SdrHdl(aPnt,eKind);
        pH->SetObj(const_cast<SdrTextObj*>(this));
        pH->SetRotationAngle(aGeo.nRotationAngle);
        rHdlList.AddHdl(pH);
    }
    return pH;
}


diff --git a/svx/source/svdraw/svdovirt.cxx b/svx/source/svdraw/svdovirt.cxx
index 698ac20..b625ae9 100644
--- a/svx/source/svdraw/svdovirt.cxx
+++ b/svx/source/svdraw/svdovirt.cxx
@@ -199,19 +199,17 @@ sal_uInt32 SdrVirtObj::GetHdlCount() const
    return rRefObj.GetHdlCount();
}

SdrHdl* SdrVirtObj::GetHdl(sal_uInt32 nHdlNum) const
void SdrVirtObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    SdrHdl* pHdl=rRefObj.GetHdl(nHdlNum);

    // #i73248#
    // GetHdl() at SdrObject is not guaranteed to return an object
    if(pHdl)
    SdrHdlList tempList(nullptr);
    rRefObj.AddToHdlList(tempList);
    for (size_t i=0; i<tempList.GetHdlCount(); ++i)
    {
        SdrHdl* pHdl = tempList.GetHdl(i);
        Point aP(pHdl->GetPos()+aAnchor);
        pHdl->SetPos(aP);
    }

    return pHdl;
    tempList.MoveTo(rHdlList);
}

sal_uInt32 SdrVirtObj::GetPlusHdlCount(const SdrHdl& rHdl) const
@@ -226,43 +224,6 @@ SdrHdl* SdrVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const
    return pHdl;
}

void SdrVirtObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    // #i73248#
    // SdrObject::AddToHdlList(rHdlList) is not a good thing to call
    // since at SdrPathObj, only AddToHdlList may be used and the call
    // will instead use the standard implementation which uses GetHdlCount()
    // and GetHdl instead. This is not wrong, but may be much less effective
    // and may not be prepared to GetHdl returning NULL

    // get handles using AddToHdlList from ref object
    SdrHdlList aLocalList(nullptr);
    rRefObj.AddToHdlList(aLocalList);
    const size_t nHdlCount(aLocalList.GetHdlCount());

    if(nHdlCount)
    {
        // translate handles and add them to dest list. They are temporarily part of
        // two lists then
        const Point aOffset(GetOffset());

        for(size_t a = 0; a < nHdlCount; ++a)
        {
            SdrHdl* pCandidate = aLocalList.GetHdl(a);
            pCandidate->SetPos(pCandidate->GetPos() + aOffset);
            rHdlList.AddHdl(pCandidate);
        }

        // remove them from source list, else they will be deleted when
        // source list is deleted
        while(aLocalList.GetHdlCount())
        {
            aLocalList.RemoveHdl(aLocalList.GetHdlCount() - 1);
        }
    }
}


bool SdrVirtObj::hasSpecialDrag() const
{
    return rRefObj.hasSpecialDrag();
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 53eaffa..b09160a 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -2187,29 +2187,6 @@ void SdrTableObj::AddToHdlList(SdrHdlList& rHdlList) const
        rHdlList.GetHdl(nHdl)->SetObj(const_cast<SdrTableObj*>(this));
}

SdrHdl* SdrTableObj::GetHdl(sal_uInt32 nHdlNum) const
{
    // #i73248#
    // Warn the user that this is ineffective and show alternatives. Should not be used at all.
    OSL_FAIL("SdrTableObj::GetHdl(): ineffective, use AddToHdlList instead (!)");

    // to have an alternative, get single handle using the ineffective way
    SdrHdl* pRetval = nullptr;
    SdrHdlList aLocalList(nullptr);
    AddToHdlList(aLocalList);
    const size_t nHdlCount(aLocalList.GetHdlCount());

    if(nHdlCount && static_cast<size_t>(nHdlNum) < nHdlCount)
    {
        // remove and remember. The other created handles will be deleted again with the
        // destruction of the local list
        pRetval = aLocalList.RemoveHdl(nHdlNum);
    }

    return pRetval;
}


// Dragging

bool SdrTableObj::hasSpecialDrag() const
diff --git a/sw/inc/dcontact.hxx b/sw/inc/dcontact.hxx
index ea0261c..4d3a48f 100644
--- a/sw/inc/dcontact.hxx
+++ b/sw/inc/dcontact.hxx
@@ -263,7 +263,7 @@ class SwDrawVirtObj : public SdrVirtObj
        virtual void RecalcBoundRect() override;
        virtual ::basegfx::B2DPolyPolygon TakeXorPoly() const override;
        virtual ::basegfx::B2DPolyPolygon TakeContour() const override;
        virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override;
        virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
        virtual void NbcMove(const Size& rSiz) override;
        virtual void NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) override;
        virtual void NbcRotate(const Point& rRef, long nAngle, double sn, double cs) override;
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 286b6dd..df8958a 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -412,10 +412,12 @@ void SwTiledRenderingTest::testSetGraphicSelection()
    SdrPage* pPage = pWrtShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
    SdrObject* pObject = pPage->GetObj(0);
    pWrtShell->SelectObj(Point(), 0, pObject);
    SdrHdlList handleList(nullptr);
    pObject->AddToHdlList(handleList);
    // Make sure the rectangle has 8 handles: at each corner and at the center of each edge.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(8), pObject->GetHdlCount());
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(8), handleList.GetHdlCount());
    // Take the bottom center one.
    SdrHdl* pHdl = pObject->GetHdl(6);
    SdrHdl* pHdl = handleList.GetHdl(6);
    CPPUNIT_ASSERT_EQUAL(int(SdrHdlKind::Lower), static_cast<int>(pHdl->GetKind()));
    tools::Rectangle aShapeBefore = pObject->GetSnapRect();
    // Resize.
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
index c3bb4ae..2f5da1b 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -2339,21 +2339,19 @@ basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const
    return aRetval;
}

SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const
void SwDrawVirtObj::AddToHdlList(SdrHdlList& rHdlList) const
{
    SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum);
    SdrHdlList tmpList(nullptr);
    rRefObj.AddToHdlList(tmpList);

    if(pHdl)
    size_t cnt = tmpList.GetHdlCount();
    for(size_t i=0; i < cnt; ++i)
    {
        SdrHdl* pHdl = tmpList.GetHdl(i);
        Point aP(pHdl->GetPos() + GetOffset());
        pHdl->SetPos(aP);
    }
    else
    {
        OSL_ENSURE(false, "Got no SdrHdl(!)");
    }

    return pHdl;
    tmpList.MoveTo(rHdlList);
}

void SwDrawVirtObj::NbcMove(const Size& rSiz)