sw: fix SolarMutex asserts from SwXCellRange dtor

Happened when loading a report from the attachment of tdf#97033,
but that bug is apparently about a different crash.

Deploy the sw::UnoImplPtr, which is clearly the best way to avoid such
problems.  Also another silly weak pointer this, for tdf#72695.

Change-Id: Ice8db95ca3eecc638bd4a4ef7fa8967d180bd525
diff --git a/sw/inc/unotbl.hxx b/sw/inc/unotbl.hxx
index f79598e..ef5c42b 100644
--- a/sw/inc/unotbl.hxx
+++ b/sw/inc/unotbl.hxx
@@ -33,7 +33,6 @@
#include <com/sun/star/table/XAutoFormattable.hpp>

#include <cppuhelper/implbase.hxx>
#include <comphelper/interfacecontainer2.hxx>

#include <comphelper/uno3.hxx>

@@ -447,28 +446,31 @@ class SwXCellRange : public cppu::WeakImplHelper
    css::chart::XChartDataArray,
    css::util::XSortable,
    css::sheet::XCellRangeData
>,
    public SwClient
>
{
    ::osl::Mutex m_Mutex;
    ::comphelper::OInterfaceContainerHelper2 m_ChartListeners;
private:
    class Impl;
    ::sw::UnoImplPtr<Impl> m_pImpl;

    SwRangeDescriptor           aRgDesc;
    const SfxItemPropertySet*   m_pPropSet;

    sw::UnoCursorPointer m_pTableCursor;

    bool m_bFirstRowAsLabel;
    bool m_bFirstColumnAsLabel;
    std::tuple<sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32> getLabelCoordinates(bool bRow);
    css::uno::Sequence<OUString> getLabelDescriptions(bool bRow);
    void setLabelDescriptions(const css::uno::Sequence<OUString>& rDesc, bool bRow);

public:
    SwXCellRange(sw::UnoCursorPointer pCursor, SwFrameFormat& rFrameFormat, SwRangeDescriptor& rDesc);
    virtual ~SwXCellRange();

public:
    static ::rtl::Reference<SwXCellRange> CreateXCellRange(
            sw::UnoCursorPointer pCursor, SwFrameFormat& rFrameFormat,
            SwRangeDescriptor& rDesc);

    void SetLabels(bool bFirstRowAsLabel, bool bFirstColumnAsLabel)
        { m_bFirstRowAsLabel = bFirstRowAsLabel, m_bFirstColumnAsLabel = bFirstColumnAsLabel; }
    virtual ~SwXCellRange() {};
    std::vector< css::uno::Reference< css::table::XCell > > GetCells();


@@ -533,10 +535,6 @@ public:
    virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw( css::uno::RuntimeException, std::exception ) override;
    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( css::uno::RuntimeException, std::exception ) override;

    //SwClient
    virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew) override;

    SwFrameFormat*   GetFrameFormat() const { return const_cast<SwFrameFormat*>(static_cast<const SwFrameFormat*>(GetRegisteredIn())); }
    sal_uInt16      getRowCount();
    sal_uInt16      getColumnCount();

diff --git a/sw/source/core/unocore/unochart.cxx b/sw/source/core/unocore/unochart.cxx
index a22b4da..bb13239 100644
--- a/sw/source/core/unocore/unochart.cxx
+++ b/sw/source/core/unocore/unochart.cxx
@@ -2146,7 +2146,7 @@ std::vector< css::uno::Reference< css::table::XCell > > SwChartDataSequence::Get
    SwRangeDescriptor aDesc;
    if(!FillRangeDescriptor(aDesc, GetCellRangeName(*pTableFormat, *m_pTableCursor)))
        return std::vector< css::uno::Reference< css::table::XCell > >();
    return SwXCellRange(m_pTableCursor, *pTableFormat, aDesc).GetCells();
    return SwXCellRange::CreateXCellRange(m_pTableCursor, *pTableFormat, aDesc)->GetCells();
}

uno::Sequence< OUString > SAL_CALL SwChartDataSequence::getTextualData()
diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx
index e20b35b..29d1b14 100644
--- a/sw/source/core/unocore/unotbl.cxx
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -99,6 +99,7 @@
#include <rtl/math.hxx>
#include <editeng/frmdiritem.hxx>
#include <calbck.hxx>
#include <comphelper/interfacecontainer2.hxx>
#include <comphelper/servicehelper.hxx>
#include <comphelper/string.hxx>
#include <cppuhelper/supportsservice.hxx>
@@ -151,14 +152,14 @@ static void lcl_SendChartEvent(::cppu::OWeakObject & rSource,
            & chart::XChartDataChangeEventListener::chartDataChanged, event);
}

static void lcl_SendChartEvent(::cppu::OWeakObject & rSource,
static void lcl_SendChartEvent(uno::Reference<uno::XInterface> const& xSource,
                               ::comphelper::OInterfaceContainerHelper2 & rListeners)
{
    if (!rListeners.getLength())
        return;
    //TODO: find appropriate settings of the Event
    chart::ChartDataChangeEvent event;
    event.Source = & rSource;
    event.Source = xSource;
    event.Type = chart::ChartDataChangeType_ALL;
    event.StartColumn = 0;
    event.EndColumn = 1;
@@ -169,6 +170,12 @@ static void lcl_SendChartEvent(::cppu::OWeakObject & rSource,
}

static void lcl_SendChartEvent(::cppu::OWeakObject & rSource,
                               ::comphelper::OInterfaceContainerHelper2 & rListeners)
{
    return lcl_SendChartEvent(&rSource, rListeners);
}

static void lcl_SendChartEvent(::cppu::OWeakObject & rSource,
                               ::cppu::OMultiTypeInterfaceContainerHelper & rListeners)
{
    ::cppu::OInterfaceContainerHelper *const pContainer(rListeners.getContainer(
@@ -2255,7 +2262,7 @@ uno::Reference<table::XCellRange>  SwXTextTable::GetRangeByName(SwFrameFormat* p
    UnoActionRemoveContext aRemoveContext(*pCursor);
    pCursor->MakeBoxSels();
    // pUnoCursor will be provided and will not be deleted
    return new SwXCellRange(pUnoCursor, *pFormat, rDesc);
    return SwXCellRange::CreateXCellRange(pUnoCursor, *pFormat, rDesc).get();
}

uno::Reference<table::XCellRange>  SwXTextTable::getCellRangeByPosition(sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom)
@@ -3137,6 +3144,36 @@ uno::Sequence<OUString> SwXTextTable::getSupportedServiceNames() throw(uno::Runt
        "com.sun.star.text.TextSortable" };
}


class SwXCellRange::Impl
    : public SwClient
{
private:
    ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2

public:
    uno::WeakReference<uno::XInterface> m_wThis;
    ::comphelper::OInterfaceContainerHelper2 m_ChartListeners;

    sw::UnoCursorPointer m_pTableCursor;

    Impl(sw::UnoCursorPointer const pCursor, SwFrameFormat& rFrameFormat)
        : SwClient(&rFrameFormat)
        , m_ChartListeners(m_Mutex)
        , m_pTableCursor(pCursor)
    {
    }

    SwFrameFormat* GetFrameFormat()
    {
        return static_cast<SwFrameFormat*>(GetRegisteredIn());
    }

    // SwClient
    virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) override;

};

namespace
{
    class theSwXCellRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXCellRangeUnoTunnelId > {};
@@ -3180,20 +3217,33 @@ uno::Sequence<OUString> SwXCellRange::getSupportedServiceNames() throw( uno::Run

SwXCellRange::SwXCellRange(sw::UnoCursorPointer pCursor, SwFrameFormat& rFrameFormat,
    SwRangeDescriptor& rDesc)
    : SwClient(&rFrameFormat)
    , m_ChartListeners(m_Mutex)
    : m_pImpl(new Impl(pCursor, rFrameFormat))
    , aRgDesc(rDesc)
    , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_RANGE))
    , m_pTableCursor(pCursor)
    , m_bFirstRowAsLabel(false)
    , m_bFirstColumnAsLabel(false)
{
    aRgDesc.Normalize();
}

SwXCellRange::~SwXCellRange()
{
}

rtl::Reference<SwXCellRange> SwXCellRange::CreateXCellRange(
        sw::UnoCursorPointer const pCursor, SwFrameFormat& rFrameFormat,
        SwRangeDescriptor& rDesc)
{
    SwXCellRange *const pCellRange(new SwXCellRange(pCursor, rFrameFormat, rDesc));
    uno::Reference<table::XCellRange> xCellRange(pCellRange);
    // need a permanent Reference to initialize m_wThis
    pCellRange->m_pImpl->m_wThis = xCellRange;
    return pCellRange;
}

std::vector< uno::Reference< table::XCell > > SwXCellRange::GetCells()
{
    SwFrameFormat* const pFormat = GetFrameFormat();
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    const sal_Int32 nRowCount(getRowCount());
    const sal_Int32 nColCount(getColumnCount());
    std::vector< uno::Reference< table::XCell > > vResult;
@@ -3209,7 +3259,7 @@ uno::Reference< table::XCell >  SwXCellRange::getCellByPosition(sal_Int32 nColum
{
    SolarMutexGuard aGuard;
    uno::Reference< table::XCell >  aRet;
    SwFrameFormat* pFormat = GetFrameFormat();
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    if(pFormat)
    {
        if(nColumn >= 0 && nRow >= 0 &&
@@ -3233,7 +3283,7 @@ uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByPosition(
{
    SolarMutexGuard aGuard;
    uno::Reference< table::XCellRange >  aRet;
    SwFrameFormat* pFormat = GetFrameFormat();
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    if(pFormat && getColumnCount() > nRight && getRowCount() > nBottom &&
        nLeft <= nRight && nTop <= nBottom
        && nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
@@ -3269,8 +3319,7 @@ uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByPosition(
                    UnoActionRemoveContext aRemoveContext(*pCursor);
                    pCursor->MakeBoxSels();
                    // pUnoCursor will be provided and will not be deleted
                    SwXCellRange* pCellRange = new SwXCellRange(pUnoCursor, *pFormat, aNewDesc);
                    aRet = pCellRange;
                    aRet = SwXCellRange::CreateXCellRange(pUnoCursor, *pFormat, aNewDesc).get();
                }
            }
        }
@@ -3313,7 +3362,7 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
           std::exception)
{
    SolarMutexGuard aGuard;
    SwFrameFormat* pFormat = GetFrameFormat();
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    if(pFormat)
    {
        const SfxItemPropertySimpleEntry* pEntry =
@@ -3323,8 +3372,8 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
            if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
                throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );

            SwDoc* pDoc = m_pTableCursor->GetDoc();
            SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*m_pTableCursor);
            SwDoc *const pDoc = m_pImpl->m_pTableCursor->GetDoc();
            SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*m_pImpl->m_pTableCursor);
            {
                // HACK: remove pending actions for selecting old style tables
                UnoActionRemoveContext aRemoveContext(rCursor);
@@ -3335,9 +3384,9 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
                case FN_UNO_TABLE_CELL_BACKGROUND:
                {
                    SvxBrushItem aBrush( RES_BACKGROUND );
                    SwDoc::GetBoxAttr( *m_pTableCursor, aBrush );
                    SwDoc::GetBoxAttr(*m_pImpl->m_pTableCursor, aBrush);
                    ((SfxPoolItem&)aBrush).PutValue(aValue, pEntry->nMemberId);
                    pDoc->SetBoxAttr( *m_pTableCursor, aBrush );
                    pDoc->SetBoxAttr(*m_pImpl->m_pTableCursor, aBrush);

                }
                break;
@@ -3372,7 +3421,7 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
                    SvxBoxItem aBoxItem(static_cast<const SvxBoxItem&>(aSet.Get(RES_BOX)));
                    ((SfxPoolItem&)aBoxItem).PutValue(aValue, pEntry->nMemberId);
                    aSet.Put(aBoxItem);
                    pDoc->SetTabBorders( *m_pTableCursor, aSet );
                    pDoc->SetTabBorders(*m_pImpl->m_pTableCursor, aSet);
                }
                break;
                case RES_BOXATR_FORMAT:
@@ -3387,7 +3436,7 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
                    bool bTmp = *static_cast<sal_Bool const *>(aValue.getValue());
                    if(m_bFirstRowAsLabel != bTmp)
                    {
                        lcl_SendChartEvent(*this, m_ChartListeners);
                        lcl_SendChartEvent(*this, m_pImpl->m_ChartListeners);
                        m_bFirstRowAsLabel = bTmp;
                    }
                }
@@ -3397,7 +3446,7 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
                    bool bTmp = *static_cast<sal_Bool const *>(aValue.getValue());
                    if(m_bFirstColumnAsLabel != bTmp)
                    {
                        lcl_SendChartEvent(*this, m_ChartListeners);
                        lcl_SendChartEvent(*this, m_pImpl->m_ChartListeners);
                        m_bFirstColumnAsLabel = bTmp;
                    }
                }
@@ -3439,7 +3488,7 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
{
    SolarMutexGuard aGuard;
    uno::Any aRet;
    SwFrameFormat* pFormat = GetFrameFormat();
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    if(pFormat)
    {
        const SfxItemPropertySimpleEntry* pEntry =
@@ -3451,20 +3500,20 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
                case FN_UNO_TABLE_CELL_BACKGROUND:
                {
                    SvxBrushItem aBrush( RES_BACKGROUND );
                    if(SwDoc::GetBoxAttr( *m_pTableCursor, aBrush ))
                    if (SwDoc::GetBoxAttr(*m_pImpl->m_pTableCursor, aBrush))
                        aBrush.QueryValue(aRet, pEntry->nMemberId);

                }
                break;
                case RES_BOX :
                {
                    SwDoc* pDoc = m_pTableCursor->GetDoc();
                    SwDoc *const pDoc = m_pImpl->m_pTableCursor->GetDoc();
                    SfxItemSet aSet(pDoc->GetAttrPool(),
                                    RES_BOX, RES_BOX,
                                    SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
                                    0);
                    aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
                    SwDoc::GetTabBorders(*m_pTableCursor, aSet);
                    SwDoc::GetTabBorders(*m_pImpl->m_pTableCursor, aSet);
                    const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(aSet.Get(RES_BOX));
                    rBoxItem.QueryValue(aRet, pEntry->nMemberId);
                }
@@ -3475,7 +3524,7 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
                case FN_UNO_PARA_STYLE:
                {
                    SwFormatColl *const pTmpFormat =
                        SwUnoCursorHelper::GetCurTextFormatColl(*m_pTableCursor, false);
                        SwUnoCursorHelper::GetCurTextFormatColl(*m_pImpl->m_pTableCursor, false);
                    OUString sRet;
                    if(pFormat)
                        sRet = pTmpFormat->GetName();
@@ -3491,7 +3540,7 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
                case RES_VERT_ORIENT:
                {
                    SwFormatVertOrient aVertOrient;
                    if( SwDoc::GetBoxAttr( *m_pTableCursor, aVertOrient ) )
                    if (SwDoc::GetBoxAttr(*m_pImpl->m_pTableCursor, aVertOrient))
                    {
                        aVertOrient.QueryValue( aRet, pEntry->nMemberId );
                    }
@@ -3499,13 +3548,14 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
                break;
                default:
                {
                    SfxItemSet aSet(m_pTableCursor->GetDoc()->GetAttrPool(),
                    SfxItemSet aSet(m_pImpl->m_pTableCursor->GetDoc()->GetAttrPool(),
                        RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
                        RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
                        RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
                        0L);
                    // first look at the attributes of the cursor
                    SwUnoTableCursor* pCursor = dynamic_cast<SwUnoTableCursor*>(&(*m_pTableCursor));
                    SwUnoTableCursor *const pCursor =
                        dynamic_cast<SwUnoTableCursor*>(&(*m_pImpl->m_pTableCursor));
                    SwUnoCursorHelper::GetCursorAttr(pCursor->GetSelRing(), aSet);
                    m_pPropSet->getPropertyValue(*pEntry, aSet, aRet);
                }
@@ -3538,7 +3588,7 @@ uno::Sequence< uno::Sequence< uno::Any > > SAL_CALL SwXCellRange::getDataArray()
    const sal_Int32 nColCount = getColumnCount();
    if(!nRowCount || !nColCount)
        throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
    lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    lcl_EnsureCoreConnected(m_pImpl->GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    uno::Sequence< uno::Sequence< uno::Any > > aRowSeq(nRowCount);
    auto vCells(GetCells());
    auto pCurrentCell(vCells.begin());
@@ -3565,7 +3615,7 @@ void SAL_CALL SwXCellRange::setDataArray(const uno::Sequence< uno::Sequence< uno
    const sal_Int32 nColCount = getColumnCount();
    if(!nRowCount || !nColCount)
        throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
    SwFrameFormat* pFormat = GetFrameFormat();
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    if(!pFormat)
        return;
    if(rArray.getLength() != nRowCount)
@@ -3634,7 +3684,7 @@ void SwXCellRange::setData(const uno::Sequence< uno::Sequence< double > >& rData
            nColCount-1, nRowCount-1), uno::UNO_QUERY);
        return xDataRange->setData(rData);
    }
    lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    lcl_EnsureCoreConnected(m_pImpl->GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    if(rData.getLength() != nRowCount)
        throw uno::RuntimeException("Row count mismatch. expected: " + OUString::number(nRowCount) + " got: " + OUString::number(rData.getLength()), static_cast<cppu::OWeakObject*>(this));
    auto vCells(GetCells());
@@ -3675,7 +3725,7 @@ uno::Sequence<OUString> SwXCellRange::getLabelDescriptions(bool bRow)
    std::tie(nLeft, nTop, nRight, nBottom) = getLabelCoordinates(bRow);
    if(!nRight && !nBottom)
        throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
    lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    lcl_EnsureCoreConnected(m_pImpl->GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    if(!(bRow ? m_bFirstColumnAsLabel : m_bFirstRowAsLabel))
        return {};  // without labels we have no descriptions
    auto xLabelRange(getCellRangeByPosition(nLeft, nTop, nRight, nBottom));
@@ -3697,7 +3747,7 @@ uno::Sequence<OUString> SwXCellRange::getColumnDescriptions()
void SwXCellRange::setLabelDescriptions(const uno::Sequence<OUString>& rDesc, bool bRow)
{
    SolarMutexGuard aGuard;
    lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    lcl_EnsureCoreConnected(m_pImpl->GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
    if(!(bRow ? m_bFirstColumnAsLabel : m_bFirstRowAsLabel))
        return; // if there are no labels we cannot set descriptions
    sal_uInt32 nLeft, nTop, nRight, nBottom;
@@ -3725,7 +3775,7 @@ void SAL_CALL SwXCellRange::addChartDataChangeEventListener(
throw (uno::RuntimeException, std::exception)
{
    // no need to lock here as m_pImpl is const and container threadsafe
    m_ChartListeners.addInterface(xListener);
    m_pImpl->m_ChartListeners.addInterface(xListener);
}

void SAL_CALL SwXCellRange::removeChartDataChangeEventListener(
@@ -3733,7 +3783,7 @@ void SAL_CALL SwXCellRange::removeChartDataChangeEventListener(
throw (uno::RuntimeException, std::exception)
{
    // no need to lock here as m_pImpl is const and container threadsafe
    m_ChartListeners.removeInterface(xListener);
    m_pImpl->m_ChartListeners.removeInterface(xListener);
}

sal_Bool SwXCellRange::isNotANumber(double /*fNumber*/) throw( uno::RuntimeException, std::exception )
@@ -3754,10 +3804,10 @@ void SAL_CALL SwXCellRange::sort(const uno::Sequence< beans::PropertyValue >& rD
{
    SolarMutexGuard aGuard;
    SwSortOptions aSortOpt;
    SwFrameFormat* pFormat(GetFrameFormat());
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    if(pFormat && SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
    {
        SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(*m_pTableCursor);
        SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(*m_pImpl->m_pTableCursor);
        rTableCursor.MakeBoxSels();
        UnoActionContext aContext(pFormat->GetDoc());
        pFormat->GetDoc()->SortTable(rTableCursor.GetSelectedBoxes(), aSortOpt);
@@ -3772,22 +3822,28 @@ sal_uInt16 SwXCellRange::getRowCount()

const SwUnoCursor* SwXCellRange::GetTableCursor() const
{
    SwFrameFormat* pFormat = GetFrameFormat();
    return pFormat ? &(*m_pTableCursor) : nullptr;
    SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
    return pFormat ? &(*m_pImpl->m_pTableCursor) : nullptr;
}

void SwXCellRange::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
void SwXCellRange::Impl::Modify(
        SfxPoolItem const*const pOld, SfxPoolItem const*const pNew)
{
    ClientModify(this, pOld, pNew );
    ClientModify(this, pOld, pNew);
    uno::Reference<uno::XInterface> const xThis(m_wThis);
    if (!xThis.is())
    {   // fdo#72695: if UNO object is already dead, don't revive it with event
        return;
    }
    if(!GetRegisteredIn() || !m_pTableCursor)
    {
        m_pTableCursor.reset(nullptr);
        lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(*this));
        lang::EventObject const ev(xThis);
        m_ChartListeners.disposeAndClear(ev);
    }
    else
    {
        lcl_SendChartEvent(*this, m_ChartListeners);
        lcl_SendChartEvent(xThis.get(), m_ChartListeners);
    }
}