Refactor SwFormatDrop

... and get rid of the SwClientNotifyCall.

Change-Id: I2118290944c21e9773c359109e60e7778459a41f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106365
Tested-by: Jenkins
Reviewed-by: Bjoern Michaelsen <bjoern.michaelsen@libreoffice.org>
diff --git a/sw/inc/fmtcol.hxx b/sw/inc/fmtcol.hxx
index 20b5409..07f157f 100644
--- a/sw/inc/fmtcol.hxx
+++ b/sw/inc/fmtcol.hxx
@@ -22,6 +22,7 @@
#include "swdllapi.h"
#include "format.hxx"
#include "hintids.hxx"
#include "paratr.hxx"
#include <rtl/ustring.hxx>
#include <tools/solar.h>

@@ -31,7 +32,7 @@
class SwAttrPool;
namespace sw{ class DocumentStylePoolManager; }

class SAL_DLLPUBLIC_RTTI SwFormatColl : public SwFormat
class SAL_DLLPUBLIC_RTTI SwFormatColl: public SwFormat
{
protected:
    SwFormatColl( SwAttrPool& rPool, const char* pFormatName,
@@ -52,7 +53,9 @@ private:
};

/// Represents the style of a paragraph.
class SW_DLLPUBLIC SwTextFormatColl: public SwFormatColl
class SW_DLLPUBLIC SwTextFormatColl
    : public SwFormatColl
    , public sw::FormatDropDefiner
{
    friend class SwDoc;
    friend class ::sw::DocumentStylePoolManager;
@@ -66,7 +69,6 @@ class SW_DLLPUBLIC SwTextFormatColl: public SwFormatColl
    SwTextFormatColl *mpNextTextFormatColl;

protected:

    SwTextFormatColl( SwAttrPool& rPool, const char* pFormatCollName,
                    SwTextFormatColl* pDerFrom = nullptr,
                    sal_uInt16 nFormatWh = RES_TXTFMTCOLL )
@@ -91,8 +93,6 @@ protected:
    virtual void SwClientNotify(const SwModify&, const SfxHint&) override;

public:


    inline void SetNextTextFormatColl(SwTextFormatColl& rNext);
    SwTextFormatColl& GetNextTextFormatColl() const { return *mpNextTextFormatColl; }

@@ -133,6 +133,11 @@ public:
    bool AreListLevelIndentsApplicable() const;

    void dumpAsXml(xmlTextWriterPtr pWriter) const;
    virtual void FormatDropNotify(const SwFormatDrop& rDrop) override
    {
        if(HasWriterListeners() && !IsModifyLocked())
            CallSwClientNotify(sw::LegacyModifyHint(&rDrop, &rDrop));
    };
};

class SwGrfFormatColl final : public SwFormatColl
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 1906496..5733a5f2 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -22,12 +22,13 @@
#include <cppuhelper/weakref.hxx>

#include "swdllapi.h"
#include "node.hxx"
#include "hintids.hxx"
#include "ndhints.hxx"
#include "SwNumberTreeTypes.hxx"
#include "IDocumentContentOperations.hxx"
#include "SwNumberTreeTypes.hxx"
#include "hintids.hxx"
#include "modeltoviewhelper.hxx"
#include "ndhints.hxx"
#include "node.hxx"
#include "paratr.hxx"

#include <sfx2/Metadatable.hxx>
#include <o3tl/sorted_vector.hxx>
@@ -79,6 +80,7 @@ typedef o3tl::sorted_vector< sal_Int32 > SwSoftPageBreakList;
class SW_DLLPUBLIC SwTextNode
    : public SwContentNode
    , public ::sfx2::Metadatable
    , public sw::FormatDropDefiner
{
    friend class SwContentNode;
    /// For creating the first TextNode.
@@ -805,6 +807,8 @@ public:

    /// In MS Word, the font underline setting of the paragraph end position won't affect the formatting of numbering, so we ignore it
    static bool IsIgnoredCharFormatForNumbering(const sal_uInt16 nWhich);
    void FormatDropNotify(const SwFormatDrop& rDrop) override
            { TriggerNodeUpdate(sw::LegacyModifyHint(&rDrop, &rDrop)); };
};

inline SwpHints & SwTextNode::GetSwpHints()
diff --git a/sw/inc/paratr.hxx b/sw/inc/paratr.hxx
index 1c6bcf4..d971202 100644
--- a/sw/inc/paratr.hxx
+++ b/sw/inc/paratr.hxx
@@ -39,18 +39,29 @@
#include <editeng/paravertalignitem.hxx>
#include <editeng/pgrditem.hxx>

class SwTextNode;
class IntlWrapper;

#define DROP_WHOLEWORD ((sal_uInt16)0x0001)

class SwFormatDrop;

namespace sw {
    class SW_DLLPUBLIC FormatDropDefiner {
        protected:
            virtual ~FormatDropDefiner() {};
        public:
            virtual void FormatDropNotify(const SwFormatDrop&) =0;
    };
}

/** If SwFormatDrop is a Client, it is the CharFormat that describes the font for the
   DropCaps. If it is not a Client, formatting uses the CharFormat of the paragraph.
   If the CharFormat is modified, this change is propagated to the paragraphs
   via the Modify of SwFormatDrop. */
class SW_DLLPUBLIC SwFormatDrop: public SfxPoolItem, public SwClient
{
    sw::BroadcastingModify* m_pDefinedIn;       /**< Modify-Object, that contains DropCaps.
                                  Can only be TextFormatCollection/TextNode. */
    sw::FormatDropDefiner* m_pDefinedIn;  ///< TextNode or FormatColl that contains the CapDrops.
    sal_uInt16 m_nDistance;       ///< Distance to beginning of text.
    sal_uInt8  m_nLines;          ///< Line count.
    sal_uInt8  m_nChars;          ///< Character count.
@@ -68,7 +79,8 @@ private:
    SwFormatDrop & operator= (const SwFormatDrop &) = delete;

protected:
    virtual void SwClientNotify(const SwModify&, const SfxHint&) override;
    virtual void SwClientNotify(const SwModify&, const SfxHint&) override
        { m_pDefinedIn->FormatDropNotify(*this); };

public:

@@ -102,9 +114,10 @@ public:
    virtual bool GetInfo( SfxPoolItem& ) const override;

    /// Get and set Modify pointer.
    const sw::BroadcastingModify* GetDefinedIn() const { return m_pDefinedIn; }
    void ChgDefinedIn( const sw::BroadcastingModify* pNew )
    { m_pDefinedIn = const_cast<sw::BroadcastingModify*>(pNew); }
    const sw::FormatDropDefiner* GetDefinedIn() const
            { return m_pDefinedIn; };
    void ChgDefinedIn( const sw::FormatDropDefiner* pDefiner )
            { m_pDefinedIn = const_cast<sw::FormatDropDefiner*>(pDefiner); };
};

class SwRegisterItem : public SfxBoolItem
diff --git a/sw/source/core/attr/swatrset.cxx b/sw/source/core/attr/swatrset.cxx
index 0fe141e..90343c3 100644
--- a/sw/source/core/attr/swatrset.cxx
+++ b/sw/source/core/attr/swatrset.cxx
@@ -259,18 +259,19 @@ bool SwAttrSet::SetModifyAtAttr( const sw::BroadcastingModify* pModify )
        bSet = true;
    }

    if( SfxItemState::SET == GetItemState( RES_PARATR_DROP, false, &pItem ) &&
        static_cast<const SwFormatDrop*>(pItem)->GetDefinedIn() != pModify )
    if(SfxItemState::SET == GetItemState( RES_PARATR_DROP, false, &pItem ))
    {
        auto pDropDefiner = dynamic_cast<const sw::FormatDropDefiner*>(pModify);
        auto pFormatDrop = const_cast<SwFormatDrop*>(static_cast<const SwFormatDrop*>(pItem));
        // If CharFormat is set and it is set in different attribute pools then
        // the CharFormat has to be copied.
        SwCharFormat* pCharFormat = const_cast<SwFormatDrop*>(static_cast<const SwFormatDrop*>(pItem))->GetCharFormat();
        if( pCharFormat && GetPool() != pCharFormat->GetAttrSet().GetPool() )
        SwCharFormat* pCharFormat = pFormatDrop->GetCharFormat();
        if(pCharFormat && GetPool() != pCharFormat->GetAttrSet().GetPool())
        {
           pCharFormat = GetDoc()->CopyCharFormat( *pCharFormat );
           const_cast<SwFormatDrop*>(static_cast<const SwFormatDrop*>(pItem))->SetCharFormat( pCharFormat );
           pCharFormat = GetDoc()->CopyCharFormat(*pCharFormat);
           pFormatDrop->SetCharFormat(pCharFormat);
        }
        const_cast<SwFormatDrop*>(static_cast<const SwFormatDrop*>(pItem))->ChgDefinedIn( pModify );
        pFormatDrop->ChgDefinedIn(pDropDefiner);
        bSet = true;
    }

diff --git a/sw/source/core/para/paratr.cxx b/sw/source/core/para/paratr.cxx
index 08be020..ede55b9 100644
--- a/sw/source/core/para/paratr.cxx
+++ b/sw/source/core/para/paratr.cxx
@@ -70,23 +70,6 @@ void SwFormatDrop::SetCharFormat( SwCharFormat *pNew )
        pNew->Add( this );
}

void SwFormatDrop::SwClientNotify(const SwModify&, const SfxHint&)
{
    if(!m_pDefinedIn)
        return;
    if(dynamic_cast<const SwFormat*>(m_pDefinedIn) == nullptr)
    {
        sw::BroadcastingModify aMod;
        m_pDefinedIn->SwClientNotifyCall(aMod, sw::LegacyModifyHint(this, this));
    }
    else if(m_pDefinedIn->HasWriterListeners() && !m_pDefinedIn->IsModifyLocked())
    {
        // Notify those who are dependent on the format on our own.
        // The format itself wouldn't pass on the notify as it does not get past the check.
        m_pDefinedIn->CallSwClientNotify(sw::LegacyModifyHint(this, this));
    }
}

bool SwFormatDrop::GetInfo( SfxPoolItem& ) const
{
    return true; // Continue
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
index 13e240a..2d6a9e5 100644
--- a/sw/source/core/undo/rolbck.cxx
+++ b/sw/source/core/undo/rolbck.cxx
@@ -85,7 +85,7 @@ SwHistorySetFormat::SwHistorySetFormat( const SfxPoolItem* pFormatHt, sal_uLong 
            static_cast<SwFormatPageDesc&>(*m_pAttr).ChgDefinedIn( nullptr );
            break;
        case RES_PARATR_DROP:
            static_cast<SwFormatDrop&>(*m_pAttr).ChgDefinedIn( nullptr );
            static_cast<SwFormatDrop&>(*m_pAttr).ChgDefinedIn(nullptr);
            break;
        case RES_BOXATR_FORMULA:
        {
@@ -854,7 +854,7 @@ SwHistorySetAttrSet::SwHistorySetAttrSet( const SfxItemSet& rSet,

                case RES_PARATR_DROP:
                    static_cast<SwFormatDrop*>(
                        const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( nullptr );
                        const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn(nullptr);
                    break;

                case RES_BOXATR_FORMULA: