tdf#125164 sw: reimplement SwUndoTOXChange

SwUndoTOXChange was effectively dead code since commit
60732d715698108f9c3a8284bb3e00baaa4e8124 "#i42807# clear undo stack
before changing of TOX properties, update TOX after changing properties"
and was resurrected by commit 4f0b568ef35353b276ae560fb43502b6f6b2bfdb.

* Calling Update() from Undo is wrong, as there is no guarantee that
  the index was up-to-date before the change
* Calling Update() from Redo is pointless, as there will be a Redo
  of SwUndoUpdateIndex anyway, given that the only caller of
  ChangeTOX, namely, SwTOXMgr::UpdateOrInsertTOX(), does that
* SwUndoTOXChange cannot retain a pointer to SwTOXBase as its life-time
  is tied to the SwSectionNode
* Repeat applying the same attributes to the same ToX is utterly
  pointless

Change-Id: I84a9de3176d1062d1a43acbc9270c547fde7936a
Reviewed-on: https://gerrit.libreoffice.org/72118
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index fd8ab6c..1e78ee0 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1559,7 +1559,7 @@ public:
                   bool bBroadcast = false);

    // Change a TOX undoable.
    void ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew, SwRootFrame const& rLayout);
    void ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew);

    /**
       Returns a textual description of a PaM.
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index cee2e77..2da307c 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -1728,22 +1728,20 @@ void SwDoc::AppendUndoForInsertFromDB( const SwPaM& rPam, bool bIsTable )
    }
}

void SwDoc::ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew,
        SwRootFrame const& rLayout)
void SwDoc::ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew)
{
    assert(dynamic_cast<const SwTOXBaseSection*>(&rTOX));
    SwTOXBaseSection& rTOXSect(static_cast<SwTOXBaseSection&>(rTOX));

    if (GetIDocumentUndoRedo().DoesUndo())
    {
        GetIDocumentUndoRedo().AppendUndo(
            std::make_unique<SwUndoTOXChange>(this, &rTOX, rNew));
            std::make_unique<SwUndoTOXChange>(this, rTOXSect, rNew));
    }

    rTOX = rNew;

    if (dynamic_cast<const SwTOXBaseSection*>( &rTOX) !=  nullptr)
    {
        static_cast<SwTOXBaseSection &>(rTOX).Update(nullptr, &rLayout);
        static_cast<SwTOXBaseSection &>(rTOX).UpdatePageNum();
    }
    // note: do not Update the ToX here - the caller will do it, with a ViewShell!
}

OUString SwDoc::GetPaMDescr(const SwPaM & rPam)
diff --git a/sw/source/core/inc/SwUndoTOXChange.hxx b/sw/source/core/inc/SwUndoTOXChange.hxx
index d78b17e..a593bfd 100644
--- a/sw/source/core/inc/SwUndoTOXChange.hxx
+++ b/sw/source/core/inc/SwUndoTOXChange.hxx
@@ -24,16 +24,18 @@
#include <tox.hxx>

class SwDoc;
class SwTOXBaseSection;

class SwUndoTOXChange : public SwUndo
{
    SwTOXBase * pTOX, aOld, aNew;
private:
    SwTOXBase m_Old;
    SwTOXBase m_New;

    void UpdateTOXBaseSection();
    void DoImpl();
    sal_uLong const m_nNodeIndex;

public:
    SwUndoTOXChange(const SwDoc* pDoc, SwTOXBase * pTOX, const SwTOXBase & rNew);
    SwUndoTOXChange(const SwDoc* pDoc, SwTOXBaseSection const& rTOX, const SwTOXBase & rNew);
    virtual ~SwUndoTOXChange() override;

    virtual void UndoImpl( ::sw::UndoRedoContext & ) override;
diff --git a/sw/source/core/undo/SwUndoTOXChange.cxx b/sw/source/core/undo/SwUndoTOXChange.cxx
index 5b69ab9..4296aa2 100644
--- a/sw/source/core/undo/SwUndoTOXChange.cxx
+++ b/sw/source/core/undo/SwUndoTOXChange.cxx
@@ -19,10 +19,17 @@

#include <SwUndoTOXChange.hxx>
#include <swundo.hxx>
#include <UndoCore.hxx>
#include <doctxm.hxx>
#include <doc.hxx>
#include <node.hxx>

SwUndoTOXChange::SwUndoTOXChange(const SwDoc *pDoc, SwTOXBase * _pTOX, const SwTOXBase & rNew)
    : SwUndo(SwUndoId::TOXCHANGE, pDoc), pTOX(_pTOX), aOld(*_pTOX), aNew(rNew)
SwUndoTOXChange::SwUndoTOXChange(const SwDoc *pDoc,
        SwTOXBaseSection const& rTOX, SwTOXBase const& rNew)
    : SwUndo(SwUndoId::TOXCHANGE, pDoc)
    , m_Old(rTOX)
    , m_New(rNew)
    , m_nNodeIndex(rTOX.GetFormat()->GetSectionNode()->GetIndex())
{
}

@@ -30,38 +37,39 @@ SwUndoTOXChange::~SwUndoTOXChange()
{
}

void SwUndoTOXChange::UpdateTOXBaseSection()
// get the current ToXBase, which is not necessarily the same instance that existed there before
static SwTOXBase & GetTOX(SwDoc & rDoc, sal_uLong const nNodeIndex)
{
    if ( dynamic_cast< const SwTOXBaseSection *>( pTOX ) != nullptr )
    SwSectionNode *const pNode(rDoc.GetNodes()[nNodeIndex]->GetSectionNode());
    assert(pNode);
    assert(dynamic_cast<SwTOXBaseSection*>(&pNode->GetSection()));
    auto & rTOX(static_cast<SwTOXBaseSection&>(pNode->GetSection()));
    return rTOX;
}

void SwUndoTOXChange::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc(rContext.GetDoc());
    SwTOXBase & rTOX(GetTOX(rDoc, m_nNodeIndex));
    rTOX = m_Old;
}

void SwUndoTOXChange::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc(rContext.GetDoc());
    SwTOXBase & rTOX(GetTOX(rDoc, m_nNodeIndex));
    rTOX = m_New;
}

void SwUndoTOXChange::RepeatImpl(::sw::RepeatContext & rContext)
{
    SwDoc & rDoc(rContext.GetDoc());
    SwTOXBase *const pTOX(SwDoc::GetCurTOX(*rContext.GetRepeatPaM().GetPoint()));
    if (pTOX)
    {
        SwTOXBaseSection * pTOXBase = static_cast<SwTOXBaseSection *>(pTOX);
        pTOXBase->Update();
        pTOXBase->UpdatePageNum();
        rDoc.ChangeTOX(*pTOX, m_New);
        // intentionally limited to not Update because we'd need layout
    }
}

void SwUndoTOXChange::UndoImpl(::sw::UndoRedoContext &)
{
    *pTOX = aOld;

    UpdateTOXBaseSection();
}

void SwUndoTOXChange::DoImpl()
{
    *pTOX = aNew;

    UpdateTOXBaseSection();
}

void SwUndoTOXChange::RedoImpl(::sw::UndoRedoContext &)
{
    DoImpl();
}

void SwUndoTOXChange::RepeatImpl(::sw::RepeatContext &)
{
    DoImpl();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/index/toxmgr.cxx b/sw/source/uibase/index/toxmgr.cxx
index d2ed262..0c594c5 100644
--- a/sw/source/uibase/index/toxmgr.cxx
+++ b/sw/source/uibase/index/toxmgr.cxx
@@ -439,7 +439,7 @@ bool SwTOXMgr::UpdateOrInsertTOX(const SwTOXDescription& rDesc,
            pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::TOXCHANGE, nullptr);
        }

        pDoc->ChangeTOX(*pTOX, *pNewTOX, *pSh->GetLayout());
        pDoc->ChangeTOX(*pTOX, *pNewTOX);

        pTOX->DisableKeepExpression();
        pSh->UpdateTableOf(*pTOX, pSet);