sw/inc/textcontentcontrol.hxx                 |    4 -
 sw/inc/textlinebreak.hxx                      |    2 
 sw/inc/txatbase.hxx                           |   72 ++++++++++++++------------
 sw/inc/txtannotationfld.hxx                   |    2 
 sw/inc/txtatr.hxx                             |   19 +++++-
 sw/inc/txtflcnt.hxx                           |    4 +
 sw/inc/txtfld.hxx                             |    4 -
 sw/inc/txtftn.hxx                             |    4 +
 sw/inc/txtinet.hxx                            |    5 +
 sw/inc/txtrfmrk.hxx                           |    6 +-
 sw/inc/txttxmrk.hxx                           |    6 +-
 sw/source/core/crsr/crstrvl.cxx               |   21 +++++--
 sw/source/core/text/itratr.cxx                |    2 
 sw/source/core/text/redlnitr.cxx              |    2 
 sw/source/core/txtnode/atrfld.cxx             |   12 ++--
 sw/source/core/txtnode/atrflyin.cxx           |    7 +-
 sw/source/core/txtnode/atrftn.cxx             |    7 +-
 sw/source/core/txtnode/atrref.cxx             |    9 ++-
 sw/source/core/txtnode/atrtox.cxx             |   11 ++-
 sw/source/core/txtnode/attrcontentcontrol.cxx |   23 ++++----
 sw/source/core/txtnode/attrlinebreak.cxx      |    5 +
 sw/source/core/txtnode/ndtxt.cxx              |    4 -
 sw/source/core/txtnode/thints.cxx             |   65 +++++++++++------------
 sw/source/core/txtnode/txatbase.cxx           |   16 ++---
 sw/source/core/txtnode/txtatr2.cxx            |   47 +++++++++++-----
 sw/source/core/undo/rolbck.cxx                |   10 +--
 26 files changed, 217 insertions(+), 152 deletions(-)

New commits:
commit 55e97eaabf6cce91f424e440af392143f11f3343
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Mon Jan 8 18:58:11 2024 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Tue Jan 9 10:49:42 2024 +0100

    Decouple SwTextAttr from DirectPutItemInPool
    
    SwTextAttr uses a 'const SfxPoolItem*' and the
    mentioned DirectPutItemInPool/DirectRemoveItemFromPool
    to force creation of a ref-counted SfxPoolItem to
    work with. There is now tooling to do so, so changed
    to using SfxPoolItemHolder. That works like a small
    SfxItemSet - it transforms the Item to ref-count
    form and takes over management. It is safe to
    pass around, cheap to copy and it does not need manual
    cleanup of SfxPoolItems (automatic -as in SfxItemPool).
    
    Change-Id: I41401d5144c9cd59d5b10362ea17d63e35ab1eb3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161799
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/sw/inc/textcontentcontrol.hxx b/sw/inc/textcontentcontrol.hxx
index b3926bd25ce9..89a69970efcc 100644
--- a/sw/inc/textcontentcontrol.hxx
+++ b/sw/inc/textcontentcontrol.hxx
@@ -28,12 +28,12 @@ class SW_DLLPUBLIC SwTextContentControl final : public 
SwTextAttrNesting
 {
     SwContentControlManager* m_pManager;
 
-    SwTextContentControl(SwContentControlManager* pManager, 
SwFormatContentControl& rAttr,
+    SwTextContentControl(SwContentControlManager* pManager, const 
SfxPoolItemHolder& rAttr,
                          sal_Int32 nStart, sal_Int32 nEnd);
 
 public:
     static SwTextContentControl* CreateTextContentControl(SwDoc& rDoc, 
SwTextNode* pTargetTextNode,
-                                                          
SwFormatContentControl& rAttr,
+                                                          const 
SfxPoolItemHolder& rHolder,
                                                           sal_Int32 nStart, 
sal_Int32 nEnd,
                                                           bool bIsCopy);
 
diff --git a/sw/inc/textlinebreak.hxx b/sw/inc/textlinebreak.hxx
index 5b5e8c6854c3..57f6b3ecb60e 100644
--- a/sw/inc/textlinebreak.hxx
+++ b/sw/inc/textlinebreak.hxx
@@ -33,7 +33,7 @@ class SW_DLLPUBLIC SwTextLineBreak final : public SwTextAttr
     SwTextNode* m_pTextNode;
 
 public:
-    SwTextLineBreak(SwFormatLineBreak& rAttr, sal_Int32 nStart);
+    SwTextLineBreak(const SfxPoolItemHolder& rAttr, sal_Int32 nStart);
 
     ~SwTextLineBreak() override;
 
diff --git a/sw/inc/txatbase.hxx b/sw/inc/txatbase.hxx
index 00e2f9b51470..2b3595709bf1 100644
--- a/sw/inc/txatbase.hxx
+++ b/sw/inc/txatbase.hxx
@@ -44,7 +44,8 @@ class SW_DLLPUBLIC SwTextAttr
 {
 friend class SwpHints;
 private:
-    SfxPoolItem * const m_pAttr;
+    // use SfxPoolItemHolder for safe reference to 'const SfxPoolItem*'
+    SfxPoolItemHolder m_aAttr;
     sal_Int32 m_nStart;
     bool m_bDontExpand          : 1;
     bool m_bLockExpandFlag      : 1;
@@ -66,7 +67,7 @@ private:
 protected:
     SwpHints * m_pHints = nullptr;  // the SwpHints holds a pointer to this, 
and needs to be notified if the start/end changes
 
-    SwTextAttr( SfxPoolItem& rAttr, sal_Int32 nStart );
+    SwTextAttr(const SfxPoolItemHolder& rAttr, sal_Int32 nStart );
     virtual ~SwTextAttr() COVERITY_NOEXCEPT_FALSE;
 
     void SetLockExpandFlag( bool bFlag )    { m_bLockExpandFlag = bFlag; }
@@ -81,7 +82,7 @@ protected:
 public:
 
     /// destroy instance
-    static void Destroy( SwTextAttr * pToDestroy, SfxItemPool& rPool );
+    static void Destroy( SwTextAttr * pToDestroy );
 
     /// start position
     void SetStart(sal_Int32 n) { m_nStart = n; if (m_pHints) 
m_pHints->StartPosChanged(); }
@@ -138,7 +139,10 @@ protected:
     sal_Int32 m_nEnd;
 
 public:
-    SwTextAttrEnd( SfxPoolItem& rAttr, sal_Int32 nStart, sal_Int32 nEnd );
+    SwTextAttrEnd(
+        const SfxPoolItemHolder& rAttr,
+        sal_Int32 nStart,
+        sal_Int32 nEnd );
 
     virtual const sal_Int32* GetEnd() const override;
     virtual void SetEnd(sal_Int32) override;
@@ -148,8 +152,10 @@ public:
 class SAL_DLLPUBLIC_RTTI SwTextAttrNesting : public SwTextAttrEnd
 {
 protected:
-    SwTextAttrNesting( SfxPoolItem & i_rAttr,
-        const sal_Int32 i_nStart, const sal_Int32 i_nEnd );
+    SwTextAttrNesting(
+        const SfxPoolItemHolder& rAttr,
+        const sal_Int32 i_nStart,
+        const sal_Int32 i_nEnd );
     virtual ~SwTextAttrNesting() override;
 };
 
@@ -166,8 +172,8 @@ inline sal_Int32 SwTextAttr::GetAnyEnd() const
 
 inline const SfxPoolItem& SwTextAttr::GetAttr() const
 {
-    assert( m_pAttr );
-    return *m_pAttr;
+    assert( m_aAttr );
+    return *m_aAttr.getItem();
 }
 
 inline SfxPoolItem& SwTextAttr::GetAttr()
@@ -186,71 +192,71 @@ inline void SwTextAttr::SetDontExpand( bool bDontExpand )
 
 inline const SwFormatCharFormat& SwTextAttr::GetCharFormat() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_CHARFMT );
-    return static_cast<const SwFormatCharFormat&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_CHARFMT );
+    return static_cast<const SwFormatCharFormat&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatAutoFormat& SwTextAttr::GetAutoFormat() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_AUTOFMT );
-    return static_cast<const SwFormatAutoFormat&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_AUTOFMT );
+    return static_cast<const SwFormatAutoFormat&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatField& SwTextAttr::GetFormatField() const
 {
-    assert( m_pAttr
-            && ( m_pAttr->Which() == RES_TXTATR_FIELD
-                 || m_pAttr->Which() == RES_TXTATR_ANNOTATION
-                 || m_pAttr->Which() == RES_TXTATR_INPUTFIELD ));
-    return static_cast<const SwFormatField&>(*m_pAttr);
+    assert( m_aAttr
+            && ( m_aAttr.Which() == RES_TXTATR_FIELD
+                 || m_aAttr.Which() == RES_TXTATR_ANNOTATION
+                 || m_aAttr.Which() == RES_TXTATR_INPUTFIELD ));
+    return static_cast<const SwFormatField&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatFootnote& SwTextAttr::GetFootnote() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_FTN );
-    return static_cast<const SwFormatFootnote&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_FTN );
+    return static_cast<const SwFormatFootnote&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatLineBreak& SwTextAttr::GetLineBreak() const
 {
-    assert(m_pAttr && m_pAttr->Which() == RES_TXTATR_LINEBREAK);
-    return static_cast<const SwFormatLineBreak&>(*m_pAttr);
+    assert(m_aAttr && m_aAttr.Which() == RES_TXTATR_LINEBREAK);
+    return static_cast<const SwFormatLineBreak&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatContentControl& SwTextAttr::GetContentControl() const
 {
-    assert(m_pAttr && m_pAttr->Which() == RES_TXTATR_CONTENTCONTROL);
-    return static_cast<const SwFormatContentControl&>(*m_pAttr);
+    assert(m_aAttr && m_aAttr.Which() == RES_TXTATR_CONTENTCONTROL);
+    return static_cast<const SwFormatContentControl&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatFlyCnt& SwTextAttr::GetFlyCnt() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_FLYCNT );
-    return static_cast<const SwFormatFlyCnt&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_FLYCNT );
+    return static_cast<const SwFormatFlyCnt&>(*m_aAttr.getItem());
 }
 
 inline const SwTOXMark& SwTextAttr::GetTOXMark() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_TOXMARK );
-    return static_cast<const SwTOXMark&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_TOXMARK );
+    return static_cast<const SwTOXMark&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatRefMark& SwTextAttr::GetRefMark() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_REFMARK );
-    return static_cast<const SwFormatRefMark&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_REFMARK );
+    return static_cast<const SwFormatRefMark&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatINetFormat& SwTextAttr::GetINetFormat() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_INETFMT );
-    return static_cast<const SwFormatINetFormat&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_INETFMT );
+    return static_cast<const SwFormatINetFormat&>(*m_aAttr.getItem());
 }
 
 inline const SwFormatRuby& SwTextAttr::GetRuby() const
 {
-    assert( m_pAttr && m_pAttr->Which() == RES_TXTATR_CJK_RUBY );
-    return static_cast<const SwFormatRuby&>(*m_pAttr);
+    assert( m_aAttr && m_aAttr.Which() == RES_TXTATR_CJK_RUBY );
+    return static_cast<const SwFormatRuby&>(*m_aAttr.getItem());
 }
 
 // these should be static_casts but with virtual inheritance it's not possible
diff --git a/sw/inc/txtannotationfld.hxx b/sw/inc/txtannotationfld.hxx
index f45e0c5b9b35..b1d35b33ea25 100644
--- a/sw/inc/txtannotationfld.hxx
+++ b/sw/inc/txtannotationfld.hxx
@@ -28,7 +28,7 @@ class SwTextAnnotationField final : public SwTextField
 {
 public:
     SwTextAnnotationField(
-        SwFormatField & rAttr,
+        const SfxPoolItemHolder& rAttr,
         sal_Int32 const nStart,
         bool const bInClipboard );
 
diff --git a/sw/inc/txtatr.hxx b/sw/inc/txtatr.hxx
index cb96256fcb10..cf1b77073676 100644
--- a/sw/inc/txtatr.hxx
+++ b/sw/inc/txtatr.hxx
@@ -37,7 +37,10 @@ class SwTextCharFormat final : public SwTextAttrEnd
     sal_uInt16 m_nSortNumber;
 
 public:
-    SwTextCharFormat( SwFormatCharFormat& rAttr, sal_Int32 nStart, sal_Int32 
nEnd );
+    SwTextCharFormat(
+        const SfxPoolItemHolder& rAttr,
+        sal_Int32 nStart,
+        sal_Int32 nEnd );
     virtual ~SwTextCharFormat( ) override;
 
     void TriggerNodeUpdate(const sw::LegacyModifyHint&);
@@ -54,14 +57,17 @@ public:
 class SwTextMeta final : public SwTextAttrNesting
 {
 private:
-    SwTextMeta( SwFormatMeta & i_rAttr,
-        const sal_Int32 i_nStart, const sal_Int32 i_nEnd );
+    SwTextMeta(
+        const SfxPoolItemHolder& rAttr,
+        const sal_Int32 i_nStart,
+        const sal_Int32 i_nEnd );
 
 public:
     static SwTextMeta * CreateTextMeta(
         ::sw::MetaFieldManager & i_rTargetDocManager,
         SwTextNode *const i_pTargetTextNode,
-        SwFormatMeta & i_rAttr,
+        const SfxPoolItemHolder& rAttr,
+        // SwFormatMeta & i_rAttr,
         sal_Int32 const i_nStart, sal_Int32 const i_nEnd,
         bool const i_bIsCopy);
 
@@ -76,7 +82,10 @@ class SW_DLLPUBLIC SwTextRuby final: public 
SwTextAttrNesting, public SwClient
     SwTextNode* m_pTextNode;
     virtual void SwClientNotify(const SwModify&, const SfxHint&) override;
 public:
-    SwTextRuby( SwFormatRuby& rAttr, sal_Int32 nStart, sal_Int32 nEnd );
+    SwTextRuby(
+        const SfxPoolItemHolder& rAttr,
+        sal_Int32 nStart,
+        sal_Int32 nEnd );
     virtual ~SwTextRuby() override;
 
     SAL_DLLPRIVATE void InitRuby(SwTextNode & rNode);
diff --git a/sw/inc/txtflcnt.hxx b/sw/inc/txtflcnt.hxx
index a4a0de1d609b..73f422116bc3 100644
--- a/sw/inc/txtflcnt.hxx
+++ b/sw/inc/txtflcnt.hxx
@@ -31,7 +31,9 @@ class SwTextFlyCnt final : public SwTextAttr
 {
     SwFlyInContentFrame  *GetFlyFrame_( const SwFrame *pCurrFrame );
 public:
-    SwTextFlyCnt( SwFormatFlyCnt& rAttr, sal_Int32 nStart );
+    SwTextFlyCnt(
+        const SfxPoolItemHolder& rAttr,
+        sal_Int32 nStart );
 
     // Sets anchor in pFormat and
     void    SetAnchor( const SwTextNode *pNode );
diff --git a/sw/inc/txtfld.hxx b/sw/inc/txtfld.hxx
index 8055b337b0cb..5e812f8682d9 100644
--- a/sw/inc/txtfld.hxx
+++ b/sw/inc/txtfld.hxx
@@ -35,7 +35,7 @@ class SAL_DLLPUBLIC_RTTI SwTextField : public virtual 
SwTextAttr
 
 public:
     SwTextField(
-        SwFormatField & rAttr,
+        const SfxPoolItemHolder& rAttr,
         sal_Int32 const nStart,
         bool const bInClipboard );
 
@@ -80,7 +80,7 @@ class SwTextInputField final
 {
 public:
     SwTextInputField(
-        SwFormatField & rAttr,
+        const SfxPoolItemHolder& rAttr,
         sal_Int32 const nStart,
         sal_Int32 const nEnd,
         bool const bInClipboard );
diff --git a/sw/inc/txtftn.hxx b/sw/inc/txtftn.hxx
index 2d86bf217e64..6c8ca41bc8c6 100644
--- a/sw/inc/txtftn.hxx
+++ b/sw/inc/txtftn.hxx
@@ -37,7 +37,9 @@ class SW_DLLPUBLIC SwTextFootnote final : public SwTextAttr
     sal_uInt16 m_nSeqNo;
 
 public:
-    SwTextFootnote( SwFormatFootnote& rAttr, sal_Int32 nStart );
+    SwTextFootnote(
+        const SfxPoolItemHolder& rAttr,
+        sal_Int32 nStart );
     virtual ~SwTextFootnote() override;
 
     const SwNodeIndex *GetStartNode() const { return m_oStartNode ? 
&*m_oStartNode : nullptr; }
diff --git a/sw/inc/txtinet.hxx b/sw/inc/txtinet.hxx
index 33b8b96c6273..ae430d59ac42 100644
--- a/sw/inc/txtinet.hxx
+++ b/sw/inc/txtinet.hxx
@@ -35,7 +35,10 @@ class SW_DLLPUBLIC SwTextINetFormat final: public 
SwTextAttrNesting, public SwCl
         virtual void SwClientNotify(const SwModify&, const SfxHint&) override;
 
     public:
-        SwTextINetFormat( SwFormatINetFormat& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+        SwTextINetFormat(
+            const SfxPoolItemHolder& rAttr,
+            sal_Int32 nStart,
+            sal_Int32 nEnd );
         virtual ~SwTextINetFormat() override;
 
         SAL_DLLPRIVATE void InitINetFormat(SwTextNode & rNode);
diff --git a/sw/inc/txtrfmrk.hxx b/sw/inc/txtrfmrk.hxx
index c01387998392..4f68b9ef0201 100644
--- a/sw/inc/txtrfmrk.hxx
+++ b/sw/inc/txtrfmrk.hxx
@@ -32,8 +32,10 @@ class SwTextRefMark final : public SwTextAttrEnd
     sal_Int32 * m_pEnd; // end is optional (point reference)
 
 public:
-    SwTextRefMark( SwFormatRefMark& rAttr,
-            sal_Int32 const nStart, sal_Int32 const*const pEnd = nullptr);
+    SwTextRefMark(
+        const SfxPoolItemHolder& rAttr,
+        sal_Int32 const nStart,
+        sal_Int32 const*const pEnd = nullptr);
 
     ~SwTextRefMark();
 
diff --git a/sw/inc/txttxmrk.hxx b/sw/inc/txttxmrk.hxx
index 96239e947e3b..202eae21a5f5 100644
--- a/sw/inc/txttxmrk.hxx
+++ b/sw/inc/txttxmrk.hxx
@@ -31,8 +31,10 @@ class SAL_DLLPUBLIC_RTTI SwTextTOXMark final : public 
SwTextAttrEnd
     sal_Int32 * m_pEnd;   // 0 if SwTOXMark without AlternativeText
 
 public:
-    SwTextTOXMark( SwTOXMark& rAttr,
-            sal_Int32 const nStart, sal_Int32 const*const pEnd);
+    SwTextTOXMark(
+        const SfxPoolItemHolder& rAttr,
+        sal_Int32 const nStart,
+        sal_Int32 const*const pEnd);
     virtual ~SwTextTOXMark() override;
 
     virtual const sal_Int32 *GetEnd() const override;     // SwTextAttr
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index c886ffb6572c..1ca95f7ef0e9 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -744,11 +744,18 @@ bool SwCursorShell::MoveFieldType(
         if( bDelField )
         {
             // create dummy for the search
-            SwFormatField* pFormatField = new SwFormatField( SwDateTimeField(
-                
static_cast<SwDateTimeFieldType*>(mxDoc->getIDocumentFieldsAccess().GetSysFieldType(
 SwFieldIds::DateTime ) ) ) );
-
-            pTextField = new SwTextField( *pFormatField, 
rPos.GetContentIndex(),
-                        mxDoc->IsClipBoard() );
+            // NOTE: with SfxPoolItemHolder in SwTextAttr the
+            // SwFormatField will just be managed by it, when
+            // wanted and handing over bPassingOwnership==true
+            pTextField = new SwTextField (
+                SfxPoolItemHolder(
+                    mxDoc->GetAttrPool(),
+                    new SwFormatField(
+                        SwDateTimeField(
+                            
static_cast<SwDateTimeFieldType*>(mxDoc->getIDocumentFieldsAccess().GetSysFieldType(
 SwFieldIds::DateTime )))),
+                    true), // bPassingOwnership
+                rPos.GetContentIndex(),
+                mxDoc->IsClipBoard() );
             pTextField->ChgTextNode( pTNd );
         }
         else
@@ -765,9 +772,9 @@ bool SwCursorShell::MoveFieldType(
 
         if( bDelField )
         {
-            auto const 
pFormat(static_cast<SwFormatField*>(&pTextField->GetAttr()));
+            // with using SfxPoolItemHolder in SwTextAttr there is no need 
anymore
+            // to cleanup the contained SwFormatField self
             delete pTextField;
-            delete pFormat;
         }
 
         if( it != aSrtLst.end() && isSrch ) // found
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index 24203ecb531c..048823256adb 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -1308,7 +1308,7 @@ sal_uInt16 SwTextFrame::GetScalingOfSelectedText(
     // scaling value 100 and priority flag on top of the scaling stack
     SwAttrHandler& rAH = aIter.GetAttrHandler();
     SvxCharScaleWidthItem aItem(100, RES_CHRATR_SCALEW);
-    SwTextAttrEnd aAttr( aItem, 0, COMPLETE_STRING );
+    SwTextAttrEnd aAttr( 
SfxPoolItemHolder(getRootFrame()->GetCurrShell()->GetAttrPool(), &aItem), 0, 
COMPLETE_STRING );
     aAttr.SetPriorityAttr( true );
     rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );
 
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index 0e89b7f75a6e..afa87aba0963 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -916,7 +916,7 @@ void SwRedlineItr::Clear_( SwFont* pFnt )
             m_rAttrHandler.PopAndChg( *hint, *pFnt );
         else
             m_rAttrHandler.Pop( *hint );
-        SwTextAttr::Destroy(hint, const_cast<SwDoc&>(m_rDoc).GetAttrPool() );
+        SwTextAttr::Destroy(hint);
     }
     m_Hints.clear();
 }
diff --git a/sw/source/core/txtnode/atrfld.cxx 
b/sw/source/core/txtnode/atrfld.cxx
index 47e78ce2c95d..2812522024bb 100644
--- a/sw/source/core/txtnode/atrfld.cxx
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -485,16 +485,18 @@ void SwFormatField::dumpAsXml(xmlTextWriterPtr pWriter) 
const
 // class SwTextField ////////////////////////////////////////////////////
 
 SwTextField::SwTextField(
-    SwFormatField & rAttr,
+    const SfxPoolItemHolder& rAttr,
     sal_Int32 const nStartPos,
     bool const bInClipboard)
     : SwTextAttr( rAttr, nStartPos )
 // fdo#39694 the ExpandField here may not give the correct result in all cases,
 // but is better than nothing
-    , m_aExpand( rAttr.GetField()->ExpandField(bInClipboard, nullptr) )
+    , m_aExpand()
     , m_pTextNode( nullptr )
 {
-    rAttr.SetTextField( *this );
+    SwFormatField& rSwFormatField(static_cast<SwFormatField&>(GetAttr()));
+    m_aExpand = rSwFormatField.GetField()->ExpandField(bInClipboard, nullptr);
+    rSwFormatField.SetTextField( *this );
     SetHasDummyChar(true);
 }
 
@@ -664,7 +666,7 @@ void SwTextField::DeleteTextField( const SwTextField& 
rTextField )
 
 // input field in-place editing
 SwTextInputField::SwTextInputField(
-    SwFormatField & rAttr,
+    const SfxPoolItemHolder& rAttr,
     sal_Int32 const nStart,
     sal_Int32 const nEnd,
     bool const bInClipboard )
@@ -765,7 +767,7 @@ void SwTextInputField::UpdateTextNodeContent( const 
OUString& rNewContent )
 
 // text annotation field
 SwTextAnnotationField::SwTextAnnotationField(
-    SwFormatField & rAttr,
+    const SfxPoolItemHolder& rAttr,
     sal_Int32 const nStart,
     bool const bInClipboard )
     : SwTextAttr( rAttr, nStart )
diff --git a/sw/source/core/txtnode/atrflyin.cxx 
b/sw/source/core/txtnode/atrflyin.cxx
index 28eb7b38e530..9a61e8dedb4a 100644
--- a/sw/source/core/txtnode/atrflyin.cxx
+++ b/sw/source/core/txtnode/atrflyin.cxx
@@ -68,10 +68,13 @@ void SwFormatFlyCnt::dumpAsXml(xmlTextWriterPtr pWriter) 
const
     (void)xmlTextWriterEndElement(pWriter);
 }
 
-SwTextFlyCnt::SwTextFlyCnt( SwFormatFlyCnt& rAttr, sal_Int32 nStartPos )
+SwTextFlyCnt::SwTextFlyCnt(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 nStartPos )
     : SwTextAttr( rAttr, nStartPos )
 {
-    rAttr.m_pTextAttr = this;
+    SwFormatFlyCnt& rSwFormatFlyCnt(static_cast<SwFormatFlyCnt&>(GetAttr()));
+    rSwFormatFlyCnt.m_pTextAttr = this;
     SetHasDummyChar(true);
 }
 
diff --git a/sw/source/core/txtnode/atrftn.cxx 
b/sw/source/core/txtnode/atrftn.cxx
index 58f6a5001690..90d93c02b10e 100644
--- a/sw/source/core/txtnode/atrftn.cxx
+++ b/sw/source/core/txtnode/atrftn.cxx
@@ -292,12 +292,15 @@ void SwFormatFootnote::dumpAsXml(xmlTextWriterPtr 
pWriter) const
     (void)xmlTextWriterEndElement(pWriter);
 }
 
-SwTextFootnote::SwTextFootnote( SwFormatFootnote& rAttr, sal_Int32 nStartPos )
+SwTextFootnote::SwTextFootnote(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 nStartPos )
     : SwTextAttr( rAttr, nStartPos )
     , m_pTextNode( nullptr )
     , m_nSeqNo( USHRT_MAX )
 {
-    rAttr.m_pTextAttr = this;
+    SwFormatFootnote& 
rSwFormatFootnote(static_cast<SwFormatFootnote&>(GetAttr()));
+    rSwFormatFootnote.m_pTextAttr = this;
     SetHasDummyChar(true);
 }
 
diff --git a/sw/source/core/txtnode/atrref.cxx 
b/sw/source/core/txtnode/atrref.cxx
index 1684e003309e..6a3e31fab130 100644
--- a/sw/source/core/txtnode/atrref.cxx
+++ b/sw/source/core/txtnode/atrref.cxx
@@ -102,14 +102,17 @@ void SwFormatRefMark::dumpAsXml(xmlTextWriterPtr pWriter) 
const
 
 // attribute for content references in the text
 
-SwTextRefMark::SwTextRefMark( SwFormatRefMark& rAttr,
-            sal_Int32 const nStartPos, sal_Int32 const*const pEnd)
+SwTextRefMark::SwTextRefMark(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 const nStartPos,
+    sal_Int32 const*const pEnd)
     : SwTextAttr(rAttr, nStartPos)
     , SwTextAttrEnd( rAttr, nStartPos, nStartPos )
     , m_pTextNode( nullptr )
     , m_pEnd( nullptr )
 {
-    rAttr.m_pTextAttr = this;
+    SwFormatRefMark& 
rSwFormatRefMark(static_cast<SwFormatRefMark&>(GetAttr()));
+    rSwFormatRefMark.m_pTextAttr = this;
     if ( pEnd )
     {
         m_nEnd = *pEnd;
diff --git a/sw/source/core/txtnode/atrtox.cxx 
b/sw/source/core/txtnode/atrtox.cxx
index 664ce55968ad..a18e35a28db2 100644
--- a/sw/source/core/txtnode/atrtox.cxx
+++ b/sw/source/core/txtnode/atrtox.cxx
@@ -21,15 +21,18 @@
 #include <txttxmrk.hxx>
 #include <tox.hxx>
 
-SwTextTOXMark::SwTextTOXMark( SwTOXMark& rAttr,
-            sal_Int32 const nStartPos, sal_Int32 const*const pEnd)
+SwTextTOXMark::SwTextTOXMark(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 const nStartPos,
+    sal_Int32 const*const pEnd)
     : SwTextAttr( rAttr, nStartPos )
     , SwTextAttrEnd( rAttr, nStartPos, nStartPos )
     , m_pTextNode( nullptr )
     , m_pEnd( nullptr )
 {
-    rAttr.m_pTextAttr = this;
-    if ( rAttr.GetAlternativeText().isEmpty() )
+    SwTOXMark& rSwTOXMark(static_cast<SwTOXMark&>(GetAttr()));
+    rSwTOXMark.m_pTextAttr = this;
+    if ( rSwTOXMark.GetAlternativeText().isEmpty() )
     {
         m_nEnd = *pEnd;
         m_pEnd = & m_nEnd;
diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx 
b/sw/source/core/txtnode/attrcontentcontrol.cxx
index 0bd7669f5d9e..28abc9b7fc30 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -697,35 +697,38 @@ SwContentControlListItem::ItemsFromAny(const 
css::uno::Any& rVal)
     return aRet;
 }
 
-SwTextContentControl* SwTextContentControl::CreateTextContentControl(SwDoc& 
rDoc,
-                                                                     
SwTextNode* pTargetTextNode,
-                                                                     
SwFormatContentControl& rAttr,
-                                                                     sal_Int32 
nStart,
-                                                                     sal_Int32 
nEnd, bool bIsCopy)
+SwTextContentControl*
+SwTextContentControl::CreateTextContentControl(SwDoc& rDoc, SwTextNode* 
pTargetTextNode,
+                                               const SfxPoolItemHolder& 
rHolder, sal_Int32 nStart,
+                                               sal_Int32 nEnd, bool bIsCopy)
 {
     if (bIsCopy)
     {
-        // rAttr is already cloned, now call DoCopy to copy the 
SwContentControl
+        // the item in rHolder is already cloned, now call DoCopy to copy the 
SwContentControl
         if (!pTargetTextNode)
         {
             SAL_WARN("sw.core",
                      "SwTextContentControl ctor: cannot copy content control 
without target node");
         }
-        rAttr.DoCopy(*pTargetTextNode);
+        SwFormatContentControl* pSwFormatContentControl(
+            
static_cast<SwFormatContentControl*>(const_cast<SfxPoolItem*>(rHolder.getItem())));
+        pSwFormatContentControl->DoCopy(*pTargetTextNode);
     }
     SwContentControlManager* pManager = &rDoc.GetContentControlManager();
-    auto pTextContentControl(new SwTextContentControl(pManager, rAttr, nStart, 
nEnd));
+    auto pTextContentControl(new SwTextContentControl(pManager, rHolder, 
nStart, nEnd));
     return pTextContentControl;
 }
 
 SwTextContentControl::SwTextContentControl(SwContentControlManager* pManager,
-                                           SwFormatContentControl& rAttr, 
sal_Int32 nStart,
+                                           const SfxPoolItemHolder& rAttr, 
sal_Int32 nStart,
                                            sal_Int32 nEnd)
     : SwTextAttr(rAttr, nStart)
     , SwTextAttrNesting(rAttr, nStart, nEnd)
     , m_pManager(pManager)
 {
-    rAttr.SetTextAttr(this);
+    SwFormatContentControl& rSwFormatContentControl(
+        static_cast<SwFormatContentControl&>(GetAttr()));
+    rSwFormatContentControl.SetTextAttr(this);
     SetHasDummyChar(true);
     m_pManager->Insert(this);
 }
diff --git a/sw/source/core/txtnode/attrlinebreak.cxx 
b/sw/source/core/txtnode/attrlinebreak.cxx
index 5ce9301820a5..b1fb393139b5 100644
--- a/sw/source/core/txtnode/attrlinebreak.cxx
+++ b/sw/source/core/txtnode/attrlinebreak.cxx
@@ -102,11 +102,12 @@ void SwFormatLineBreak::dumpAsXml(xmlTextWriterPtr 
pWriter) const
     (void)xmlTextWriterEndElement(pWriter);
 }
 
-SwTextLineBreak::SwTextLineBreak(SwFormatLineBreak& rAttr, sal_Int32 nStartPos)
+SwTextLineBreak::SwTextLineBreak(const SfxPoolItemHolder& rAttr, sal_Int32 
nStartPos)
     : SwTextAttr(rAttr, nStartPos)
     , m_pTextNode(nullptr)
 {
-    rAttr.SetTextLineBreak(this);
+    SwFormatLineBreak& 
rSwFormatLineBreak(static_cast<SwFormatLineBreak&>(GetAttr()));
+    rSwFormatLineBreak.SetTextLineBreak(this);
     SetHasDummyChar(true);
 }
 
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 47bff5e08bac..95441c85ab7a 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -764,7 +764,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & 
rPos,
             }
 
             m_pSwpHints->DeleteAtPos(i);
-            SwTextAttr::Destroy(pHt, GetDoc().GetAttrPool());
+            SwTextAttr::Destroy(pHt);
             --i;
         }
     }
@@ -1409,7 +1409,7 @@ void SwTextNode::Update(
                             {
                                 SwTextAttr *pTmp = *it;
                                 pCollector->erase( it );
-                                SwTextAttr::Destroy( pTmp, 
GetDoc().GetAttrPool() );
+                                SwTextAttr::Destroy( pTmp );
                             }
                             SwTextAttr * const pTmp =
                             MakeTextAttr( GetDoc(),
diff --git a/sw/source/core/txtnode/thints.cxx 
b/sw/source/core/txtnode/thints.cxx
index f85187e9fa13..0220fa9d8b2a 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -105,7 +105,7 @@ SwpHints::SwpHints(const SwTextNode& rParent)
 {
 }
 
-static void TextAttrDelete( SwDoc & rDoc, SwTextAttr * const pAttr )
+static void TextAttrDelete( SwTextAttr * const pAttr )
 {
     if (RES_TXTATR_META == pAttr->Which() ||
         RES_TXTATR_METAFIELD == pAttr->Which())
@@ -116,7 +116,7 @@ static void TextAttrDelete( SwDoc & rDoc, SwTextAttr * 
const pAttr )
     {
         
static_txtattr_cast<SwTextContentControl*>(pAttr)->ChgTextNode(nullptr);
     }
-    SwTextAttr::Destroy( pAttr, rDoc.GetAttrPool() );
+    SwTextAttr::Destroy( pAttr );
 }
 
 static bool TextAttrContains(const sal_Int32 nPos, const SwTextAttrEnd * const 
pAttr)
@@ -415,7 +415,7 @@ SwpHints::TryInsertNesting( SwTextNode & rNode, 
SwTextAttrNesting & rNewHint )
                     case FAIL:
                         SAL_INFO("sw.core", "cannot insert hint: overlap");
                         for (const auto& aSplit : SplitNew)
-                            TextAttrDelete(rNode.GetDoc(), aSplit);
+                            TextAttrDelete(aSplit);
                         return false;
                     case SPLIT_NEW:
                         lcl_DoSplitNew(SplitNew, rNode, nNewStart,
@@ -470,7 +470,7 @@ SwpHints::TryInsertNesting( SwTextNode & rNode, 
SwTextAttrNesting & rNewHint )
             {
                 SAL_INFO("sw.core", "cannot insert hint: fieldmark overlap");
                 assert(SplitNew.size() == 1);
-                TextAttrDelete(rNode.GetDoc(), &rNewHint);
+                TextAttrDelete(&rNewHint);
                 return false;
             }
             else
@@ -1022,11 +1022,8 @@ SwTextAttr* MakeRedlineTextAttr( SwDoc & rDoc, 
SfxPoolItem const & rAttr )
             break;
     }
 
-    // Put new attribute into pool
-    // FIXME: this const_cast is evil!
-    SfxPoolItem& rNew =
-        const_cast<SfxPoolItem&>( rDoc.GetAttrPool().DirectPutItemInPool( 
rAttr ) );
-    return new SwTextAttrEnd( rNew, 0, 0 );
+    // create a SfxPoolItemHolder and return it (will move Item to referenced 
mode)
+    return new SwTextAttrEnd(SfxPoolItemHolder(rDoc.GetAttrPool(), &rAttr), 0, 
0);
 }
 
 // create new text attribute
@@ -1060,13 +1057,12 @@ SwTextAttr* MakeTextAttr(
         return pNew;
     }
 
-    // Put new attribute into pool
-    // FIXME: this const_cast is evil!
-    SfxPoolItem& rNew =
-        const_cast<SfxPoolItem&>( rDoc.GetAttrPool().DirectPutItemInPool( 
rAttr ) );
+    // create a SfxPoolItemHolder and use it (will move Item to referenced 
mode)
+    const SfxPoolItemHolder aHolder(rDoc.GetAttrPool(), &rAttr);
+    SfxPoolItem& rNew(const_cast<SfxPoolItem&>(*aHolder.getItem()));
 
     SwTextAttr* pNew = nullptr;
-    switch( rNew.Which() )
+    switch( aHolder.Which() )
     {
     case RES_TXTATR_CHARFMT:
         {
@@ -1076,21 +1072,21 @@ SwTextAttr* MakeTextAttr(
                 rFormatCharFormat.SetCharFormat( rDoc.GetDfltCharFormat() );
             }
 
-            pNew = new SwTextCharFormat( rFormatCharFormat, nStt, nEnd );
+            pNew = new SwTextCharFormat( aHolder, nStt, nEnd );
         }
         break;
     case RES_TXTATR_INETFMT:
-        pNew = new SwTextINetFormat( static_cast<SwFormatINetFormat&>(rNew), 
nStt, nEnd );
+        pNew = new SwTextINetFormat( aHolder, nStt, nEnd );
         break;
 
     case RES_TXTATR_FIELD:
-        pNew = new SwTextField( static_cast<SwFormatField &>(rNew), nStt,
+        pNew = new SwTextField( aHolder, nStt,
                     rDoc.IsClipBoard() );
         break;
 
     case RES_TXTATR_ANNOTATION:
         {
-            pNew = new SwTextAnnotationField( static_cast<SwFormatField 
&>(rNew), nStt, rDoc.IsClipBoard() );
+            pNew = new SwTextAnnotationField( aHolder, nStt, 
rDoc.IsClipBoard() );
             if (bIsCopy == CopyOrNewType::Copy)
             {
                 // On copy of the annotation field do not keep the annotated 
text range by removing
@@ -1105,14 +1101,14 @@ SwTextAttr* MakeTextAttr(
         break;
 
     case RES_TXTATR_INPUTFIELD:
-        pNew = new SwTextInputField( static_cast<SwFormatField &>(rNew), nStt, 
nEnd,
+        pNew = new SwTextInputField( aHolder, nStt, nEnd,
                     rDoc.IsClipBoard() );
         break;
 
     case RES_TXTATR_FLYCNT:
         {
             // finally, copy the frame format (with content)
-            pNew = new SwTextFlyCnt( static_cast<SwFormatFlyCnt&>(rNew), nStt 
);
+            pNew = new SwTextFlyCnt( aHolder, nStt );
             if ( static_cast<const SwFormatFlyCnt &>(rAttr).GetTextFlyCnt() )
             {
                 // if it has an existing attr then the format must be copied
@@ -1121,15 +1117,15 @@ SwTextAttr* MakeTextAttr(
         }
         break;
     case RES_TXTATR_FTN:
-        pNew = new SwTextFootnote( static_cast<SwFormatFootnote&>(rNew), nStt 
);
+        pNew = new SwTextFootnote( aHolder, nStt );
         // copy note's SeqNo
         if( static_cast<SwFormatFootnote&>(rAttr).GetTextFootnote() )
             static_cast<SwTextFootnote*>(pNew)->SetSeqNo( 
static_cast<SwFormatFootnote&>(rAttr).GetTextFootnote()->GetSeqRefNo() );
         break;
     case RES_TXTATR_REFMARK:
         pNew = nStt == nEnd
-                ? new SwTextRefMark( static_cast<SwFormatRefMark&>(rNew), nStt 
)
-                : new SwTextRefMark( static_cast<SwFormatRefMark&>(rNew), 
nStt, &nEnd );
+                ? new SwTextRefMark( aHolder, nStt )
+                : new SwTextRefMark( aHolder, nStt, &nEnd );
         break;
     case RES_TXTATR_TOXMARK:
     {
@@ -1146,28 +1142,31 @@ SwTextAttr* MakeTextAttr(
             rMark.RegisterToTOXType(*pToxType);
         }
 
-        pNew = new SwTextTOXMark(rMark, nStt, &nEnd);
+        pNew = new SwTextTOXMark(aHolder, nStt, &nEnd);
         break;
     }
     case RES_TXTATR_CJK_RUBY:
-        pNew = new SwTextRuby( static_cast<SwFormatRuby&>(rNew), nStt, nEnd );
+        pNew = new SwTextRuby( aHolder, nStt, nEnd );
         break;
     case RES_TXTATR_META:
     case RES_TXTATR_METAFIELD:
         pNew = SwTextMeta::CreateTextMeta( rDoc.GetMetaFieldManager(), 
pTextNode,
-                static_cast<SwFormatMeta&>(rNew), nStt, nEnd, bIsCopy == 
CopyOrNewType::Copy );
+                aHolder,
+                nStt, nEnd, bIsCopy == CopyOrNewType::Copy );
         break;
     case RES_TXTATR_LINEBREAK:
-        pNew = new SwTextLineBreak(static_cast<SwFormatLineBreak&>(rNew), 
nStt);
+        pNew = new SwTextLineBreak(aHolder, nStt);
         break;
     case RES_TXTATR_CONTENTCONTROL:
         pNew = SwTextContentControl::CreateTextContentControl(
-            rDoc, pTextNode, static_cast<SwFormatContentControl&>(rNew), nStt, 
nEnd,
+            rDoc, pTextNode,
+            aHolder,
+            nStt, nEnd,
             bIsCopy == CopyOrNewType::Copy);
         break;
     default:
         assert(RES_TXTATR_AUTOFMT == rNew.Which());
-        pNew = new SwTextAttrEnd( rNew, nStt, nEnd );
+        pNew = new SwTextAttrEnd( aHolder, nStt, nEnd );
         break;
     }
 
@@ -1302,7 +1301,7 @@ void SwTextNode::DestroyAttr( SwTextAttr* pAttr )
         break;
     }
 
-    SwTextAttr::Destroy( pAttr, rDoc.GetAttrPool() );
+    SwTextAttr::Destroy( pAttr );
 }
 
 SwTextAttr* SwTextNode::InsertItem(
@@ -1802,7 +1801,7 @@ void SwTextNode::DeleteAttribute( SwTextAttr * const 
pAttr )
             pAttr->Which());
 
         m_pSwpHints->Delete( pAttr );
-        SwTextAttr::Destroy( pAttr, GetDoc().GetAttrPool() );
+        SwTextAttr::Destroy( pAttr );
         CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aHint));
 
         TryDeleteSwpHints();
@@ -1877,7 +1876,7 @@ void SwTextNode::DeleteAttributes(
                     nWhich);
 
                 m_pSwpHints->DeleteAtPos( nPos );
-                SwTextAttr::Destroy( pTextHt, GetDoc().GetAttrPool() );
+                SwTextAttr::Destroy( pTextHt );
                 CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aHint));
             }
         }
@@ -2763,7 +2762,7 @@ bool SwpHints::MergePortions( SwTextNode& rNode )
                 if (pHt->GetStart() == *pHt->GetEnd())
                 {
                     DeleteAtPos(i); // kill it without History!
-                    SwTextAttr::Destroy(pHt, rNode.GetDoc().GetAttrPool());
+                    SwTextAttr::Destroy(pHt);
                     --i;
                     continue;
                 }
diff --git a/sw/source/core/txtnode/txatbase.cxx 
b/sw/source/core/txtnode/txatbase.cxx
index 701e9c1399f7..32ba0586853e 100644
--- a/sw/source/core/txtnode/txatbase.cxx
+++ b/sw/source/core/txtnode/txatbase.cxx
@@ -23,8 +23,8 @@
 #include <txatbase.hxx>
 #include <fmtfld.hxx>
 
-SwTextAttr::SwTextAttr( SfxPoolItem& rAttr, sal_Int32 nStart )
-    : m_pAttr( &rAttr )
+SwTextAttr::SwTextAttr( const SfxPoolItemHolder& rAttr, sal_Int32 nStart )
+    : m_aAttr( rAttr )
     , m_nStart( nStart )
     , m_bDontExpand( false )
     , m_bLockExpandFlag( false )
@@ -55,12 +55,10 @@ void SwTextAttr::SetEnd(sal_Int32 )
     assert(false);
 }
 
-void SwTextAttr::Destroy( SwTextAttr * pToDestroy, SfxItemPool& rPool )
+void SwTextAttr::Destroy( SwTextAttr * pToDestroy )
 {
     if (!pToDestroy) return;
-    SfxPoolItem * const pAttr = pToDestroy->m_pAttr;
     delete pToDestroy;
-    rPool.DirectRemoveItemFromPool( *pAttr );
 }
 
 bool SwTextAttr::operator==( const SwTextAttr& rAttr ) const
@@ -68,8 +66,10 @@ bool SwTextAttr::operator==( const SwTextAttr& rAttr ) const
     return GetAttr() == rAttr.GetAttr();
 }
 
-SwTextAttrEnd::SwTextAttrEnd( SfxPoolItem& rAttr,
-        sal_Int32 nStart, sal_Int32 nEnd ) :
+SwTextAttrEnd::SwTextAttrEnd(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 nStart,
+    sal_Int32 nEnd ) :
     SwTextAttr( rAttr, nStart ), m_nEnd( nEnd )
 {
 }
@@ -99,7 +99,7 @@ void SwTextAttr::dumpAsXml(xmlTextWriterPtr pWriter) const
     if (End())
         (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("end"), 
BAD_CAST(OString::number(*End()).getStr()));
     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("m_pAttr"), 
"%p", m_pAttr);
+    (void)xmlTextWriterWriteFormatAttribute(pWriter, 
BAD_CAST("m_aAttr.getItem()"), "%p", m_aAttr.getItem());
     const char* pWhich = nullptr;
     std::optional<OString> oValue;
     switch (Which())
diff --git a/sw/source/core/txtnode/txtatr2.cxx 
b/sw/source/core/txtnode/txtatr2.cxx
index cc150fc1843a..0fc95bd6451c 100644
--- a/sw/source/core/txtnode/txtatr2.cxx
+++ b/sw/source/core/txtnode/txtatr2.cxx
@@ -54,14 +54,17 @@ bool lcl_CheckAutoFormatHint(const SfxHint& rHint, const 
SwTextNode* pTextNode)
 }
 }
 
-SwTextCharFormat::SwTextCharFormat( SwFormatCharFormat& rAttr,
-                    sal_Int32 nStt, sal_Int32 nEnd )
+SwTextCharFormat::SwTextCharFormat(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 nStt,
+    sal_Int32 nEnd )
     : SwTextAttr( rAttr, nStt )
     , SwTextAttrEnd( rAttr, nStt, nEnd )
     , m_pTextNode( nullptr )
     , m_nSortNumber( 0 )
 {
-    rAttr.m_pTextAttribute = this;
+    SwFormatCharFormat& 
rSwFormatCharFormat(static_cast<SwFormatCharFormat&>(GetAttr()));
+    rSwFormatCharFormat.m_pTextAttribute = this;
     SetCharFormatAttr( true );
 }
 
@@ -93,8 +96,10 @@ void SwTextCharFormat::HandleAutoFormatUsedHint(const 
sw::AutoFormatUsedHint& rH
     rHint.CheckNode(m_pTextNode);
 }
 
-SwTextAttrNesting::SwTextAttrNesting( SfxPoolItem & i_rAttr,
-            const sal_Int32 i_nStart, const sal_Int32 i_nEnd )
+SwTextAttrNesting::SwTextAttrNesting(
+    const SfxPoolItemHolder& i_rAttr,
+    const sal_Int32 i_nStart,
+    const sal_Int32 i_nEnd )
     : SwTextAttr( i_rAttr, i_nStart )
     , SwTextAttrEnd( i_rAttr, i_nStart, i_nEnd )
 {
@@ -110,8 +115,10 @@ SwTextAttrNesting::~SwTextAttrNesting()
 {
 }
 
-SwTextINetFormat::SwTextINetFormat( SwFormatINetFormat& rAttr,
-                            sal_Int32 nStart, sal_Int32 nEnd )
+SwTextINetFormat::SwTextINetFormat(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 nStart,
+    sal_Int32 nEnd )
     : SwTextAttr( rAttr, nStart )
     , SwTextAttrNesting( rAttr, nStart, nEnd )
     , SwClient( nullptr )
@@ -119,7 +126,8 @@ SwTextINetFormat::SwTextINetFormat( SwFormatINetFormat& 
rAttr,
     , m_bVisited( false )
     , m_bVisitedValid( false )
 {
-    rAttr.mpTextAttr  = this;
+    SwFormatINetFormat& 
rSwFormatINetFormat(static_cast<SwFormatINetFormat&>(GetAttr()));
+    rSwFormatINetFormat.mpTextAttr  = this;
     SetCharFormatAttr( true );
 }
 
@@ -192,14 +200,17 @@ bool SwTextINetFormat::IsProtect( ) const
     return m_pTextNode && m_pTextNode->IsProtect();
 }
 
-SwTextRuby::SwTextRuby( SwFormatRuby& rAttr,
-                      sal_Int32 nStart, sal_Int32 nEnd )
+SwTextRuby::SwTextRuby(
+    const SfxPoolItemHolder& rAttr,
+    sal_Int32 nStart,
+    sal_Int32 nEnd )
     : SwTextAttr( rAttr, nStart )
     , SwTextAttrNesting( rAttr, nStart, nEnd )
     , SwClient( nullptr )
     , m_pTextNode( nullptr )
 {
-    rAttr.m_pTextAttr  = this;
+    SwFormatRuby& rSwFormatRuby(static_cast<SwFormatRuby&>(GetAttr()));
+    rSwFormatRuby.m_pTextAttr  = this;
 }
 
 SwTextRuby::~SwTextRuby()
@@ -270,7 +281,7 @@ SwTextMeta *
 SwTextMeta::CreateTextMeta(
     ::sw::MetaFieldManager & i_rTargetDocManager,
     SwTextNode *const i_pTargetTextNode,
-    SwFormatMeta & i_rAttr,
+    const SfxPoolItemHolder& i_rAttr,
     sal_Int32 const i_nStart,
     sal_Int32 const i_nEnd,
     bool const i_bIsCopy)
@@ -278,18 +289,22 @@ SwTextMeta::CreateTextMeta(
     if (i_bIsCopy)
     {   // i_rAttr is already cloned, now call DoCopy to copy the sw::Meta
         OSL_ENSURE(i_pTargetTextNode, "cannot copy Meta without target node");
-        i_rAttr.DoCopy(i_rTargetDocManager, *i_pTargetTextNode);
+        SwFormatMeta* 
pSwFormatMeta(static_cast<SwFormatMeta*>(const_cast<SfxPoolItem*>(i_rAttr.getItem())));
+        pSwFormatMeta->DoCopy(i_rTargetDocManager, *i_pTargetTextNode);
     }
     SwTextMeta *const pTextMeta(new SwTextMeta(i_rAttr, i_nStart, i_nEnd));
     return pTextMeta;
 }
 
-SwTextMeta::SwTextMeta( SwFormatMeta & i_rAttr,
-        const sal_Int32 i_nStart, const sal_Int32 i_nEnd )
+SwTextMeta::SwTextMeta(
+    const SfxPoolItemHolder& i_rAttr,
+    const sal_Int32 i_nStart,
+    const sal_Int32 i_nEnd )
     : SwTextAttr( i_rAttr, i_nStart )
     , SwTextAttrNesting( i_rAttr, i_nStart, i_nEnd )
 {
-    i_rAttr.SetTextAttr( this );
+    SwFormatMeta& rSwFormatMeta(static_cast<SwFormatMeta&>(GetAttr()));
+    rSwFormatMeta.SetTextAttr( this );
     SetHasDummyChar(true);
 }
 
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
index 426be22dcc25..7e54ef4a66dc 100644
--- a/sw/source/core/undo/rolbck.cxx
+++ b/sw/source/core/undo/rolbck.cxx
@@ -500,14 +500,14 @@ void SwHistorySetFootnote::SetInDoc( SwDoc* pDoc, bool )
     if (m_pUndo)
     {
         // set the footnote in the TextNode
-        SwFormatFootnote aTemp( m_bEndNote );
-        SwFormatFootnote& rNew = const_cast<SwFormatFootnote&>(
-                pDoc->GetAttrPool().DirectPutItemInPool(aTemp) );
+        SwFormatFootnote aNew( m_bEndNote );
         if ( !m_FootnoteNumber.isEmpty() )
         {
-            rNew.SetNumStr( m_FootnoteNumber );
+            aNew.SetNumStr( m_FootnoteNumber );
         }
-        SwTextFootnote* pTextFootnote = new SwTextFootnote( rNew, m_nStart );
+        SwTextFootnote* pTextFootnote = new SwTextFootnote(
+            SfxPoolItemHolder(pDoc->GetAttrPool(), &aNew),
+            m_nStart );
 
         // create the section of the Footnote
         SwNodeIndex aIdx( *pTextNd );

Reply via email to