editeng/inc/editattr.hxx                |   60 +++++------
 editeng/inc/editdoc.hxx                 |   16 +--
 editeng/source/editeng/editattr.cxx     |  164 +++++++++++++++----------------
 editeng/source/editeng/editdoc.cxx      |  167 +++++++++++---------------------
 editeng/source/editeng/editeng.cxx      |    5 
 editeng/source/editeng/editobj.cxx      |   37 +------
 editeng/source/editeng/editobj2.hxx     |   11 --
 editeng/source/editeng/editundo.cxx     |   20 ---
 editeng/source/editeng/editview.cxx     |   12 +-
 editeng/source/editeng/fieldupdater.cxx |    2 
 editeng/source/editeng/impedit.cxx      |    6 -
 editeng/source/editeng/impedit.hxx      |    1 
 editeng/source/editeng/impedit2.cxx     |   24 +---
 editeng/source/editeng/impedit4.cxx     |    4 
 editeng/source/editeng/impedit5.cxx     |    5 
 include/editeng/editeng.hxx             |    1 
 include/svl/itemset.hxx                 |   18 +++
 svl/source/items/itempool.cxx           |   13 +-
 svl/source/items/itemset.cxx            |   59 +++++++++++
 vcl/source/app/svapp.cxx                |    4 
 20 files changed, 306 insertions(+), 323 deletions(-)

New commits:
commit 52b692d16bc9b373067f3748fabf31aeace6e201
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Fri Nov 24 16:12:03 2023 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Sat Nov 25 16:13:47 2023 +0100

    tdf#158317 fix cleanup of SfxPoolItems in editeng
    
    It is not possible to use implCreateItemEntry/implCleanupItemEntry,
    that is tooling limited *by purpose* to svl/Item/ItemSet stuff.
    But what I can do is to do that SfxPoolItemHolder I already
    talked/thought about. It is a helper that can safely hold a
    SfxPoolItem in cases where an SfxItemSet is too expensive.
    Think about it as a SfxItemSet for a single item. That solves
    the problem why DirectPutItemInPool/DirectRemoveItemFromPool
    is used in general (each usage is a 'compromize').
    Did that now, works well. Editengine is now free of
    DirectPutItemInPool/DirectRemoveItemFromPool.
    
    Replaced ::CursorMoved with checkAndDeleteEmptyAttribs since all
    these got static with no longer need to DirectRemoveItemFromPool.
    Corrected create/delete counters.
    
    Change-Id: Ia6e53f48ac2e479b461546515e68697039b5b628
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159931
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/editeng/inc/editattr.hxx b/editeng/inc/editattr.hxx
index fcc14ba5ce25..bb609ac1e996 100644
--- a/editeng/inc/editattr.hxx
+++ b/editeng/inc/editattr.hxx
@@ -25,6 +25,7 @@
 #include <tools/color.hxx>
 #include <tools/debug.hxx>
 #include <tools/fontenum.hxx>
+#include <svl/itemset.hxx>
 
 class SvxFont;
 class SvxFontItem;
@@ -65,7 +66,7 @@ class SfxGrabBagItem;
 // bEdge: Attribute will not expand, if you want to expand just on the edge
 class EditCharAttrib
 {
-    const SfxPoolItem*  pItem;
+    SfxPoolItemHolder   maItemHolder;
 
     sal_Int32               nStart;
     sal_Int32               nEnd;
@@ -73,7 +74,7 @@ class EditCharAttrib
     bool                bEdge       :1;
 
 public:
-    EditCharAttrib( const SfxPoolItem& rAttr, sal_Int32 nStart, sal_Int32 nEnd 
);
+    EditCharAttrib(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
     virtual ~EditCharAttrib();
 
     EditCharAttrib(const EditCharAttrib&) = delete;
@@ -81,8 +82,9 @@ public:
 
     void                dumpAsXml(xmlTextWriterPtr pWriter) const;
 
-    sal_uInt16          Which() const   { return pItem->Which(); }
-    const SfxPoolItem*  GetItem() const { return pItem; }
+    const SfxPoolItemHolder& GetHolder() const {  return maItemHolder; }
+    const SfxPoolItem* GetItem() const { return GetHolder().getItem(); }
+    sal_uInt16 Which() const { if(GetItem()) return GetItem()->Which(); return 
0; }
 
     sal_Int32&          GetStart()                  { return nStart; }
     sal_Int32&          GetEnd()                    { return nEnd; }
@@ -153,7 +155,7 @@ inline void EditCharAttrib::Collaps( sal_Int32 nDiff )
 class EditCharAttribFont final : public EditCharAttrib
 {
 public:
-    EditCharAttribFont( const SvxFontItem& rAttr, sal_Int32 nStart, sal_Int32 
nEnd );
+    EditCharAttribFont(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -163,7 +165,7 @@ public:
 class EditCharAttribWeight final : public EditCharAttrib
 {
 public:
-    EditCharAttribWeight( const SvxWeightItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribWeight(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -172,7 +174,7 @@ public:
 class EditCharAttribItalic final : public EditCharAttrib
 {
 public:
-    EditCharAttribItalic( const SvxPostureItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribItalic(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -182,7 +184,7 @@ public:
 class EditCharAttribShadow final : public EditCharAttrib
 {
 public:
-    EditCharAttribShadow( const SvxShadowedItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribShadow(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -192,7 +194,7 @@ public:
 class EditCharAttribEscapement final : public EditCharAttrib
 {
 public:
-    EditCharAttribEscapement( const SvxEscapementItem& rAttr, sal_Int32 
nStart, sal_Int32 nEnd );
+    EditCharAttribEscapement(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -202,7 +204,7 @@ public:
 class EditCharAttribOutline final : public EditCharAttrib
 {
 public:
-    EditCharAttribOutline( const SvxContourItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribOutline(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -212,7 +214,7 @@ public:
 class EditCharAttribStrikeout final : public EditCharAttrib
 {
 public:
-    EditCharAttribStrikeout( const SvxCrossedOutItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribStrikeout(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -222,7 +224,7 @@ public:
 class EditCharAttribCaseMap final : public EditCharAttrib
 {
 public:
-    EditCharAttribCaseMap( const SvxCaseMapItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribCaseMap(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -232,7 +234,7 @@ public:
 class EditCharAttribUnderline final : public EditCharAttrib
 {
 public:
-    EditCharAttribUnderline( const SvxUnderlineItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribUnderline(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -242,7 +244,7 @@ public:
 class EditCharAttribOverline final : public EditCharAttrib
 {
 public:
-    EditCharAttribOverline( const SvxOverlineItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribOverline(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -252,7 +254,7 @@ public:
 class EditCharAttribEmphasisMark final : public EditCharAttrib
 {
 public:
-    EditCharAttribEmphasisMark( const SvxEmphasisMarkItem& rAttr, sal_Int32 
nStart, sal_Int32 nEnd );
+    EditCharAttribEmphasisMark(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -262,7 +264,7 @@ public:
 class EditCharAttribRelief final : public EditCharAttrib
 {
 public:
-    EditCharAttribRelief( const SvxCharReliefItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribRelief(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -272,7 +274,7 @@ public:
 class EditCharAttribFontHeight final : public EditCharAttrib
 {
 public:
-    EditCharAttribFontHeight( const SvxFontHeightItem& rAttr, sal_Int32 
nStart, sal_Int32 nEnd );
+    EditCharAttribFontHeight(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -282,7 +284,7 @@ public:
 class EditCharAttribFontWidth final : public EditCharAttrib
 {
 public:
-    EditCharAttribFontWidth( const SvxCharScaleWidthItem& rAttr, sal_Int32 
nStart, sal_Int32 nEnd );
+    EditCharAttribFontWidth(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -292,7 +294,7 @@ public:
 class EditCharAttribColor final : public EditCharAttrib
 {
 public:
-    EditCharAttribColor( const SvxColorItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribColor(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -301,9 +303,7 @@ public:
 class EditCharAttribBackgroundColor final : public EditCharAttrib
 {
 public:
-    EditCharAttribBackgroundColor(const SvxColorItem& rAttr,
-                                  sal_Int32 nStart,
-                                  sal_Int32 nEnd );
+    EditCharAttribBackgroundColor(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
     virtual void    SetFont(SvxFont& rFont, OutputDevice* pOutDev) override;
 };
 
@@ -312,7 +312,7 @@ public:
 class EditCharAttribLanguage final : public EditCharAttrib
 {
 public:
-    EditCharAttribLanguage( const SvxLanguageItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribLanguage(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -322,7 +322,7 @@ public:
 class EditCharAttribTab final : public EditCharAttrib
 {
 public:
-    EditCharAttribTab( const SfxVoidItem& rAttr, sal_Int32 nPos );
+    EditCharAttribTab(SfxItemPool&, const SfxPoolItem&, sal_Int32 nPos);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -332,7 +332,7 @@ public:
 class EditCharAttribLineBreak final : public EditCharAttrib
 {
 public:
-    EditCharAttribLineBreak( const SfxVoidItem& rAttr, sal_Int32 nPos );
+    EditCharAttribLineBreak(SfxItemPool&, const SfxPoolItem&, sal_Int32 nPos);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -349,7 +349,7 @@ class EditCharAttribField final : public EditCharAttrib
     EditCharAttribField& operator = ( const EditCharAttribField& rAttr ) = 
delete;
 
 public:
-    EditCharAttribField( const SvxFieldItem& rAttr, sal_Int32 nPos );
+    EditCharAttribField(SfxItemPool&, const SfxPoolItem&, sal_Int32 nPos);
     EditCharAttribField( const EditCharAttribField& rAttr );
     virtual ~EditCharAttribField() override;
 
@@ -373,7 +373,7 @@ public:
 class EditCharAttribPairKerning final : public EditCharAttrib
 {
 public:
-    EditCharAttribPairKerning( const SvxAutoKernItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribPairKerning(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -383,7 +383,7 @@ public:
 class EditCharAttribKerning final : public EditCharAttrib
 {
 public:
-    EditCharAttribKerning( const SvxKerningItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribKerning(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -393,7 +393,7 @@ public:
 class EditCharAttribWordLineMode final : public EditCharAttrib
 {
 public:
-    EditCharAttribWordLineMode( const SvxWordLineModeItem& rAttr, sal_Int32 
nStart, sal_Int32 nEnd );
+    EditCharAttribWordLineMode(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
 
     virtual void    SetFont( SvxFont& rFont, OutputDevice* pOutDev ) override;
 };
@@ -402,7 +402,7 @@ public:
 class EditCharAttribGrabBag final : public EditCharAttrib
 {
 public:
-    EditCharAttribGrabBag( const SfxGrabBagItem& rAttr, sal_Int32 nStart, 
sal_Int32 nEnd );
+    EditCharAttribGrabBag(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd);
 };
 
 
diff --git a/editeng/inc/editdoc.hxx b/editeng/inc/editdoc.hxx
index e5c3abbef0cf..16eaf157a91f 100644
--- a/editeng/inc/editdoc.hxx
+++ b/editeng/inc/editdoc.hxx
@@ -122,7 +122,6 @@ public:
     const SfxItemSet&       GetPrevParaAttribs() const  { return 
aPrevParaAttribs; }
     const CharAttribsType&  GetPrevCharAttribs() const  { return 
aPrevCharAttribs; }
 
-    void RemoveAllCharAttribsFromPool(SfxItemPool& rPool) const;
     void AppendCharAttrib(EditCharAttrib* pNew);
 };
 
@@ -196,7 +195,7 @@ public:
 
     void            dumpAsXml(xmlTextWriterPtr pWriter) const;
 
-    void            DeleteEmptyAttribs(  SfxItemPool& rItemPool );
+    void            DeleteEmptyAttribs();
 
     const EditCharAttrib* FindAttrib( sal_uInt16 nWhich, sal_Int32 nPos ) 
const;
     EditCharAttrib* FindAttrib( sal_uInt16 nWhich, sal_Int32 nPos );
@@ -206,7 +205,7 @@ public:
 
 
     void            ResortAttribs();
-    void            OptimizeRanges( SfxItemPool& rItemPool );
+    void            OptimizeRanges();
 
     sal_Int32 Count() const;
 
@@ -256,8 +255,8 @@ public:
     CharAttribList& GetCharAttribs()        { return aCharAttribList; }
     const CharAttribList& GetCharAttribs() const { return aCharAttribList; }
 
-    void            ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNewChars, 
SfxItemPool& rItemPool );
-    void            CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDelChars, 
SfxItemPool& rItemPool );
+    void            ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNewChars );
+    void            CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDelChars );
     void            AppendAttribs( ContentNode* pNextNode );
     void            CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& 
rPool, bool bKeepEndingAttribs );
 
@@ -295,6 +294,8 @@ public:
     OUString Copy(sal_Int32 nPos) const;
     OUString Copy(sal_Int32 nPos, sal_Int32 nCount) const;
     sal_Unicode GetChar(sal_Int32 nPos) const;
+
+    void checkAndDeleteEmptyAttribs() const;
 };
 
 
@@ -759,9 +760,6 @@ private:
     bool            bModified:1;
     bool            bDisableAttributeExpanding:1;
 
-private:
-    void            ImplDestroyContents();
-
 public:
                     EditDoc( SfxItemPool* pItemPool );
                     ~EditDoc();
@@ -812,8 +810,6 @@ public:
     SfxItemPool&        GetItemPool()                   { return *pItemPool; }
     const SfxItemPool&  GetItemPool() const             { return *pItemPool; }
 
-    void RemoveItemsFromPool(const ContentNode& rNode);
-
     void            InsertAttrib( const SfxPoolItem& rItem, ContentNode* 
pNode, sal_Int32 nStart, sal_Int32 nEnd );
     void            InsertAttrib( ContentNode* pNode, sal_Int32 nStart, 
sal_Int32 nEnd, const SfxPoolItem& rPoolItem );
     void            InsertAttribInSelection( ContentNode* pNode, sal_Int32 
nStart, sal_Int32 nEnd, const SfxPoolItem& rPoolItem );
diff --git a/editeng/source/editeng/editattr.cxx 
b/editeng/source/editeng/editattr.cxx
index d1d79fd0263e..75bbcabc5a66 100644
--- a/editeng/source/editeng/editattr.cxx
+++ b/editeng/source/editeng/editattr.cxx
@@ -46,14 +46,15 @@
 #include <editattr.hxx>
 
 
-
-EditCharAttrib::EditCharAttrib( const SfxPoolItem& rAttr, sal_Int32 nS, 
sal_Int32 nE ) :
-    nStart(nS), nEnd(nE), bFeature(false), bEdge(false)
+EditCharAttrib::EditCharAttrib(SfxItemPool& rPool, const SfxPoolItem& rItem, 
sal_Int32 nS, sal_Int32 nE )
+: maItemHolder(rPool, &rItem)
+, nStart(nS)
+, nEnd(nE)
+, bFeature(false)
+, bEdge(false)
 {
-    pItem = &rAttr;
-
-    assert((rAttr.Which() >= EE_ITEMS_START) && (rAttr.Which() <= 
EE_ITEMS_END));
-    assert((rAttr.Which() < EE_FEATURE_START) || (rAttr.Which() > 
EE_FEATURE_END) || (nE == (nS+1)));
+    assert((rItem.Which() >= EE_ITEMS_START) && (rItem.Which() <= 
EE_ITEMS_END));
+    assert((rItem.Which() < EE_FEATURE_START) || (rItem.Which() > 
EE_FEATURE_END) || (nE == (nS+1)));
 }
 
 EditCharAttrib::~EditCharAttrib()
@@ -71,16 +72,16 @@ void EditCharAttrib::dumpAsXml(xmlTextWriterPtr pWriter) 
const
     pWriter, BAD_CAST("nStart"), "%" SAL_PRIdINT32, nStart);
     (void)xmlTextWriterWriteFormatAttribute(
     pWriter, BAD_CAST("nEnd"), "%" SAL_PRIdINT32, nEnd);
-    pItem->dumpAsXml(pWriter);
+    GetItem()->dumpAsXml(pWriter);
     (void)xmlTextWriterEndElement(pWriter);
 }
 
 
 
-EditCharAttribFont::EditCharAttribFont( const SvxFontItem& rAttr, sal_Int32 
_nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribFont::EditCharAttribFont(SfxItemPool& rPool, const SfxPoolItem& 
rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_FONTINFO || rAttr.Which() == 
EE_CHAR_FONTINFO_CJK || rAttr.Which() == EE_CHAR_FONTINFO_CTL);
+    assert(rItem.Which() == EE_CHAR_FONTINFO || rItem.Which() == 
EE_CHAR_FONTINFO_CJK || rItem.Which() == EE_CHAR_FONTINFO_CTL);
 }
 
 void EditCharAttribFont::SetFont( SvxFont& rFont, OutputDevice* )
@@ -95,10 +96,10 @@ void EditCharAttribFont::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribItalic::EditCharAttribItalic( const SvxPostureItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribItalic::EditCharAttribItalic(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_ITALIC || rAttr.Which() == 
EE_CHAR_ITALIC_CJK || rAttr.Which() == EE_CHAR_ITALIC_CTL);
+    assert(rItem.Which() == EE_CHAR_ITALIC || rItem.Which() == 
EE_CHAR_ITALIC_CJK || rItem.Which() == EE_CHAR_ITALIC_CTL);
 }
 
 void EditCharAttribItalic::SetFont( SvxFont& rFont, OutputDevice* )
@@ -108,10 +109,10 @@ void EditCharAttribItalic::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribWeight::EditCharAttribWeight( const SvxWeightItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribWeight::EditCharAttribWeight(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_WEIGHT || rAttr.Which() == 
EE_CHAR_WEIGHT_CJK || rAttr.Which() == EE_CHAR_WEIGHT_CTL);
+    assert(rItem.Which() == EE_CHAR_WEIGHT || rItem.Which() == 
EE_CHAR_WEIGHT_CJK || rItem.Which() == EE_CHAR_WEIGHT_CTL);
 }
 
 void EditCharAttribWeight::SetFont( SvxFont& rFont, OutputDevice* )
@@ -121,10 +122,10 @@ void EditCharAttribWeight::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribUnderline::EditCharAttribUnderline( const SvxUnderlineItem& 
rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribUnderline::EditCharAttribUnderline(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_UNDERLINE);
+    assert(rItem.Which() == EE_CHAR_UNDERLINE);
 }
 
 void EditCharAttribUnderline::SetFont( SvxFont& rFont, OutputDevice* pOutDev )
@@ -138,10 +139,10 @@ void EditCharAttribUnderline::SetFont( SvxFont& rFont, 
OutputDevice* pOutDev )
 
 
 
-EditCharAttribOverline::EditCharAttribOverline( const SvxOverlineItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribOverline::EditCharAttribOverline(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_OVERLINE);
+    assert(rItem.Which() == EE_CHAR_OVERLINE);
 }
 
 void EditCharAttribOverline::SetFont( SvxFont& rFont, OutputDevice* pOutDev )
@@ -153,10 +154,10 @@ void EditCharAttribOverline::SetFont( SvxFont& rFont, 
OutputDevice* pOutDev )
 
 
 
-EditCharAttribFontHeight::EditCharAttribFontHeight( const SvxFontHeightItem& 
rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribFontHeight::EditCharAttribFontHeight(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_FONTHEIGHT || rAttr.Which() == 
EE_CHAR_FONTHEIGHT_CJK || rAttr.Which() == EE_CHAR_FONTHEIGHT_CTL);
+    assert(rItem.Which() == EE_CHAR_FONTHEIGHT || rItem.Which() == 
EE_CHAR_FONTHEIGHT_CJK || rItem.Which() == EE_CHAR_FONTHEIGHT_CTL);
 }
 
 void EditCharAttribFontHeight::SetFont( SvxFont& rFont, OutputDevice* )
@@ -167,10 +168,10 @@ void EditCharAttribFontHeight::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribFontWidth::EditCharAttribFontWidth( const SvxCharScaleWidthItem& 
rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribFontWidth::EditCharAttribFontWidth(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_FONTWIDTH);
+    assert(rItem.Which() == EE_CHAR_FONTWIDTH);
 }
 
 void EditCharAttribFontWidth::SetFont( SvxFont& /*rFont*/, OutputDevice* )
@@ -180,10 +181,10 @@ void EditCharAttribFontWidth::SetFont( SvxFont& 
/*rFont*/, OutputDevice* )
 
 
 
-EditCharAttribStrikeout::EditCharAttribStrikeout( const SvxCrossedOutItem& 
rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribStrikeout::EditCharAttribStrikeout(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_STRIKEOUT);
+    assert(rItem.Which() == EE_CHAR_STRIKEOUT);
 }
 
 void EditCharAttribStrikeout::SetFont( SvxFont& rFont, OutputDevice* )
@@ -193,10 +194,10 @@ void EditCharAttribStrikeout::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribCaseMap::EditCharAttribCaseMap( const SvxCaseMapItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribCaseMap::EditCharAttribCaseMap(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_CASEMAP);
+    assert(rItem.Which() == EE_CHAR_CASEMAP);
 }
 
 void EditCharAttribCaseMap::SetFont( SvxFont& rFont, OutputDevice* )
@@ -206,10 +207,10 @@ void EditCharAttribCaseMap::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribColor::EditCharAttribColor( const SvxColorItem& rAttr, sal_Int32 
_nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribColor::EditCharAttribColor(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_COLOR);
+    assert(rItem.Which() == EE_CHAR_COLOR);
 }
 
 void EditCharAttribColor::SetFont( SvxFont& rFont, OutputDevice* )
@@ -219,13 +220,10 @@ void EditCharAttribColor::SetFont( SvxFont& rFont, 
OutputDevice* )
 }
 
 
-EditCharAttribBackgroundColor::EditCharAttribBackgroundColor(
-                                const SvxColorItem& rAttr,
-                                  sal_Int32 _nStart,
-                                  sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribBackgroundColor::EditCharAttribBackgroundColor(SfxItemPool& 
rPool, const SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_BKGCOLOR);
+    assert(rItem.Which() == EE_CHAR_BKGCOLOR);
 }
 
 void EditCharAttribBackgroundColor::SetFont( SvxFont& rFont, OutputDevice* )
@@ -235,10 +233,10 @@ void EditCharAttribBackgroundColor::SetFont( SvxFont& 
rFont, OutputDevice* )
     rFont.SetFillColor(aColor);
 }
 
-EditCharAttribLanguage::EditCharAttribLanguage( const SvxLanguageItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribLanguage::EditCharAttribLanguage(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert((rAttr.Which() == EE_CHAR_LANGUAGE) || (rAttr.Which() == 
EE_CHAR_LANGUAGE_CJK) || (rAttr.Which() == EE_CHAR_LANGUAGE_CTL));
+    assert((rItem.Which() == EE_CHAR_LANGUAGE) || (rItem.Which() == 
EE_CHAR_LANGUAGE_CJK) || (rItem.Which() == EE_CHAR_LANGUAGE_CTL));
 }
 
 void EditCharAttribLanguage::SetFont( SvxFont& rFont, OutputDevice* )
@@ -248,10 +246,10 @@ void EditCharAttribLanguage::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribShadow::EditCharAttribShadow( const SvxShadowedItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribShadow::EditCharAttribShadow(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_SHADOW);
+    assert(rItem.Which() == EE_CHAR_SHADOW);
 }
 
 void EditCharAttribShadow::SetFont( SvxFont& rFont, OutputDevice* )
@@ -261,10 +259,10 @@ void EditCharAttribShadow::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribEscapement::EditCharAttribEscapement( const SvxEscapementItem& 
rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribEscapement::EditCharAttribEscapement(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_ESCAPEMENT);
+    assert(rItem.Which() == EE_CHAR_ESCAPEMENT);
 }
 
 void EditCharAttribEscapement::SetFont( SvxFont& rFont, OutputDevice* pOutDev )
@@ -278,10 +276,10 @@ void EditCharAttribEscapement::SetFont( SvxFont& rFont, 
OutputDevice* pOutDev )
 
 
 
-EditCharAttribOutline::EditCharAttribOutline( const SvxContourItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribOutline::EditCharAttribOutline(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_OUTLINE);
+    assert(rItem.Which() == EE_CHAR_OUTLINE);
 }
 
 void EditCharAttribOutline::SetFont( SvxFont& rFont, OutputDevice* )
@@ -291,8 +289,8 @@ void EditCharAttribOutline::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribTab::EditCharAttribTab( const SfxVoidItem& rAttr, sal_Int32 nPos 
)
-    : EditCharAttrib( rAttr, nPos, nPos+1 )
+EditCharAttribTab::EditCharAttribTab(SfxItemPool& rPool, const SfxPoolItem& 
rItem, sal_Int32 nPos)
+: EditCharAttrib(rPool, rItem, nPos, nPos+1)
 {
     SetFeature( true );
 }
@@ -303,8 +301,8 @@ void EditCharAttribTab::SetFont( SvxFont&, OutputDevice* )
 
 
 
-EditCharAttribLineBreak::EditCharAttribLineBreak( const SfxVoidItem& rAttr, 
sal_Int32 nPos )
-    : EditCharAttrib( rAttr, nPos, nPos+1 )
+EditCharAttribLineBreak::EditCharAttribLineBreak(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 nPos)
+: EditCharAttrib(rPool, rItem, nPos, nPos+1)
 {
     SetFeature( true );
 }
@@ -315,8 +313,8 @@ void EditCharAttribLineBreak::SetFont( SvxFont&, 
OutputDevice* )
 
 
 
-EditCharAttribField::EditCharAttribField( const SvxFieldItem& rAttr, sal_Int32 
nPos )
-    : EditCharAttrib( rAttr, nPos, nPos+1 )
+EditCharAttribField::EditCharAttribField(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 nPos)
+: EditCharAttrib(rPool, rItem, nPos, nPos+1)
 {
     SetFeature( true ); // !!!
 }
@@ -348,9 +346,9 @@ void EditCharAttribField::Reset()
     mxFldLineStyle.reset();
 }
 
-EditCharAttribField::EditCharAttribField( const EditCharAttribField& rAttr )
-    : EditCharAttrib( *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd() ),
-        aFieldValue( rAttr.aFieldValue )
+EditCharAttribField::EditCharAttribField(const EditCharAttribField& rAttr)
+: EditCharAttrib(rAttr.GetHolder().getPool(), *rAttr.GetHolder().getItem(), 
rAttr.GetStart(), rAttr.GetEnd())
+, aFieldValue( rAttr.aFieldValue )
 {
     // Use this constructor only for temporary Objects, Item is not pooled.
     mxTxtColor = rAttr.mxTxtColor;
@@ -388,10 +386,10 @@ bool EditCharAttribField::operator == ( const 
EditCharAttribField& rAttr ) const
 
 
 
-EditCharAttribPairKerning::EditCharAttribPairKerning( const SvxAutoKernItem& 
rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-: EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribPairKerning::EditCharAttribPairKerning(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_PAIRKERNING);
+    assert(rItem.Which() == EE_CHAR_PAIRKERNING);
 }
 
 void EditCharAttribPairKerning::SetFont( SvxFont& rFont, OutputDevice* )
@@ -401,10 +399,10 @@ void EditCharAttribPairKerning::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribKerning::EditCharAttribKerning( const SvxKerningItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-: EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribKerning::EditCharAttribKerning(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_KERNING);
+    assert(rItem.Which() == EE_CHAR_KERNING);
 }
 
 void EditCharAttribKerning::SetFont( SvxFont& rFont, OutputDevice* )
@@ -414,10 +412,10 @@ void EditCharAttribKerning::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribWordLineMode::EditCharAttribWordLineMode( const 
SvxWordLineModeItem& rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-: EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribWordLineMode::EditCharAttribWordLineMode(SfxItemPool& rPool, 
const SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_WLM);
+    assert(rItem.Which() == EE_CHAR_WLM);
 }
 
 void EditCharAttribWordLineMode::SetFont( SvxFont& rFont, OutputDevice* )
@@ -427,10 +425,10 @@ void EditCharAttribWordLineMode::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribEmphasisMark::EditCharAttribEmphasisMark( const 
SvxEmphasisMarkItem& rAttr, sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribEmphasisMark::EditCharAttribEmphasisMark(SfxItemPool& rPool, 
const SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_EMPHASISMARK);
+    assert(rItem.Which() == EE_CHAR_EMPHASISMARK);
 }
 
 void EditCharAttribEmphasisMark::SetFont( SvxFont& rFont, OutputDevice* )
@@ -440,10 +438,10 @@ void EditCharAttribEmphasisMark::SetFont( SvxFont& rFont, 
OutputDevice* )
 
 
 
-EditCharAttribRelief::EditCharAttribRelief( const SvxCharReliefItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribRelief::EditCharAttribRelief(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_RELIEF);
+    assert(rItem.Which() == EE_CHAR_RELIEF);
 }
 
 void EditCharAttribRelief::SetFont( SvxFont& rFont, OutputDevice* )
@@ -452,10 +450,10 @@ void EditCharAttribRelief::SetFont( SvxFont& rFont, 
OutputDevice* )
 }
 
 
-EditCharAttribGrabBag::EditCharAttribGrabBag( const SfxGrabBagItem& rAttr, 
sal_Int32 _nStart, sal_Int32 _nEnd )
-    : EditCharAttrib( rAttr, _nStart, _nEnd )
+EditCharAttribGrabBag::EditCharAttribGrabBag(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
+: EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
-    assert(rAttr.Which() == EE_CHAR_GRABBAG);
+    assert(rItem.Which() == EE_CHAR_GRABBAG);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/editeng/source/editeng/editdoc.cxx 
b/editeng/source/editeng/editdoc.cxx
index 7a5d70b34567..d892bd1c3a25 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -222,152 +222,149 @@ const SfxItemInfo aItemInfos[EDITITEMCOUNT] =
 EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, 
sal_Int32 nS, sal_Int32 nE )
 {
     // Create a new attribute in the pool
-    const SfxPoolItem& rNew = rPool.DirectPutItemInPool( rAttr );
-
-    EditCharAttrib* pNew = nullptr;
-    switch( rNew.Which() )
+    switch( rAttr.Which() )
     {
         case EE_CHAR_LANGUAGE:
         case EE_CHAR_LANGUAGE_CJK:
         case EE_CHAR_LANGUAGE_CTL:
         {
-            pNew = new EditCharAttribLanguage( static_cast<const 
SvxLanguageItem&>(rNew), nS, nE );
+            return new EditCharAttribLanguage(rPool, rAttr, nS, nE);
         }
         break;
         case EE_CHAR_COLOR:
         {
-            pNew = new EditCharAttribColor( static_cast<const 
SvxColorItem&>(rNew), nS, nE );
+            return new EditCharAttribColor(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_FONTINFO:
         case EE_CHAR_FONTINFO_CJK:
         case EE_CHAR_FONTINFO_CTL:
         {
-            pNew = new EditCharAttribFont( static_cast<const 
SvxFontItem&>(rNew), nS, nE );
+            return new EditCharAttribFont(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_FONTHEIGHT:
         case EE_CHAR_FONTHEIGHT_CJK:
         case EE_CHAR_FONTHEIGHT_CTL:
         {
-            pNew = new EditCharAttribFontHeight( static_cast<const 
SvxFontHeightItem&>(rNew), nS, nE );
+            return new EditCharAttribFontHeight(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_FONTWIDTH:
         {
-            pNew = new EditCharAttribFontWidth( static_cast<const 
SvxCharScaleWidthItem&>(rNew), nS, nE );
+            return new EditCharAttribFontWidth(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_WEIGHT:
         case EE_CHAR_WEIGHT_CJK:
         case EE_CHAR_WEIGHT_CTL:
         {
-            pNew = new EditCharAttribWeight( static_cast<const 
SvxWeightItem&>(rNew), nS, nE );
+            return new EditCharAttribWeight(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_UNDERLINE:
         {
-            pNew = new EditCharAttribUnderline( static_cast<const 
SvxUnderlineItem&>(rNew), nS, nE );
+            return new EditCharAttribUnderline(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_OVERLINE:
         {
-            pNew = new EditCharAttribOverline( static_cast<const 
SvxOverlineItem&>(rNew), nS, nE );
+            return new EditCharAttribOverline(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_EMPHASISMARK:
         {
-            pNew = new EditCharAttribEmphasisMark( static_cast<const 
SvxEmphasisMarkItem&>(rNew), nS, nE );
+            return new EditCharAttribEmphasisMark(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_RELIEF:
         {
-            pNew = new EditCharAttribRelief( static_cast<const 
SvxCharReliefItem&>(rNew), nS, nE );
+            return new EditCharAttribRelief(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_STRIKEOUT:
         {
-            pNew = new EditCharAttribStrikeout( static_cast<const 
SvxCrossedOutItem&>(rNew), nS, nE );
+            return new EditCharAttribStrikeout(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_ITALIC:
         case EE_CHAR_ITALIC_CJK:
         case EE_CHAR_ITALIC_CTL:
         {
-            pNew = new EditCharAttribItalic( static_cast<const 
SvxPostureItem&>(rNew), nS, nE );
+            return new EditCharAttribItalic(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_OUTLINE:
         {
-            pNew = new EditCharAttribOutline( static_cast<const 
SvxContourItem&>(rNew), nS, nE );
+            return new EditCharAttribOutline(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_SHADOW:
         {
-            pNew = new EditCharAttribShadow( static_cast<const 
SvxShadowedItem&>(rNew), nS, nE );
+            return new EditCharAttribShadow(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_ESCAPEMENT:
         {
-            pNew = new EditCharAttribEscapement( static_cast<const 
SvxEscapementItem&>(rNew), nS, nE );
+            return new EditCharAttribEscapement(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_PAIRKERNING:
         {
-            pNew = new EditCharAttribPairKerning( static_cast<const 
SvxAutoKernItem&>(rNew), nS, nE );
+            return new EditCharAttribPairKerning(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_KERNING:
         {
-            pNew = new EditCharAttribKerning( static_cast<const 
SvxKerningItem&>(rNew), nS, nE );
+            return new EditCharAttribKerning(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_WLM:
         {
-            pNew = new EditCharAttribWordLineMode( static_cast<const 
SvxWordLineModeItem&>(rNew), nS, nE );
+            return new EditCharAttribWordLineMode(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_XMLATTRIBS:
         {
-            pNew = new EditCharAttrib( rNew, nS, nE );  // Attribute is only 
for holding XML information...
+            return new EditCharAttrib(rPool, rAttr, nS, nE);  // Attribute is 
only for holding XML information...
         }
         break;
         case EE_CHAR_CASEMAP:
         {
-            pNew = new EditCharAttribCaseMap( static_cast<const 
SvxCaseMapItem&>(rNew), nS, nE );
+            return new EditCharAttribCaseMap(rPool, rAttr, nS, nE );
         }
         break;
         case EE_CHAR_GRABBAG:
         {
-            pNew = new EditCharAttribGrabBag( static_cast<const 
SfxGrabBagItem&>(rNew), nS, nE );
+            return new EditCharAttribGrabBag(rPool, rAttr, nS, nE );
         }
         break;
         case EE_FEATURE_TAB:
         {
-            pNew = new EditCharAttribTab( static_cast<const 
SfxVoidItem&>(rNew), nS );
+            return new EditCharAttribTab(rPool, rAttr, nS );
         }
         break;
         case EE_FEATURE_LINEBR:
         {
-            pNew = new EditCharAttribLineBreak( static_cast<const 
SfxVoidItem&>(rNew), nS );
+            return new EditCharAttribLineBreak(rPool, rAttr, nS );
         }
         break;
         case EE_FEATURE_FIELD:
         {
-            pNew = new EditCharAttribField( static_cast<const 
SvxFieldItem&>(rNew), nS );
+            return new EditCharAttribField(rPool, rAttr, nS );
         }
         break;
         case EE_CHAR_BKGCOLOR:
         {
-            pNew = new EditCharAttribBackgroundColor( static_cast<const 
SvxColorItem&>(rNew), nS, nE );
+            return new EditCharAttribBackgroundColor(rPool, rAttr, nS, nE );
         }
         break;
         default:
-        {
-            OSL_FAIL( "Invalid Attribute!" );
-        }
+        break;
     }
-    return pNew;
+
+    OSL_FAIL( "Invalid Attribute!" );
+    return nullptr;
 }
 
 TextPortionList::TextPortionList()
@@ -812,12 +809,6 @@ ContentAttribsInfo::ContentAttribsInfo( SfxItemSet 
aParaAttribs ) :
 {
 }
 
-void ContentAttribsInfo::RemoveAllCharAttribsFromPool(SfxItemPool& rPool) const
-{
-    for (const std::unique_ptr<EditCharAttrib>& rAttrib : aPrevCharAttribs)
-        rPool.DirectRemoveItemFromPool(*rAttrib->GetItem());
-}
-
 void ContentAttribsInfo::AppendCharAttrib(EditCharAttrib* pNew)
 {
     aPrevCharAttribs.push_back(std::unique_ptr<EditCharAttrib>(pNew));
@@ -1212,7 +1203,7 @@ ContentNode::~ContentNode()
 {
 }
 
-void ContentNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew, 
SfxItemPool& rItemPool )
+void ContentNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew )
 {
     if ( !nNew )
         return;
@@ -1330,7 +1321,6 @@ void ContentNode::ExpandAttribs( sal_Int32 nIndex, 
sal_Int32 nNew, SfxItemPool&
         {
             OSL_FAIL( "Empty Attribute after ExpandAttribs?" );
             bResort = true;
-            rItemPool.DirectRemoveItemFromPool( *pAttrib->GetItem() );
             rAttribs.erase(rAttribs.begin()+nAttr);
         }
         else
@@ -1354,7 +1344,7 @@ void ContentNode::ExpandAttribs( sal_Int32 nIndex, 
sal_Int32 nNew, SfxItemPool&
 #endif
 }
 
-void ContentNode::CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDeleted, 
SfxItemPool& rItemPool )
+void ContentNode::CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDeleted )
 {
     if ( !nDeleted )
         return;
@@ -1426,7 +1416,6 @@ void ContentNode::CollapseAttribs( sal_Int32 nIndex, 
sal_Int32 nDeleted, SfxItem
         if ( bDelAttr )
         {
             bResort = true;
-            rItemPool.DirectRemoveItemFromPool( *pAttrib->GetItem() );
             rAttribs.erase(rAttribs.begin()+nAttr);
         }
         else
@@ -1813,6 +1802,14 @@ void ContentNode::dumpAsXml(xmlTextWriterPtr pWriter) 
const
     (void)xmlTextWriterEndElement(pWriter);
 }
 
+void ContentNode::checkAndDeleteEmptyAttribs() const
+{
+    // Delete empty attributes, but only if paragraph is not empty!
+    if (GetCharAttribs().HasEmptyAttribs() && Len())
+    {
+        const_cast<ContentNode*>(this)->GetCharAttribs().DeleteEmptyAttribs();
+    }
+}
 
 ContentAttribs::ContentAttribs( SfxItemPool& rPool )
 : pStyle(nullptr)
@@ -1934,47 +1931,9 @@ EditDoc::EditDoc( SfxItemPool* pPool ) :
 
 EditDoc::~EditDoc()
 {
-    ImplDestroyContents();
-}
-
-namespace {
-
-class RemoveEachItemFromPool
-{
-    EditDoc& mrDoc;
-public:
-    explicit RemoveEachItemFromPool(EditDoc& rDoc) : mrDoc(rDoc) {}
-    void operator() (const std::unique_ptr<ContentNode>& rNode)
-    {
-        mrDoc.RemoveItemsFromPool(*rNode);
-    }
-};
-
-struct ClearSpellErrorsHandler
-{
-    void operator() (std::unique_ptr<ContentNode> const & rNode)
-    {
-        rNode->DestroyWrongList();
-    }
-};
-
-}
-
-void EditDoc::ImplDestroyContents()
-{
-    std::for_each(maContents.begin(), maContents.end(), 
RemoveEachItemFromPool(*this));
     maContents.clear();
 }
 
-void EditDoc::RemoveItemsFromPool(const ContentNode& rNode)
-{
-    for (sal_Int32 nAttr = 0; nAttr < rNode.GetCharAttribs().Count(); ++nAttr)
-    {
-        const EditCharAttrib& rAttr = 
*rNode.GetCharAttribs().GetAttribs()[nAttr];
-        GetItemPool().DirectRemoveItemFromPool(*rAttr.GetItem());
-    }
-}
-
 void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent, 
SvtScriptType nScriptType )
 {
     vcl::Font aPrevFont( rFont );
@@ -2223,7 +2182,7 @@ sal_Int32 EditDoc::GetTextLen() const
 
 EditPaM EditDoc::Clear()
 {
-    ImplDestroyContents();
+    maContents.clear();
 
     ContentNode* pNode = new ContentNode( GetItemPool() );
     Insert(0, pNode);
@@ -2235,6 +2194,17 @@ EditPaM EditDoc::Clear()
     return EditPaM( pNode, 0 );
 }
 
+namespace
+{
+struct ClearSpellErrorsHandler
+{
+    void operator() (std::unique_ptr<ContentNode> const & rNode)
+    {
+        rNode->DestroyWrongList();
+    }
+};
+}
+
 void EditDoc::ClearSpellErrors()
 {
     std::for_each(maContents.begin(), maContents.end(), 
ClearSpellErrorsHandler());
@@ -2257,7 +2227,7 @@ EditPaM EditDoc::RemoveText()
     SfxItemSet aPrevSet( pPrevFirstNode->GetContentAttribs().GetItems() );
     vcl::Font aPrevFont( pPrevFirstNode->GetCharAttribs().GetDefFont() );
 
-    ImplDestroyContents();
+    maContents.clear();
 
     ContentNode* pNode = new ContentNode( GetItemPool() );
     Insert(0, pNode);
@@ -2279,7 +2249,7 @@ EditPaM EditDoc::InsertText( EditPaM aPaM, 
std::u16string_view rStr )
     assert(aPaM.GetNode());
 
     aPaM.GetNode()->Insert( rStr, aPaM.GetIndex() );
-    aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), rStr.size(), GetItemPool() 
);
+    aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), rStr.size() );
     aPaM.SetIndex( aPaM.GetIndex() + rStr.size() );
 
     SetModified( true );
@@ -2334,7 +2304,7 @@ EditPaM EditDoc::InsertFeature( EditPaM aPaM, const 
SfxPoolItem& rItem  )
     assert(aPaM.GetNode());
 
     aPaM.GetNode()->Insert( rtl::OUStringChar(CH_FEATURE), aPaM.GetIndex() );
-    aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), 1, GetItemPool() );
+    aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), 1 );
 
     // Create a feature-attribute for the feature...
     EditCharAttrib* pAttrib = MakeCharAttrib( GetItemPool(), rItem, 
aPaM.GetIndex(), aPaM.GetIndex()+1 );
@@ -2357,7 +2327,6 @@ EditPaM EditDoc::ConnectParagraphs( ContentNode* pLeft, 
ContentNode* pRight )
     pLeft->Append(pRight->GetString());
 
     // the one to the right disappears.
-    RemoveItemsFromPool(*pRight);
     sal_Int32 nRight = GetPos( pRight );
     Remove( nRight );
 
@@ -2370,7 +2339,7 @@ void EditDoc::RemoveChars( EditPaM aPaM, sal_Int32 nChars 
)
 {
     // Maybe remove Features!
     aPaM.GetNode()->Erase( aPaM.GetIndex(), nChars );
-    aPaM.GetNode()->CollapseAttribs( aPaM.GetIndex(), nChars, GetItemPool() );
+    aPaM.GetNode()->CollapseAttribs( aPaM.GetIndex(), nChars );
 
     SetModified( true );
 }
@@ -2405,7 +2374,6 @@ void EditDoc::InsertAttribInSelection( ContentNode* 
pNode, sal_Int32 nStart, sal
     {
         // Will become a large Attribute.
         pEndingAttrib->GetEnd() = pStartingAttrib->GetEnd();
-        GetItemPool().DirectRemoveItemFromPool( *(pStartingAttrib->GetItem()) 
);
         pNode->GetCharAttribs().Remove(pStartingAttrib);
     }
     else if ( pStartingAttrib && ( *(pStartingAttrib->GetItem()) == rPoolItem 
) )
@@ -2527,7 +2495,6 @@ bool EditDoc::RemoveAttribs( ContentNode* pNode, 
sal_Int32 nStart, sal_Int32 nEn
         {
             DBG_ASSERT( ( pAttr != rpStarting ) && ( pAttr != rpEnding ), 
"Delete and retain the same attribute?" );
             DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a 
feature?!" );
-            GetItemPool().DirectRemoveItemFromPool( *pAttr->GetItem() );
             rAttribs.erase(rAttribs.begin()+nAttr);
         }
         else
@@ -2808,7 +2775,7 @@ void CharAttribList::ResortAttribs()
 #endif
 }
 
-void CharAttribList::OptimizeRanges( SfxItemPool& rItemPool )
+void CharAttribList::OptimizeRanges()
 {
 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
     CharAttribList::DbgCheckAttribs(*this);
@@ -2824,7 +2791,6 @@ void CharAttribList::OptimizeRanges( SfxItemPool& 
rItemPool )
                 if (*rNext.GetItem() == *rAttr.GetItem())
                 {
                     rAttr.GetEnd() = rNext.GetEnd();
-                    rItemPool.DirectRemoveItemFromPool(*rNext.GetItem());
                     aAttribs.erase(aAttribs.begin()+nNext);
                 }
                 break;  // only 1 attr with same which can start here.
@@ -2990,25 +2956,8 @@ const EditCharAttrib* CharAttribList::FindFeature( 
sal_Int32 nPos ) const
     return it == aAttribs.end() ? nullptr : it->get();
 }
 
-namespace {
-
-class RemoveEmptyAttrItem
-{
-    SfxItemPool& mrItemPool;
-public:
-    explicit RemoveEmptyAttrItem(SfxItemPool& rPool) : mrItemPool(rPool) {}
-    void operator() (const std::unique_ptr<EditCharAttrib>& r)
-    {
-        if (r->IsEmpty())
-            mrItemPool.DirectRemoveItemFromPool(*r->GetItem());
-    }
-};
-
-}
-
-void CharAttribList::DeleteEmptyAttribs( SfxItemPool& rItemPool )
+void CharAttribList::DeleteEmptyAttribs()
 {
-    std::for_each(aAttribs.begin(), aAttribs.end(), 
RemoveEmptyAttrItem(rItemPool));
     std::erase_if(aAttribs, [](const std::unique_ptr<EditCharAttrib>& aAttrib) 
{ return aAttrib->IsEmpty(); } );
     bHasEmptyAttribs = false;
 }
diff --git a/editeng/source/editeng/editeng.cxx 
b/editeng/source/editeng/editeng.cxx
index d27a38665950..4dbb93ce2c94 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -678,11 +678,6 @@ ESelection EditEngine::GetWord( const ESelection& 
rSelection, sal_uInt16 nWordTy
     return pE->pImpEditEngine->CreateESel( aSel );
 }
 
-void EditEngine::CursorMoved(const ContentNode* pPrevNode)
-{
-    pImpEditEngine->CursorMoved(pPrevNode);
-}
-
 void EditEngine::CheckIdleFormatter()
 {
     pImpEditEngine->CheckIdleFormatter();
diff --git a/editeng/source/editeng/editobj.cxx 
b/editeng/source/editeng/editobj.cxx
index ba3aac6990e2..762cac112ddb 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -44,30 +44,22 @@ using std::endl;
 using namespace com::sun::star;
 
 
-static XEditAttribute MakeXEditAttribute( SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd )
-{
-    // Create the new attribute in the pool
-    const SfxPoolItem& rNew = rPool.DirectPutItemInPool( rItem );
-
-    return XEditAttribute( rNew, nStart, nEnd );
-}
-
-XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr, sal_Int32 nS, 
sal_Int32 nE )
-    : pItem(&rAttr)
-    , nStart(nS)
-    , nEnd(nE)
+XEditAttribute::XEditAttribute(SfxItemPool& rPool, const SfxPoolItem& rItem, 
sal_Int32 nS, sal_Int32 nE)
+: maItemHolder(rPool, &rItem)
+, nStart(nS)
+, nEnd(nE)
 {
 }
 
 bool XEditAttribute::IsFeature() const
 {
-    sal_uInt16 nWhich = pItem->Which();
+    sal_uInt16 nWhich = GetItem()->Which();
     return  ((nWhich >= EE_FEATURE_START) && (nWhich <=  EE_FEATURE_END));
 }
 
-void XEditAttribute::SetItem(const SfxPoolItem& rNew)
+void XEditAttribute::SetItem(SfxItemPool& rPool, const SfxPoolItem& rItem)
 {
-    pItem = &rNew;
+    maItemHolder = SfxPoolItemHolder(rPool, &rItem);
 }
 
 XParaPortionList::XParaPortionList(OutputDevice* pRefDev, sal_uInt32 nPW,
@@ -110,9 +102,7 @@ ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, 
SfxItemPool& rPoolToUse
 
     for (const XEditAttribute & rAttr : rCopyFrom.maCharAttribs)
     {
-        XEditAttribute aMyAttr = MakeXEditAttribute(
-            rPoolToUse, *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd());
-        maCharAttribs.push_back(aMyAttr);
+        maCharAttribs.emplace_back(rPoolToUse, *rAttr.GetItem(), 
rAttr.GetStart(), rAttr.GetEnd());
     }
 
     if ( rCopyFrom.GetWrongList() )
@@ -121,8 +111,6 @@ ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, 
SfxItemPool& rPoolToUse
 
 ContentInfo::~ContentInfo()
 {
-    for (auto const& charAttrib : maCharAttribs)
-        
aParaAttribs.GetPool()->DirectRemoveItemFromPool(*charAttrib.GetItem());
     maCharAttribs.clear();
 }
 
@@ -376,15 +364,9 @@ TextRotation EditTextObjectImpl::GetRotation() const
 
 XEditAttribute EditTextObjectImpl::CreateAttrib( const SfxPoolItem& rItem, 
sal_Int32 nStart, sal_Int32 nEnd )
 {
-    return MakeXEditAttribute( *mpPool, rItem, nStart, nEnd );
+    return XEditAttribute(*mpPool, rItem, nStart, nEnd);
 }
 
-void EditTextObjectImpl::DestroyAttrib( const XEditAttribute& rAttr )
-{
-    mpPool->DirectRemoveItemFromPool( *rAttr.GetItem() );
-}
-
-
 ContentInfo* EditTextObjectImpl::CreateAndInsertContent()
 {
     maContents.push_back(std::unique_ptr<ContentInfo>(new 
ContentInfo(*mpPool)));
@@ -540,7 +522,6 @@ bool EditTextObjectImpl::RemoveCharAttribs( sal_uInt16 
_nWhich )
             XEditAttribute& rAttr = rC.maCharAttribs[--nAttr];
             if ( !_nWhich || (rAttr.GetItem()->Which() == _nWhich) )
             {
-                mpPool->DirectRemoveItemFromPool(*rAttr.GetItem());
                 rC.maCharAttribs.erase(rC.maCharAttribs.begin()+nAttr);
                 bChanged = true;
             }
diff --git a/editeng/source/editeng/editobj2.hxx 
b/editeng/source/editeng/editobj2.hxx
index 8a714741ebb4..fd1f1437e910 100644
--- a/editeng/source/editeng/editobj2.hxx
+++ b/editeng/source/editeng/editobj2.hxx
@@ -47,14 +47,14 @@ class SharedStringPool;
 class XEditAttribute
 {
 private:
-    const SfxPoolItem*  pItem;
+    SfxPoolItemHolder   maItemHolder;
     sal_Int32           nStart;
     sal_Int32           nEnd;
 
 public:
-    XEditAttribute( const SfxPoolItem& rAttr, sal_Int32 nStart, sal_Int32 nEnd 
);
+    XEditAttribute(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, 
sal_Int32 nEnd );
 
-    const SfxPoolItem*      GetItem() const             { return pItem; }
+    const SfxPoolItem*      GetItem() const             { return 
maItemHolder.getItem(); }
 
     sal_Int32&              GetStart()                  { return nStart; }
     sal_Int32&              GetEnd()                    { return nEnd; }
@@ -65,7 +65,7 @@ public:
     sal_Int32               GetLen() const              { return nEnd-nStart; }
 
     bool IsFeature() const;
-    void SetItem(const SfxPoolItem& rNew);
+    void SetItem(SfxItemPool&, const SfxPoolItem&);
 
     inline bool operator==( const XEditAttribute& rCompare ) const;
 };
@@ -74,7 +74,7 @@ inline bool XEditAttribute::operator==( const XEditAttribute& 
rCompare ) const
 {
     return  (nStart == rCompare.nStart) &&
             (nEnd == rCompare.nEnd) &&
-            SfxPoolItem::areSame(pItem, rCompare.pItem);
+            SfxPoolItem::areSame(GetItem(), rCompare.GetItem());
 }
 
 struct XParaPortion
@@ -214,7 +214,6 @@ public:
 
     ContentInfo*            CreateAndInsertContent();
     XEditAttribute CreateAttrib( const SfxPoolItem& rItem, sal_Int32 nStart, 
sal_Int32 nEnd );
-    void                    DestroyAttrib( const XEditAttribute& rAttr );
 
     ContentInfosType&       GetContents() { return maContents;}
     const ContentInfosType& GetContents() const { return maContents;}
diff --git a/editeng/source/editeng/editundo.cxx 
b/editeng/source/editeng/editundo.cxx
index d957da25a32d..5854d1683e46 100644
--- a/editeng/source/editeng/editundo.cxx
+++ b/editeng/source/editeng/editundo.cxx
@@ -514,26 +514,8 @@ EditUndoSetAttribs::EditUndoSetAttribs(EditEngine* pEE, 
const ESelection& rESel,
 {
 }
 
-namespace {
-
-struct RemoveAttribsFromPool
-{
-    SfxItemPool& mrPool;
-public:
-    explicit RemoveAttribsFromPool(SfxItemPool& rPool) : mrPool(rPool) {}
-    void operator() (std::unique_ptr<ContentAttribsInfo> const & rInfo)
-    {
-        rInfo->RemoveAllCharAttribsFromPool(mrPool);
-    }
-};
-
-}
-
 EditUndoSetAttribs::~EditUndoSetAttribs()
 {
-    // Get Items from Pool...
-    SfxItemPool* pPool = aNewAttribs.GetPool();
-    std::for_each(aPrevAttribs.begin(), aPrevAttribs.end(), 
RemoveAttribsFromPool(*pPool));
 }
 
 void EditUndoSetAttribs::Undo()
@@ -620,7 +602,7 @@ void EditUndoTransliteration::Undo()
     EditSelection aDelSel( aSel );
     aSel = pEE->InsertParaBreak( aSel );
     aDelSel.Max() = aSel.Min();
-    aDelSel.Max().GetNode()->GetCharAttribs().DeleteEmptyAttribs( 
pEE->GetEditDoc().GetItemPool() );
+    aDelSel.Max().GetNode()->GetCharAttribs().DeleteEmptyAttribs();
     EditSelection aNewSel;
     if ( pTxtObj )
     {
diff --git a/editeng/source/editeng/editview.cxx 
b/editeng/source/editeng/editview.cxx
index df9f193ebfe6..77dab94e6b98 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -261,8 +261,9 @@ void EditView::SetSelection( const ESelection& rESel )
     {
         // tdf#113591 Get node from EditDoc, as the selection might have a 
pointer to an
         // already deleted node.
-        const ContentNode* pNode = 
pImpEditView->pEditEngine->GetEditDoc().GetEndPaM().GetNode();
-        pImpEditView->pEditEngine->CursorMoved( pNode );
+        const ContentNode* 
pNode(pImpEditView->pEditEngine->GetEditDoc().GetEndPaM().GetNode());
+        if (nullptr != pNode)
+            pNode->checkAndDeleteEmptyAttribs();
     }
     EditSelection aNewSelection( 
pImpEditView->pEditEngine->pImpEditEngine->ConvertSelection(
                                             rESel.nStartPara, rESel.nStartPos, 
rESel.nEndPara, rESel.nEndPos ) );
@@ -1719,7 +1720,12 @@ void EditView::SetCursorLogicPosition(const Point& 
rPosition, bool bPoint, bool
         aSelection.Min() = aPaM;
 
     if (pImpEditView->GetEditSelection().Min() != aSelection.Min())
-        
pImpEditView->pEditEngine->CursorMoved(pImpEditView->GetEditSelection().Min().GetNode());
+    {
+        const ContentNode* 
pNode(pImpEditView->GetEditSelection().Min().GetNode());
+        if (nullptr != pNode)
+            pNode->checkAndDeleteEmptyAttribs();
+    }
+
     pImpEditView->DrawSelectionXOR(aSelection);
     if (pImpEditView->GetEditSelection() != aSelection)
         pImpEditView->SetEditSelection(aSelection);
diff --git a/editeng/source/editeng/fieldupdater.cxx 
b/editeng/source/editeng/fieldupdater.cxx
index 008793a04ffd..05eca4575590 100644
--- a/editeng/source/editeng/fieldupdater.cxx
+++ b/editeng/source/editeng/fieldupdater.cxx
@@ -47,7 +47,7 @@ public:
                 // Create a new table field with the new ID, and set it to the
                 // attribute object.
                 SvxFieldItem aNewItem(SvxTableField(nTab), EE_FEATURE_FIELD);
-                rAttr.SetItem(pPool->DirectPutItemInPool(aNewItem));
+                rAttr.SetItem(*pPool, aNewItem);
             }
         }
     }
diff --git a/editeng/source/editeng/impedit.cxx 
b/editeng/source/editeng/impedit.cxx
index 851e63c0453d..92fb5affa6c3 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -2156,7 +2156,11 @@ bool ImpEditView::SetCursorAtPoint( const Point& 
rPointPixel )
     if (!pEditEngine->GetSelectionEngine().HasAnchor())
     {
         if ( aNewEditSelection.Min() != aPaM )
-            pEditEngine->CursorMoved(aNewEditSelection.Min().GetNode());
+        {
+            const ContentNode* pNode(aNewEditSelection.Min().GetNode());
+            if (nullptr != pNode)
+                pNode->checkAndDeleteEmptyAttribs();
+        }
         aNewEditSelection.Min() = aPaM;
     }
     else
diff --git a/editeng/source/editeng/impedit.hxx 
b/editeng/source/editeng/impedit.hxx
index d20ed8a1caae..e4352f298fd8 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -617,7 +617,6 @@ private:
     // Methods...
 
 
-    void                CursorMoved( const ContentNode* pPrevNode );
     void                ParaAttribsChanged( ContentNode const * pNode, bool 
bIgnoreUndoCheck = false );
     void                TextModified();
     void                CalcHeight( ParaPortion* pPortion );
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 15f6078dcec6..4b8f0a63799a 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -758,15 +758,6 @@ const SfxItemSet& ImpEditEngine::GetEmptyItemSet() const
 
 //  MISC
 
-void ImpEditEngine::CursorMoved( const ContentNode* pPrevNode )
-{
-    // Delete empty attributes, but only if paragraph is not empty!
-    if (pPrevNode->GetCharAttribs().HasEmptyAttribs() && pPrevNode->Len())
-    {
-        
const_cast<ContentNode*>(pPrevNode)->GetCharAttribs().DeleteEmptyAttribs(maEditDoc.GetItemPool());
-    }
-}
-
 void ImpEditEngine::TextModified()
 {
     mbFormatted = false;
@@ -949,9 +940,9 @@ EditSelection const & ImpEditEngine::MoveCursor( const 
KeyEvent& rKeyEvent, Edit
                             break;
     }
 
-    if ( aOldPaM != aPaM )
+    if ( aOldPaM != aPaM && nullptr != aOldPaM.GetNode() )
     {
-        CursorMoved( aOldPaM.GetNode() );
+        aOldPaM.GetNode()->checkAndDeleteEmptyAttribs();
     }
 
     // May cause, a CreateAnchor or deselection all
@@ -2454,8 +2445,10 @@ EditPaM ImpEditEngine::ImpDeleteSelection(const 
EditSelection& rCurSel)
     EditPaM aStartPaM(aCurSel.Min());
     EditPaM aEndPaM(aCurSel.Max());
 
-    CursorMoved( aStartPaM.GetNode() ); // only so that newly set Attributes 
disappear...
-    CursorMoved( aEndPaM.GetNode() );   // only so that newly set Attributes 
disappear...
+    if( nullptr != aStartPaM.GetNode() )
+        aStartPaM.GetNode()->checkAndDeleteEmptyAttribs(); // only so that 
newly set Attributes disappear...
+    if( nullptr != aEndPaM.GetNode() )
+        aEndPaM.GetNode()->checkAndDeleteEmptyAttribs(); // only so that newly 
set Attributes disappear...
 
     OSL_ENSURE( aStartPaM.GetIndex() <= aStartPaM.GetNode()->Len(), "Index out 
of range in ImpDeleteSelection" );
     OSL_ENSURE( aEndPaM.GetIndex() <= aEndPaM.GetNode()->Len(), "Index out of 
range in ImpDeleteSelection" );
@@ -2532,7 +2525,6 @@ void ImpEditEngine::ImpRemoveParagraph( sal_Int32 nPara )
         InsertUndo(std::make_unique<EditUndoDelContent>(pEditEngine, pNode, 
nPara));
     else
     {
-        maEditDoc.RemoveItemsFromPool(*pNode);
         if ( pNode->GetStyleSheet() )
             EndListening( *pNode->GetStyleSheet() );
         delete pNode;
@@ -2979,7 +2971,9 @@ EditPaM ImpEditEngine::ImpInsertParaBreak( EditPaM& rPaM, 
bool bKeepEndingAttrib
     if ( IsCallParaInsertedOrDeleted() )
         GetEditEnginePtr()->ParagraphInserted( nPos+1 );
 
-    CursorMoved( rPaM.GetNode() );  // if empty Attributes have emerged.
+    if( nullptr != rPaM.GetNode() )
+        rPaM.GetNode()->checkAndDeleteEmptyAttribs(); // if empty Attributes 
have emerged.
+
     TextModified();
     return aPaM;
 }
diff --git a/editeng/source/editeng/impedit4.cxx 
b/editeng/source/editeng/impedit4.cxx
index d6e31e7ec57e..57b3d65c54b4 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -1095,9 +1095,7 @@ std::unique_ptr<EditTextObject> 
ImpEditEngine::CreateTextObject( EditSelection a
                         aX.GetEnd() = nEndPos-nStartPos;
                 }
                 DBG_ASSERT( aX.GetEnd() <= (nEndPos-nStartPos), 
"CreateTextObject: Attribute too long!" );
-                if ( !aX.GetLen() && !bEmptyPara )
-                    pTxtObj->DestroyAttrib(aX);
-                else
+                if ( aX.GetLen() || bEmptyPara )
                     rCAttriblist.push_back(std::move(aX));
             }
             nAttr++;
diff --git a/editeng/source/editeng/impedit5.cxx 
b/editeng/source/editeng/impedit5.cxx
index abe351deea4c..0f5af2f75db0 100644
--- a/editeng/source/editeng/impedit5.cxx
+++ b/editeng/source/editeng/impedit5.cxx
@@ -429,8 +429,7 @@ SfxItemSet ImpEditEngine::GetAttribs( sal_Int32 nPara, 
sal_Int32 nStart, sal_Int
         if ( nFlags & GetAttribsFlags::CHARATTRIBS )
         {
             // Make testing easier...
-            const SfxItemPool& rPool = GetEditDoc().GetItemPool();
-            
pNode->GetCharAttribs().OptimizeRanges(const_cast<SfxItemPool&>(rPool));
+            pNode->GetCharAttribs().OptimizeRanges();
 
             const CharAttribList::AttribsType& rAttrs = 
pNode->GetCharAttribs().GetAttribs();
             for (const auto & nAttr : rAttrs)
@@ -756,7 +755,7 @@ void ImpEditEngine::GetCharAttribs( sal_Int32 nPara, 
std::vector<EECharAttrib>&
 
 void ImpEditEngine::ParaAttribsToCharAttribs( ContentNode* pNode )
 {
-    pNode->GetCharAttribs().DeleteEmptyAttribs( GetEditDoc().GetItemPool() );
+    pNode->GetCharAttribs().DeleteEmptyAttribs();
     sal_Int32 nEndPos = pNode->Len();
     for ( sal_uInt16 nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich++ )
     {
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index b3bbcbd608ca..57e327444a49 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -166,7 +166,6 @@ private:
                        EditEngine&     operator=( const EditEngine& ) = delete;
     EDITENG_DLLPRIVATE bool            PostKeyEvent( const KeyEvent& 
rKeyEvent, EditView* pView, vcl::Window const * pFrameWin );
 
-    EDITENG_DLLPRIVATE void CursorMoved(const ContentNode* pPrevNode);
     EDITENG_DLLPRIVATE void CheckIdleFormatter();
     EDITENG_DLLPRIVATE bool IsIdleFormatterActive() const;
     EDITENG_DLLPRIVATE ParaPortion* FindParaPortion(ContentNode const * pNode);
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index 998830c6542a..60f028aeac39 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -34,12 +34,30 @@ class SfxItemPool;
 #ifdef DBG_UTIL
 SVL_DLLPUBLIC size_t getAllocatedSfxItemSetCount();
 SVL_DLLPUBLIC size_t getUsedSfxItemSetCount();
+SVL_DLLPUBLIC size_t getAllocatedSfxPoolItemHolderCount();
+SVL_DLLPUBLIC size_t getUsedSfxPoolItemHolderCount();
 #endif
 
 // ItemSet/ItemPool helpers
 SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* 
pSource, sal_uInt16 nWhich, bool bPassingOwnership);
 void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource);
 
+class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxPoolItemHolder
+{
+    SfxItemPool*            m_pPool;
+    const SfxPoolItem*      m_pItem;
+public:
+    SfxPoolItemHolder(SfxItemPool&, const SfxPoolItem* = nullptr);
+    SfxPoolItemHolder(const SfxPoolItemHolder&);
+    ~SfxPoolItemHolder();
+
+    const SfxPoolItemHolder& operator=(const SfxPoolItemHolder&);
+    bool operator==(const SfxPoolItemHolder &) const;
+    SfxItemPool& getPool() const { return *m_pPool; }
+    const SfxPoolItem* getItem() const { return m_pItem; }
+    sal_uInt16 Which() const { if(nullptr != m_pItem) return m_pItem->Which(); 
return 0; }
+};
+
 class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
 {
     friend class SfxItemIter;
diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx
index c2c37c1200fb..faedbd516a41 100644
--- a/svl/source/items/itempool.cxx
+++ b/svl/source/items/itempool.cxx
@@ -794,15 +794,15 @@ void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 
nWhichId )
 
 const SfxPoolItem& SfxItemPool::DirectPutItemInPoolImpl(const SfxPoolItem& 
rItem, sal_uInt16 nWhich, bool bPassingOwnership)
 {
+    // CAUTION: Do not register the problematic pool default
+    if (rItem.isExceptionalSCItem() && 
GetMasterPool()->newItem_UseDirect(rItem))
+        return rItem;
+
 #ifdef DBG_UTIL
     nAllDirectlyPooledSfxPoolItemCount++;
     nRemainingDirectlyPooledSfxPoolItemCount++;
 #endif
 
-    // CAUTION: Do not register the problematic pool default
-    if (rItem.isExceptionalSCItem() && 
GetMasterPool()->newItem_UseDirect(rItem))
-        return rItem;
-
     // make sure to use 'master'-pool, that's the one used by SfxItemSets
     const SfxPoolItem* pRetval(implCreateItemEntry(*GetMasterPool(), &rItem, 
nWhich, bPassingOwnership));
 
@@ -816,13 +816,16 @@ const SfxPoolItem& 
SfxItemPool::DirectPutItemInPoolImpl(const SfxPoolItem& rItem
 
 void SfxItemPool::DirectRemoveItemFromPool(const SfxPoolItem& rItem)
 {
+    // CAUTION: Do not remove the problematic pool default
+    if (rItem.isExceptionalSCItem() && 
GetMasterPool()->newItem_UseDirect(rItem))
+        return;
+
 #ifdef DBG_UTIL
     nRemainingDirectlyPooledSfxPoolItemCount--;
 #endif
 
     // make sure to use 'master'-pool, that's the one used by SfxItemSets
     implCleanupItemEntry(*GetMasterPool(), &rItem);
-    return;
 }
 
 void SfxItemPool::newItem_Callback(const SfxPoolItem& rItem) const
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index abb264422828..102cf4d2bef8 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -39,8 +39,12 @@
 #ifdef DBG_UTIL
 static size_t nAllocatedSfxItemSetCount(0);
 static size_t nUsedSfxItemSetCount(0);
+static size_t nAllocatedSfxPoolItemHolderCount(0);
+static size_t nUsedSfxPoolItemHolderCount(0);
 size_t getAllocatedSfxItemSetCount() { return nAllocatedSfxItemSetCount; }
 size_t getUsedSfxItemSetCount() { return nUsedSfxItemSetCount; }
+size_t getAllocatedSfxPoolItemHolderCount() { return 
nAllocatedSfxPoolItemHolderCount; }
+size_t getUsedSfxPoolItemHolderCount() { return nUsedSfxPoolItemHolderCount; }
 #endif
 // NOTE: Only needed for one Item in SC (see notes below for
 // ScPatternAttr/ATTR_PATTERN). Still keep it so that when errors
@@ -48,6 +52,61 @@ size_t getUsedSfxItemSetCount() { return 
nUsedSfxItemSetCount; }
 // fallback flag 'ITEM_CLASSIC_MODE'
 static bool g_bItemClassicMode(getenv("ITEM_CLASSIC_MODE"));
 
+SfxPoolItemHolder::SfxPoolItemHolder(SfxItemPool& rPool, const SfxPoolItem* 
pItem)
+: m_pPool(&rPool),
+  m_pItem(pItem)
+{
+#ifdef DBG_UTIL
+    nAllocatedSfxPoolItemHolderCount++;
+    nUsedSfxPoolItemHolderCount++;
+#endif
+    if (nullptr != m_pItem)
+        m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), 
false);
+}
+
+SfxPoolItemHolder::SfxPoolItemHolder(const SfxPoolItemHolder& rHolder)
+: m_pPool(rHolder.m_pPool),
+  m_pItem(rHolder.m_pItem)
+{
+#ifdef DBG_UTIL
+    nAllocatedSfxPoolItemHolderCount++;
+    nUsedSfxPoolItemHolderCount++;
+#endif
+    if (nullptr != m_pItem)
+        m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), 
false);
+}
+
+SfxPoolItemHolder::~SfxPoolItemHolder()
+{
+#ifdef DBG_UTIL
+    nAllocatedSfxPoolItemHolderCount--;
+#endif
+    if (nullptr != m_pItem)
+        implCleanupItemEntry(*m_pPool, m_pItem);
+}
+
+const SfxPoolItemHolder& SfxPoolItemHolder::operator=(const SfxPoolItemHolder& 
rHolder)
+{
+    if (this == &rHolder || *this == rHolder)
+        return *this;
+
+    if (nullptr != m_pItem)
+        implCleanupItemEntry(*m_pPool, m_pItem);
+
+    m_pPool = rHolder.m_pPool;
+    m_pItem = rHolder.m_pItem;
+
+    if (nullptr != m_pItem)
+        m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), 
false);
+
+    return *this;
+}
+
+bool SfxPoolItemHolder::operator==(const SfxPoolItemHolder &rHolder) const
+{
+    return m_pPool == rHolder.m_pPool && areSfxPoolItemPtrsEqual(m_pItem, 
rHolder.m_pItem);
+}
+
 /**
  * Ctor for a SfxItemSet with exactly the Which Ranges, which are known to
  * the supplied SfxItemPool.
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index d7624cb111a3..e1e12dbc3e8a 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -200,6 +200,10 @@ Application::~Application()
     SAL_INFO("vcl.items", "ITEM: " << getAllocatedSfxItemSetCount() << " 
SfxItemSets still allocated at shutdown");
     SAL_INFO("vcl.items", "ITEM: " << getUsedSfxItemSetCount() << " 
SfxItemSets were incarnated during runtime");
 
+    // Same mechanism for PoolItemHolder(s)
+    SAL_INFO("vcl.items", "ITEM: " << getAllocatedSfxPoolItemHolderCount() << 
" SfxPoolItemHolders still allocated at shutdown");
+    SAL_INFO("vcl.items", "ITEM: " << getUsedSfxPoolItemHolderCount() << " 
SfxPoolItemHolders were incarnated during runtime");
+
     // Same mechanism for SfxPoolItem(s)directly put to a Pool
     SAL_INFO("vcl.items", "ITEM: " << 
getRemainingDirectlyPooledSfxPoolItemCount() << " SfxPoolItems still directly 
put in Pool at shutdown (deleted @Pool destruction)");
     SAL_INFO("vcl.items", "ITEM: " << getAllDirectlyPooledSfxPoolItemCount() 
<< " SfxPoolItems directly put in Pool");

Reply via email to