editeng/source/items/frmitems.cxx |    8 +-
 editeng/source/items/paraitem.cxx |    4 -
 editeng/source/items/textitem.cxx |   58 +++++++++------
 include/editeng/udlnitem.hxx      |    9 +-
 include/svl/poolitem.hxx          |   27 ++++++-
 svl/source/items/cenumitm.cxx     |   13 ++-
 svl/source/items/itemset.cxx      |  141 ++++++++++++++++++++++++++++----------
 7 files changed, 188 insertions(+), 72 deletions(-)

New commits:
commit 37f148c58974210707e069f21da2cc2b9ae086dd
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Wed Jan 24 17:53:19 2024 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Thu Jan 25 01:58:36 2024 +0100

    ITEM: Slight re-design of global Item-Reusage
    
    Unfortunately I had overseen something with derived
    classes, but it came now up on CI ASan/UBsan build
    with a failing UnitTest - thanks to pointing me at
    it.
    
    The ItemInstanceManager at the SfxPoolItems are now
    no longer static but constructed instances returned
    on-demand.
    
    Also added checks to really use an incarnated/
    registered one *only* for that derivation and made
    sure this is now correctly supported.
    
    Had to change again, using createItemInstanceManager
    to always create instances was less effective than
    intended, back to getItemInstanceManager & static
    instances in the Item implementations. Also added
    some stuff to implCreateItemEntry/implCleanupItemEntry
    to be more effective, e.g. direct handling of
    slot stuff in latter one. Also some more asserts
    and comments. Slot stuff is now handled without
    RefCounting, takes some write accesses away...
    
    Change-Id: I6cd69556b416510b5b23549dd042ff3ba155559d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162521
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/editeng/source/items/frmitems.cxx 
b/editeng/source/items/frmitems.cxx
index c3a5836b082a..e84ae2140e33 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -3980,8 +3980,8 @@ void SvxLineItem::SetLine( const SvxBorderLine* pNew )
 
 ItemInstanceManager* SvxBrushItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxBrushItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxBrushItem::SvxBrushItem(sal_uInt16 _nWhich)
@@ -4598,8 +4598,8 @@ void SvxBrushItem::dumpAsXml(xmlTextWriterPtr pWriter) 
const
 
 ItemInstanceManager* SvxFrameDirectionItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxFrameDirectionItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxFrameDirectionItem::SvxFrameDirectionItem( SvxFrameDirection nValue ,
diff --git a/editeng/source/items/paraitem.cxx 
b/editeng/source/items/paraitem.cxx
index 2a9a514a6461..e080b517eb43 100644
--- a/editeng/source/items/paraitem.cxx
+++ b/editeng/source/items/paraitem.cxx
@@ -340,8 +340,8 @@ void SvxLineSpacingItem::SetEnumValue( sal_uInt16 nVal )
 
 ItemInstanceManager* SvxAdjustItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxAdjustItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxAdjustItem::SvxAdjustItem(const SvxAdjust eAdjst, const sal_uInt16 nId )
diff --git a/editeng/source/items/textitem.cxx 
b/editeng/source/items/textitem.cxx
index 0bed0a7d077d..77e4c6c9cda0 100644
--- a/editeng/source/items/textitem.cxx
+++ b/editeng/source/items/textitem.cxx
@@ -168,8 +168,17 @@ namespace
     {
         SvxFontItemMap  maRegistered;
 
+    public:
+        SvxFontItemInstanceManager()
+        : ItemInstanceManager(typeid(SvxFontItem).hash_code())
+        {
+        }
+
+    private:
         static size_t hashCode(const SfxPoolItem&);
 
+        // standard interface, accessed exclusively
+        // by implCreateItemEntry/implCleanupItemEntry
         virtual const SfxPoolItem* find(const SfxPoolItem&) const override;
         virtual void add(const SfxPoolItem&) override;
         virtual void remove(const SfxPoolItem&) override;
@@ -209,8 +218,8 @@ namespace
 
 ItemInstanceManager* SvxFontItem::getItemInstanceManager() const
 {
-    static SvxFontItemInstanceManager aManager;
-    return &aManager;
+    static SvxFontItemInstanceManager aInstanceManager;
+    return &aInstanceManager;
 }
 
 SvxFontItem::SvxFontItem(
@@ -439,8 +448,8 @@ void SvxFontItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 
 ItemInstanceManager* SvxPostureItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxPostureItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxPostureItem::SvxPostureItem( const FontItalic ePosture, const sal_uInt16 
nId ) :
@@ -561,8 +570,8 @@ void SvxPostureItem::dumpAsXml(xmlTextWriterPtr pWriter) 
const
 
 ItemInstanceManager* SvxWeightItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxWeightItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxWeightItem::SvxWeightItem( const FontWeight eWght, const sal_uInt16 nId ) :
@@ -691,8 +700,8 @@ void SvxWeightItem::dumpAsXml(xmlTextWriterPtr pWriter) 
const
 
 ItemInstanceManager* SvxFontHeightItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxFontHeightItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxFontHeightItem::SvxFontHeightItem( const sal_uInt32 nSz,
@@ -1038,12 +1047,6 @@ void SvxFontHeightItem::dumpAsXml(xmlTextWriterPtr 
pWriter) const
 
 // class SvxTextLineItem ------------------------------------------------
 
-ItemInstanceManager* SvxTextLineItem::getItemInstanceManager() const
-{
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
-}
-
 SvxTextLineItem::SvxTextLineItem( const FontLineStyle eSt, const sal_uInt16 
nId )
     : SfxEnumItem(nId, eSt)
     , maColor(COL_TRANSPARENT)
@@ -1196,6 +1199,11 @@ bool SvxTextLineItem::operator==( const SfxPoolItem& 
rItem ) const
 
 // class SvxUnderlineItem ------------------------------------------------
 
+ItemInstanceManager* SvxUnderlineItem::getItemInstanceManager() const
+{
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxUnderlineItem).hash_code());
+    return &aInstanceManager;
+}
 
 SvxUnderlineItem::SvxUnderlineItem( const FontLineStyle eSt, const sal_uInt16 
nId )
     : SvxTextLineItem( eSt, nId )
@@ -1238,6 +1246,12 @@ OUString SvxUnderlineItem::GetValueTextByPos( sal_uInt16 
nPos ) const
 
 // class SvxOverlineItem ------------------------------------------------
 
+ItemInstanceManager* SvxOverlineItem::getItemInstanceManager() const
+{
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxOverlineItem).hash_code());
+    return &aInstanceManager;
+}
+
 SvxOverlineItem::SvxOverlineItem( const FontLineStyle eSt, const sal_uInt16 
nId )
     : SvxTextLineItem( eSt, nId )
 {
@@ -1281,8 +1295,8 @@ OUString SvxOverlineItem::GetValueTextByPos( sal_uInt16 
nPos ) const
 
 ItemInstanceManager* SvxCrossedOutItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxCrossedOutItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxCrossedOutItem::SvxCrossedOutItem( const FontStrikeout eSt, const 
sal_uInt16 nId )
@@ -2083,8 +2097,8 @@ bool SvxEscapementItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
 
 ItemInstanceManager* SvxLanguageItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxLanguageItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxLanguageItem::SvxLanguageItem( const LanguageType eLang, const sal_uInt16 
nId )
@@ -2231,8 +2245,8 @@ bool SvxBlinkItem::GetPresentation
 
 ItemInstanceManager* SvxEmphasisMarkItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxEmphasisMarkItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxEmphasisMarkItem::SvxEmphasisMarkItem( const FontEmphasisMark nValue,
@@ -2671,8 +2685,8 @@ bool SvxCharScaleWidthItem::QueryValue( uno::Any& rVal, 
sal_uInt8 /*nMemberId*/
 
 ItemInstanceManager* SvxCharReliefItem::getItemInstanceManager() const
 {
-    static DefaultItemInstanceManager aManager;
-    return &aManager;
+    static DefaultItemInstanceManager 
aInstanceManager(typeid(SvxCharReliefItem).hash_code());
+    return &aInstanceManager;
 }
 
 SvxCharReliefItem::SvxCharReliefItem( FontRelief eValue,
diff --git a/include/editeng/udlnitem.hxx b/include/editeng/udlnitem.hxx
index 560833d4d088..b140c47b8bc5 100644
--- a/include/editeng/udlnitem.hxx
+++ b/include/editeng/udlnitem.hxx
@@ -33,9 +33,6 @@ class EDITENG_DLLPUBLIC SvxTextLineItem : public 
SfxEnumItem<FontLineStyle>
     Color maColor;
     model::ComplexColor maComplexColor;
 
-protected:
-    virtual ItemInstanceManager* getItemInstanceManager() const override;
-
 public:
     SvxTextLineItem( const FontLineStyle eSt,
                      const sal_uInt16 nId );
@@ -90,6 +87,9 @@ public:
 
 class EDITENG_DLLPUBLIC SvxUnderlineItem final : public SvxTextLineItem
 {
+protected:
+    virtual ItemInstanceManager* getItemInstanceManager() const override;
+
 public:
     static SfxPoolItem* CreateDefault();
 
@@ -106,6 +106,9 @@ public:
 
 class EDITENG_DLLPUBLIC SvxOverlineItem final : public SvxTextLineItem
 {
+protected:
+    virtual ItemInstanceManager* getItemInstanceManager() const override;
+
 public:
     static SfxPoolItem* CreateDefault();
 
diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx
index 43d8c101dd05..22a5d5bcb9ff 100644
--- a/include/svl/poolitem.hxx
+++ b/include/svl/poolitem.hxx
@@ -176,7 +176,12 @@ protected:
     void setNonShareable() { m_bShareable = false; }
 
     // access ItemInstanceManager for this Item, default
-    // is nullptr
+    // is nullptr. If you overload this it is expected that
+    // you return a ptr to a static, Item-local managed
+    // instance that exists the whole office lifetime. This
+    // usually means to have a static instance irectly in the
+    // implementation of the overloaded function (just grep
+    // for examples)
     virtual ItemInstanceManager* getItemInstanceManager() const;
 
 public:
@@ -297,6 +302,19 @@ class SVL_DLLPUBLIC ItemInstanceManager
     friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem 
const*, bool);
     friend void implCleanupItemEntry(SfxPoolItem const*);
 
+    // Define for which class to register (usually typeid().hash_code()).
+    std::size_t     m_aClassHash;
+
+public:
+    ItemInstanceManager(const std::size_t aClassHash)
+    : m_aClassHash(aClassHash)
+    {
+    }
+    virtual ~ItemInstanceManager() = default;
+
+    std::size_t getClassHash() const { return m_aClassHash; }
+
+private:
     // standard interface, accessed exclusively
     // by implCreateItemEntry/implCleanupItemEntry
     virtual const SfxPoolItem* find(const SfxPoolItem&) const = 0;
@@ -317,7 +335,12 @@ class SVL_DLLPUBLIC DefaultItemInstanceManager : public 
ItemInstanceManager
     std::unordered_set<const SfxPoolItem*>  maRegistered;
 
 public:
-    virtual ~DefaultItemInstanceManager() = default;
+    DefaultItemInstanceManager(const std::size_t aClassHash)
+    : ItemInstanceManager(aClassHash)
+    {
+    }
+
+private:
     virtual const SfxPoolItem* find(const SfxPoolItem&) const override;
     virtual void add(const SfxPoolItem&) override;
     virtual void remove(const SfxPoolItem&) override;
diff --git a/svl/source/items/cenumitm.cxx b/svl/source/items/cenumitm.cxx
index 86e30b7e6bdc..4bb3dd8bcd70 100644
--- a/svl/source/items/cenumitm.cxx
+++ b/svl/source/items/cenumitm.cxx
@@ -91,6 +91,15 @@ namespace
     {
         SfxBoolItemMap  maRegistered;
 
+    public:
+        SfxBoolItemInstanceManager()
+        : ItemInstanceManager(typeid(SfxBoolItem).hash_code())
+        {
+        }
+
+    private:
+        // standard interface, accessed exclusively
+        // by implCreateItemEntry/implCleanupItemEntry
         virtual const SfxPoolItem* find(const SfxPoolItem&) const override;
         virtual void add(const SfxPoolItem&) override;
         virtual void remove(const SfxPoolItem&) override;
@@ -149,8 +158,8 @@ namespace
 
 ItemInstanceManager* SfxBoolItem::getItemInstanceManager() const
 {
-    static SfxBoolItemInstanceManager aManager;
-    return &aManager;
+    static SfxBoolItemInstanceManager aInstanceManager;
+    return &aInstanceManager;
 }
 
 void SfxBoolItem::SetValue(bool const bTheValue)
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 907daa23180f..d62f54766698 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -324,6 +324,42 @@ SfxItemSet::SfxItemSet(SfxItemPool& pool, 
WhichRangesContainer wids)
     assert(svl::detail::validRanges2(m_pWhichRanges));
 }
 
+// Class that implements global Item sharing. It uses rtti to
+// associate every Item-derivation with a possible incarnation
+// of a DefaultItemInstanceManager. This is the default, it will
+// give direct implementatioons at the Items that overload
+// getItemInstanceManager() preference. These are expected to
+// return static instances of aderived implementation of a
+// ItemInstanceManager.
+// All in all there are now the following possibilities to support
+// this for individual Item derivations:
+// (1) Do nothing:
+//     In that case, if the Item is shareable, the new mechanism
+//     will kick in: It will start sharing the Item globally,
+//     but not immediately: After a defined amount of allowed
+//     non-shared ocurrences (look for NUMBER_OF_UNSHARED_INSTANCES)
+//     an instance of the default ItemInstanceManager, a
+//     DefaultItemInstanceManager, will be incarnated and used.
+//     NOTE: Mixing shared/unshared instances is not a problem (we
+//     might even implement a kind of 're-hash' when this kicks in,
+//     but is not really needded).
+// (2) Overload getItemInstanceManager for SfxPoolItem in a class
+//     derived from SfxPoolItem and...
+// (2a) Return a static incarnation of DefaultItemInstanceManager to
+//      immediately start global sharing of that Item derivation.
+// (2b) Implement and return your own implementation and static
+//      incarnation of ItemInstanceManager to do something better/
+//      faster that the default implementation can do. Example:
+//      SvxFontItem, uses hashing now.
+// There are two supported ENVVARs to use:
+// (a) SVL_DISABLE_ITEM_INSTANCE_MANAGER:
+//     This disables the mechanism of global Item sharing completely.
+//     This can be used to test/check speed/memory needs compared with
+//     using it, but also may come in handy to check if evtl. errors/
+//     regressions have to do with it.
+// (b) SVL_SHARE_ITEMS_GLOBALLY_INSTANTLY:
+//     This internally forces the NUMBER_OF_UNSHARED_INSTANCES to be
+//     ignored and start sharing ALL Item derivations instantly.
 class InstanceManagerHelper
 {
     typedef std::unordered_map<std::size_t, std::pair<sal_uInt16, 
DefaultItemInstanceManager*>> managerTypeMap;
@@ -348,24 +384,29 @@ public:
         if (!rItem.isShareable())
             return nullptr;
 
-        // prefer getting an ItemInstanceManager directly from
+        // Prefer getting an ItemInstanceManager directly from
         // the Item: These are the extra implemented (and thus
-        // hopefully fast) incarnations
+        // hopefully fastest) incarnations
         ItemInstanceManager* pManager(rItem.getItemInstanceManager());
-        if (nullptr != pManager)
-            return pManager;
 
-        // get hash and check memory for existing entry
+        // Check for correct hash, there may be derivations of that class.
+        // Note that Managers from the Items are *not* added to local list,
+        // they are expected to be static instances at the Items
         const std::size_t aHash(typeid(rItem).hash_code());
+        if (nullptr != pManager && pManager->getClassHash() == aHash)
+            return pManager;
+
+        // check local memory for existing entry
         managerTypeMap::iterator aHit(maManagerPerType.find(aHash));
 
-        // no instance yet, create one to start usage-counting
+        // no instance yet
         if (aHit == maManagerPerType.end())
         {
+            // create a default one to start usage-counting
             if (g_bShareImmediately)
             {
-                // create and immediately start sharing
-                DefaultItemInstanceManager* pNew(new 
DefaultItemInstanceManager);
+                // create, insert locally and immediately start sharing
+                DefaultItemInstanceManager* pNew(new 
DefaultItemInstanceManager(aHash));
                 maManagerPerType.insert({aHash, std::make_pair(0, pNew)});
                 return pNew;
             }
@@ -375,21 +416,21 @@ public:
             return nullptr;
         }
 
-        // if there is already a ItemInstanceManager incarnated, return it
+        // if there is already an ItemInstanceManager incarnated, return it
         if (nullptr != aHit->second.second)
             return aHit->second.second;
 
         if (aHit->second.first > 0)
         {
-            // still not the neeed number of hits, countdown & return nullptr
+            // still not the needed number of hits, countdown & return nullptr
             aHit->second.first--;
             return nullptr;
         }
 
-        // here there is not yet a ItemInstanceManager incarnated. Do
-        // so and return it
+        // here the countdown is zero and there is not yet a 
ItemInstanceManager
+        // incarnated. Do so, regsiter and return it
         assert(nullptr == aHit->second.second);
-        DefaultItemInstanceManager* pNew(new DefaultItemInstanceManager);
+        DefaultItemInstanceManager* pNew(new 
DefaultItemInstanceManager(aHash));
         aHit->second.second = pNew;
 
         return pNew;
@@ -405,15 +446,19 @@ public:
         if (!rItem.isShareable())
             return nullptr;
 
-        // prefer getting an ItemInstanceManager directly from
+        // Prefer getting an ItemInstanceManager directly from
         // the Item: These are the extra implemented (and thus
-        // hopefully fast) incarnations
+        // hopefully fastest) incarnations
         ItemInstanceManager* pManager(rItem.getItemInstanceManager());
-        if (nullptr != pManager)
-            return pManager;
 
-        // get hash and check memory for existing entry
+        // Check for correct hash, there may be derivations of that class.
+        // Note that Managers from the Items are *not* added to local list,
+        // they are expected to be static instances at the Items
         const std::size_t aHash(typeid(rItem).hash_code());
+        if (nullptr != pManager && pManager->getClassHash() == aHash)
+            return pManager;
+
+        // check local memory for existing entry
         managerTypeMap::iterator aHit(maManagerPerType.find(aHash));
 
         if (aHit == maManagerPerType.end())
@@ -424,7 +469,7 @@ public:
         if (nullptr != aHit->second.second)
             return aHit->second.second;
 
-        // count-up neeed number of hits again if item is released
+        // count-up needed number of hits again if item is released
         if (aHit->second.first < NUMBER_OF_UNSHARED_INSTANCES)
             aHit->second.first++;
 
@@ -432,6 +477,7 @@ public:
     }
 };
 
+// the single static instance that takes over that global Item sharing
 static InstanceManagerHelper aInstanceManagerHelper;
 
 SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* 
pSource, bool bPassingOwnership)
@@ -442,12 +488,12 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& 
rPool, SfxPoolItem const* pS
         return nullptr;
 
     if (IsInvalidItem(pSource))
-        // SfxItemState::DONTCARE aka invalid item
+        // SfxItemState::DONTCARE aka INVALID_POOL_ITEM
         // just use pSource which equals INVALID_POOL_ITEM
         return pSource;
 
     if (IsDisabledItem(pSource))
-        // SfxItemState::DISABLED aka invalid item
+        // SfxItemState::DISABLED aka DISABLED_POOL_ITEM
         // just use pSource which equals DISABLED_POOL_ITEM
         return pSource;
 
@@ -472,28 +518,27 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& 
rPool, SfxPoolItem const* pS
         return pSource->Clone();
     }
 
-    // get correct target WhichID
-    sal_uInt16 nWhich(pSource->Which());
+#ifdef DBG_UTIL
+    // remember WhichID due to being able to assert Clone() error(s)
+    const sal_uInt16 nWhich(pSource->Which());
+#endif
 
-    if (SfxItemPool::IsSlot(nWhich))
+    if (SfxItemPool::IsSlot(pSource->Which()))
     {
         // SlotItems were always cloned in original (even when 
bPassingOwnership),
         // so do that here, too (but without bPassingOwnership).
         // They do not need to be registered at pool (actually impossible, 
pools
         // do not have entries for SlotItems) so handle here early
         if (!bPassingOwnership)
-            pSource = pSource->Clone(rPool.GetMasterPool());
-
-        // ARGH! Found out that *some* ::Clone implementations fail to also 
clone the
-        // WhichID set at the original Item, e.g. SfxFrameItem. Corrected 
there, but
-        // there may be more cases, so add a SAL_WARN here and correct this
-        if (pSource->Which() != nWhich)
         {
-            SAL_WARN("svl.items", "ITEM: Clone of Item with class " << 
typeid(*pSource).name() << " did NOT copy/set WhichID (!)");
-            const_cast<SfxPoolItem*>(pSource)->SetWhich(nWhich);
+            pSource = pSource->Clone(rPool.GetMasterPool());
+            // ARGH! Found out that *some* ::Clone implementations fail to 
also clone the
+            // WhichID set at the original Item, e.g. SfxFrameItem. Assert, 
this is an error
+#ifdef DBG_UTIL
+            assert(pSource->Which() == nWhich && "ITEM: Clone of Item did NOT 
copy/set WhichID (!)");
+#endif
         }
 
-        pSource->AddRef();
         return pSource;
     }
 
@@ -515,7 +560,7 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, 
SfxPoolItem const* pS
     // if (IsStaticDefaultItem(pSource))
     // {
     //     assert(!bPassingOwnership && "ITEM: PassingOwnership not possible 
combined with StaticDefault (!)");
-    //     const SfxPoolItem* pStatic(pTargetPool->GetItem2Default(nWhich));
+    //     const SfxPoolItem* 
pStatic(pTargetPool->GetItem2Default(pSource->Which()));
     //     if (nullptr != pStatic)
     //     {
     //         if (SfxPoolItem::areSame(pSource, pStatic))
@@ -530,7 +575,7 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, 
SfxPoolItem const* pS
     // else if (IsDefaultItem(pSource))
     // {
     //     assert(!bPassingOwnership && "ITEM: PassingOwnership not possible 
combined with DynamicDefault (!)");
-    //     const SfxPoolItem* 
pDynamic(pTargetPool->GetPoolDefaultItem(nWhich));
+    //     const SfxPoolItem* 
pDynamic(pTargetPool->GetPoolDefaultItem(pSource->Which()));
     //     if (nullptr != pDynamic)
     //     {
     //         if (SfxPoolItem::areSame(pSource, pDynamic))
@@ -572,6 +617,12 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, 
SfxPoolItem const* pS
             // no already globally shared one found, done
             break;
 
+        // Here we do *not* need to check if it is an SfxSetItem
+        // and cannot be shared if they are in/use another pool:
+        // The SfxItemSet::operator== will check for SfxItemPools
+        // being equal, thus when found in global share the Pool
+        // cannot be equal
+
         // need to delete evtl. handed over ownership change Item
         if (bPassingOwnership)
             delete pSource;
@@ -591,6 +642,9 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, 
SfxPoolItem const* pS
     {
         const SfxPoolItem* pOld(pSource);
         pSource = pSource->Clone(pMasterPool);
+#ifdef DBG_UTIL
+        assert(pSource->Which() == nWhich && "ITEM: Clone of Item did NOT 
copy/set WhichID (!)");
+#endif
         delete pOld;
     }
 
@@ -602,7 +656,12 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, 
SfxPoolItem const* pS
     // when we reach this line we know that we have to add/create a new item. 
If
     // bPassingOwnership is given just use the item, else clone it
     if (!bPassingOwnership)
+    {
         pSource = pSource->Clone(pMasterPool);
+#ifdef DBG_UTIL
+        assert(pSource->Which() == nWhich && "ITEM: Clone of Item did NOT 
copy/set WhichID (!)");
+#endif
+    }
 
     // increase RefCnt 0->1
     pSource->AddRef();
@@ -622,12 +681,13 @@ void implCleanupItemEntry(SfxPoolItem const* pSource)
         return;
 
     if (IsInvalidItem(pSource))
+        // SfxItemState::DONTCARE aka INVALID_POOL_ITEM
         // nothing to do for invalid item entries
         return;
 
     if (IsDisabledItem(pSource))
-        // SfxItemState::DISABLED aka invalid item
-        // just use pSource which equals DISABLED_POOL_ITEM
+        // SfxItemState::DONTCARE aka DISABLED_POOL_ITEM
+        // nothing to do for disabled item entries
         return;
 
     if (0 == pSource->Which())
@@ -639,6 +699,13 @@ void implCleanupItemEntry(SfxPoolItem const* pSource)
         return;
     }
 
+    if (SfxItemPool::IsSlot(pSource->Which()))
+    {
+        // SlotItems are cloned, so delete
+        delete pSource;
+        return;
+    }
+
     if (1 < pSource->GetRefCount())
     {
         // Still multiple references present, so just alter the RefCount

Reply via email to