summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/editeng/fontitem.hxx1
-rw-r--r--include/editeng/wghtitem.hxx8
-rw-r--r--include/sal/log-areas.dox1
-rw-r--r--include/svl/custritm.hxx2
-rw-r--r--include/svl/itempool.hxx88
-rw-r--r--include/svl/itemset.hxx21
-rw-r--r--include/svl/poolitem.hxx81
-rw-r--r--include/svx/pageitem.hxx2
-rw-r--r--include/svx/sdasitm.hxx2
-rw-r--r--include/svx/xbtmpit.hxx2
10 files changed, 133 insertions, 75 deletions
diff --git a/include/editeng/fontitem.hxx b/include/editeng/fontitem.hxx
index deabf3101f44..7cab5f462e4e 100644
--- a/include/editeng/fontitem.hxx
+++ b/include/editeng/fontitem.hxx
@@ -46,7 +46,6 @@ public:
// "pure virtual Methods" from SfxPoolItem
virtual bool operator==(const SfxPoolItem& rItem) const override;
- bool operator<(const SfxPoolItem& rCmp) const override;
virtual SvxFontItem* Clone(SfxItemPool *pPool = nullptr) const override;
virtual bool QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId = 0) const override;
virtual bool PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) override;
diff --git a/include/editeng/wghtitem.hxx b/include/editeng/wghtitem.hxx
index 6f5f4b31ccc3..121cfcf318a6 100644
--- a/include/editeng/wghtitem.hxx
+++ b/include/editeng/wghtitem.hxx
@@ -59,14 +59,6 @@ public:
FontWeight GetWeight() const { return GetValue(); }
void dumpAsXml(xmlTextWriterPtr pWriter) const override;
-
- virtual bool IsSortable() const override { return true; }
-
- virtual bool operator<(const SfxPoolItem& rCmp) const override
- {
- auto const & other = static_cast<const SvxWeightItem&>(rCmp);
- return GetValue() < other.GetValue();
- }
};
#endif // INCLUDED_EDITENG_WGHTITEM_HXX
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index 8e6d5d81f1ae..0b3907e08610 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -499,6 +499,7 @@ certain functionality.
@li @c vcl.helper
@li @c vcl.icontest
@li @c vcl.ios.clipboard
+@li @c vcl.items
@li @c vcl.kf5 - KF5
@li @c vcl.layout - Widget layout
@li @c vcl.lazydelete
diff --git a/include/svl/custritm.hxx b/include/svl/custritm.hxx
index 90215aff45d3..3159c41dfc96 100644
--- a/include/svl/custritm.hxx
+++ b/include/svl/custritm.hxx
@@ -39,8 +39,6 @@ public:
{}
virtual bool operator ==(const SfxPoolItem & rItem) const override;
- virtual bool operator <(const SfxPoolItem & rItem) const override;
- virtual bool IsSortable() const override { return true; }
virtual bool GetPresentation(SfxItemPresentation,
MapUnit, MapUnit,
diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx
index e85451ecb738..8dfac4766ffb 100644
--- a/include/svl/itempool.hxx
+++ b/include/svl/itempool.hxx
@@ -26,6 +26,7 @@
#include <svl/whichranges.hxx>
#include <memory>
#include <vector>
+#include <unordered_set>
#include <o3tl/sorted_vector.hxx>
#include <salhelper/simplereferenceobject.hxx>
@@ -34,11 +35,30 @@ struct SfxItemPool_Impl;
struct SfxItemInfo
{
+ // Defines a mapping between WhichID <-> SlotID
sal_uInt16 _nSID;
- bool _bPoolable;
+
+ // Defines if this Item needs to be registered at the pool
+ // to make it accessible for the GetItemSurrogates call. It
+ // will not be included when this flag is not set, but also
+ // needs no registration. There are SAL_INFO calls in the
+ // GetItemSurrogates impl that will mention that
+ bool _bNeedsPoolRegistration : 1;
+
+ // Defines if the Item can be shared/RefCounted else it will be cloned.
+ // Default is true - as it should be for all Items. It is needed by some
+ // SW items, so protected to let them set it in constructor. If this could
+ // be fixed at that Items we may remove this again.
+ bool _bShareable : 1;
};
class SfxItemPool;
+typedef std::unordered_set<const SfxPoolItem*> registeredSfxPoolItems;
+
+#ifdef DBG_UTIL
+SVL_DLLPUBLIC size_t getAllDirectlyPooledSfxPoolItemCount();
+SVL_DLLPUBLIC size_t getRemainingDirectlyPooledSfxPoolItemCount();
+#endif
/** Base class for providers of defaults of SfxPoolItems.
*
@@ -53,14 +73,26 @@ class SVL_DLLPUBLIC SfxItemPool : public salhelper::SimpleReferenceObject
friend class SfxItemSet;
friend class SfxAllItemSet;
+ // allow ItemSetTooling to access
+ friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool, bool);
+ friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
+
+ // unit testing
+ friend class PoolItemTest;
+
const SfxItemInfo* pItemInfos;
std::unique_ptr<SfxItemPool_Impl> pImpl;
+ registeredSfxPoolItems** ppRegisteredSfxPoolItems;
+
private:
sal_uInt16 GetIndex_Impl(sal_uInt16 nWhich) const;
sal_uInt16 GetSize_Impl() const;
- SVL_DLLPRIVATE bool IsItemPoolable_Impl( sal_uInt16 nWhich ) const;
+ SVL_DLLPRIVATE bool NeedsPoolRegistration_Impl(sal_uInt16 nPos) const
+ { return pItemInfos[nPos]._bNeedsPoolRegistration; }
+ SVL_DLLPRIVATE bool Shareable_Impl(sal_uInt16 nPos) const
+ { return pItemInfos[nPos]._bShareable; }
public:
// for default SfxItemSet::CTOR, set default WhichRanges
@@ -135,18 +167,16 @@ public:
virtual rtl::Reference<SfxItemPool> Clone() const;
const OUString& GetName() const;
- template<class T> const T& Put( std::unique_ptr<T> xItem, sal_uInt16 nWhich = 0 )
- { return static_cast<const T&>(PutImpl( *xItem.release(), nWhich, /*bPassingOwnership*/true)); }
- template<class T> const T& Put( const T& rItem, sal_uInt16 nWhich = 0 )
- { return static_cast<const T&>(PutImpl( rItem, nWhich, /*bPassingOwnership*/false)); }
- void Remove( const SfxPoolItem& );
+ template<class T> const T& DirectPutItemInPool( std::unique_ptr<T> xItem, sal_uInt16 nWhich = 0 )
+ { return static_cast<const T&>(DirectPutItemInPoolImpl( *xItem.release(), nWhich, /*bPassingOwnership*/true)); }
+ template<class T> const T& DirectPutItemInPool( const T& rItem, sal_uInt16 nWhich = 0 )
+ { return static_cast<const T&>(DirectPutItemInPoolImpl( rItem, nWhich, /*bPassingOwnership*/false)); }
+ void DirectRemoveItemFromPool( const SfxPoolItem& );
const SfxPoolItem& GetDefaultItem( sal_uInt16 nWhich ) const;
template<class T> const T& GetDefaultItem( TypedWhichId<T> nWhich ) const
{ return static_cast<const T&>(GetDefaultItem(sal_uInt16(nWhich))); }
- bool CheckItemInPool(const SfxPoolItem *) const;
-
struct Item2Range
{
o3tl::sorted_vector<SfxPoolItem*>::const_iterator m_begin;
@@ -158,8 +188,7 @@ public:
template<class T> const T* GetItem2Default( TypedWhichId<T> nWhich ) const
{ return static_cast<const T*>(GetItem2Default(sal_uInt16(nWhich))); }
- sal_uInt32 GetItemCount2(sal_uInt16 nWhich) const;
- Item2Range GetItemSurrogates(sal_uInt16 nWhich) const;
+ const registeredSfxPoolItems& GetItemSurrogates(sal_uInt16 nWhich) const;
/*
This is only valid for SfxPoolItem that override IsSortable and operator<.
Returns a range of items defined by using operator<.
@@ -179,9 +208,14 @@ public:
void Delete();
- bool IsItemPoolable( sal_uInt16 nWhich ) const;
- bool IsItemPoolable( const SfxPoolItem &rItem ) const
- { return IsItemPoolable( rItem.Which() ); }
+ bool NeedsPoolRegistration(sal_uInt16 nWhich) const;
+ bool NeedsPoolRegistration(const SfxPoolItem &rItem) const
+ { return NeedsPoolRegistration(rItem.Which()); }
+
+ bool Shareable(sal_uInt16 nWhich) const;
+ bool Shareable(const SfxPoolItem &rItem) const
+ { return Shareable(rItem.Which()); }
+
void SetItemInfos( const SfxItemInfo *pInfos );
sal_uInt16 GetWhich( sal_uInt16 nSlot, bool bDeep = true ) const;
template<class T>
@@ -196,10 +230,34 @@ public:
static bool IsSlot(sal_uInt16 nId) {
return nId && nId > SFX_WHICH_MAX; }
+ // this method tries to register an Item at this Pool. If this
+ // is done depends on the SfxItemInfo-flag _bNeedsPoolRegistration
+ // which needs to be set for Items that are acessed using
+ // GetItemSurrogates, else the Item will not be returned/accessed
+ void tryRegisterSfxPoolItem(const SfxPoolItem& rItem, bool bPoolDirect);
+
+ // this method will register the Item at this Pool, no matter what.
+ // It is needed for all calls that directly register Items at the
+ // Pool, so the DirectPutItemInPool-methods
+ void doRegisterSfxPoolItem(const SfxPoolItem& rItem);
+
+ // this method will unregister an Item from this Pool
+ void unregisterSfxPoolItem(const SfxPoolItem& rItem);
+
+ // check if this Item is registered at this Pool, needed to detect
+ // if an Item is to be set at another Pool and needs to be cloned
+ bool isSfxPoolItemRegisteredAtThisPool(const SfxPoolItem& rItem) const;
+
+ // try to find an equal existing Item to given one in pool
+ const SfxPoolItem* tryToGetEqualItem(const SfxPoolItem& rItem, sal_uInt16 nWhich) const;
+
void dumpAsXml(xmlTextWriterPtr pWriter) const;
protected:
- virtual const SfxPoolItem& PutImpl( const SfxPoolItem&, sal_uInt16 nWhich = 0, bool bPassingOwnership = false );
+ const SfxPoolItem& DirectPutItemInPoolImpl( const SfxPoolItem&, sal_uInt16 nWhich = 0, bool bPassingOwnership = false );
+ virtual void newItem_Callback(const SfxPoolItem& rItem) const;
+ virtual bool newItem_UseDirect(const SfxPoolItem& rItem) const;
+
private:
const SfxItemPool& operator=(const SfxItemPool &) = delete;
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index 01d9d5058b14..06e82b87e054 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -36,11 +36,19 @@ SVL_DLLPUBLIC size_t getAllocatedSfxItemSetCount();
SVL_DLLPUBLIC size_t getUsedSfxItemSetCount();
#endif
+// ItemSet/ItemPool helpers
+SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource, sal_uInt16 nWhich, bool bPassingOwnership, bool bPoolDirect);
+void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource);
+
class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
{
friend class SfxItemIter;
friend class SfxWhichIter;
+ // allow ItemSetTooling to access
+ friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool, bool);
+ friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
+
SfxItemPool* m_pPool; ///< pool that stores the items
const SfxItemSet* m_pParent; ///< derivation
sal_uInt16 m_nCount; ///< number of items
@@ -88,7 +96,7 @@ private:
const SfxItemSet& operator=(const SfxItemSet &) = delete;
protected:
- virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership );
+ virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bPassingOwnership );
/** special constructor for SfxAllItemSet */
enum class SfxAllItemSetFlag { Flag };
@@ -207,9 +215,9 @@ public:
// add, delete items, work on items
public:
const SfxPoolItem* Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
- { return PutImpl(rItem, nWhich, /*bItemIsSetMember*/false, /*bPassingOwnership*/false); }
+ { return PutImpl(rItem, nWhich, /*bPassingOwnership*/false); }
const SfxPoolItem* Put( std::unique_ptr<SfxPoolItem> xItem, sal_uInt16 nWhich )
- { return PutImpl(*xItem.release(), nWhich, /*bItemIsSetMember*/false, /*bPassingOwnership*/true); }
+ { return PutImpl(*xItem.release(), nWhich, /*bPassingOwnership*/true); }
const SfxPoolItem* Put( const SfxPoolItem& rItem )
{ return Put(rItem, rItem.Which()); }
const SfxPoolItem* Put( std::unique_ptr<SfxPoolItem> xItem )
@@ -261,7 +269,7 @@ private:
sal_uInt16 ClearAllItemsImpl();
// Merge two given Item(entries)
- void MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, bool bItemIsSetMember, bool bIgnoreDefaults);
+ void MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, bool bIgnoreDefaults);
// split version(s) of InvalidateItem for input types WhichID and Offset
void InvalidateItem_ForWhichID(sal_uInt16 nWhich);
@@ -270,9 +278,6 @@ private:
// split version(s) of GetItemStateImpl for input types WhichID and Offset
SfxItemState GetItemState_ForWhichID( SfxItemState eState, sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem) const;
SfxItemState GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPoolItem **ppItem) const;
-
- SfxPoolItem const* implCreateItemEntry(SfxPoolItem const* pSource, sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership);
- void implCleanupItemEntry(SfxPoolItem const* pSource);
};
inline void SfxItemSet::SetParent( const SfxItemSet* pNew )
@@ -292,7 +297,7 @@ public:
virtual std::unique_ptr<SfxItemSet> Clone( bool bItems = true, SfxItemPool *pToPool = nullptr ) const override;
private:
- virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bItemIsSetMember,bool bPassingOwnership ) override;
+ virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bPassingOwnership ) override;
};
diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx
index 4714e2f44be6..b434302a2f85 100644
--- a/include/svl/poolitem.hxx
+++ b/include/svl/poolitem.hxx
@@ -100,6 +100,7 @@ enum class SfxItemState {
#ifdef DBG_UTIL
SVL_DLLPUBLIC size_t getAllocatedSfxPoolItemCount();
SVL_DLLPUBLIC size_t getUsedSfxPoolItemCount();
+SVL_DLLPUBLIC void listAllocatedSfxPoolItems();
#endif
class SfxItemPool;
@@ -108,31 +109,40 @@ typedef struct _xmlTextWriter* xmlTextWriterPtr;
class SVL_DLLPUBLIC SfxPoolItem
{
-friend class SfxItemPool;
-friend class SfxItemDisruptor_Impl;
-friend class SfxItemPoolCache;
-friend class SfxItemSet;
+ friend class SfxItemPool;
+ friend class SfxItemDisruptor_Impl;
+ friend class SfxItemPoolCache;
+ friend class SfxItemSet;
+
+ // allow ItemSetTooling to access
+ friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool, bool);
+ friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
mutable sal_uInt32 m_nRefCount;
sal_uInt16 m_nWhich;
+#ifdef DBG_UTIL
+ // for debugging add a serial number, will be set in the constructor
+ // and count up from zero. If you have a deterministic error case and
+ // see the Item involved in the debugger you can use that number in
+ // the next run to see where that Item gets constructed and how it is
+ // involved/ processed
+ sal_uInt32 m_nSerialNumber;
+#endif
+
// bitfield for flags (instead of SfxItemKind)
- bool m_bIsVoidItem : 1;
- bool m_bDeleteOnIdle : 1;
- bool m_bStaticDefault : 1;
- bool m_bPoolDefault : 1;
+ bool m_bIsVoidItem : 1; // bit 0
+ bool m_bDeleteOnIdle : 1; // bit 1
+ bool m_bStaticDefault : 1; // bit 2
+ bool m_bPoolDefault : 1; // bit 3
+ bool m_bRegisteredAtPool : 1; // bit 4
+ bool m_bNewItemCallback : 1; // bit 5
+ bool m_bIsSetItem : 1; // bit 6
protected:
- // Defines if the Item can be shared/RefCounted else it will be cloned.
- // Default is true - as it should be for all Items. It is needed by some
- // SW items, so protected to let them set it in constructor. If this could
- // be fixed at that Items we may remove this again.
- bool m_bShareable : 1;
-
-private:
#ifdef DBG_UTIL
// this flag will make debugging item stuff much simpler
- bool m_bDeleted : 1;
+ bool m_bDeleted : 1; // bit 7
#endif
private:
@@ -143,10 +153,13 @@ private:
}
protected:
- void setVoidItem() { m_bIsVoidItem = true; }
+ void setIsVoidItem() { m_bIsVoidItem = true; }
void setDeleteOnIdle() { m_bDeleteOnIdle = true; }
void setStaticDefault() { m_bStaticDefault = true; }
void setPoolDefault() { m_bPoolDefault = true; }
+ void setRegisteredAtPool(bool bNew) { m_bRegisteredAtPool = bNew; }
+ void setNewItemCallback() { m_bNewItemCallback = true; }
+ void setIsSetItem() { m_bIsSetItem = true; }
public:
inline void AddRef(sal_uInt32 n = 1) const
@@ -156,11 +169,23 @@ public:
m_nRefCount += n;
}
+#ifdef DBG_UTIL
+ sal_uInt32 getSerialNumber() const { return m_nSerialNumber; }
+#endif
+
bool isVoidItem() const { return m_bIsVoidItem; }
bool isDeleteOnIdle() const { return m_bDeleteOnIdle; }
bool isStaticDefault() const { return m_bStaticDefault; }
bool isPoolDefault() const { return m_bPoolDefault; }
- bool isShareable() const { return m_bShareable; }
+ bool isRegisteredAtPool() const { return m_bRegisteredAtPool; }
+ bool isNewItemCallback() const { return m_bNewItemCallback; }
+ bool isSetItem() const { return m_bIsSetItem; }
+
+ // version that allows nullptrs
+ static bool areSame(const SfxPoolItem* pItem1, const SfxPoolItem* pItem2);
+
+ // if you have the items (not nullptrs) use this version
+ static bool areSame(const SfxPoolItem& rItem1, const SfxPoolItem& rItem2);
private:
inline sal_uInt32 ReleaseRef(sal_uInt32 n = 1) const
@@ -223,24 +248,6 @@ public:
bool operator!=( const SfxPoolItem& rItem ) const
{ return !(*this == rItem); }
- // Sorting is only used for faster searching in a pool which contains large quantities
- // of a single kind of pool item.
- virtual bool operator<( const SfxPoolItem& ) const { assert(false); return false; }
- virtual bool IsSortable() const { return false; }
-
- // Some item types cannot be IsSortable() (such as because they are modified while stored
- // in a pool, which would change the ordering position, see e.g. 585e0ac43b9bd8a2f714903034).
- // To improve performance in such cases it is possible to reimplement Lookup() to do a linear
- // lookup optimized for the specific class (avoiding virtual functions may allow the compiler
- // to generate better code and class-specific optimizations such as hashing or caching may
- // be used.)
- // If reimplemented, the Lookup() function should search [begin,end) for an item matching
- // this object and return an iterator pointing to the item or the end iterator.
- virtual bool HasLookup() const { return false; }
- typedef std::vector<SfxPoolItem*>::const_iterator lookup_iterator;
- virtual lookup_iterator Lookup(lookup_iterator /*begin*/, lookup_iterator end ) const
- { assert( false ); return end; }
-
/** @return true if it has a valid string representation */
virtual bool GetPresentation( SfxItemPresentation ePresentation,
MapUnit eCoreMetric,
@@ -299,6 +306,8 @@ inline bool IsInvalidItem(const SfxPoolItem *pItem)
return pItem == INVALID_POOL_ITEM;
}
+SVL_DLLPUBLIC bool areSfxPoolItemPtrsEqual(const SfxPoolItem* pItem1, const SfxPoolItem* pItem2);
+
class SVL_DLLPUBLIC SfxPoolItemHint final : public SfxHint
{
SfxPoolItem* pObj;
diff --git a/include/svx/pageitem.hxx b/include/svx/pageitem.hxx
index 32702fe8089f..de93730731d2 100644
--- a/include/svx/pageitem.hxx
+++ b/include/svx/pageitem.hxx
@@ -98,7 +98,7 @@ class SVX_DLLPUBLIC SvxSetItem final : public SfxSetItem
{
public:
SvxSetItem( const TypedWhichId<SvxSetItem> nId, const SfxItemSet& rSet );
- SvxSetItem( const SvxSetItem& rItem );
+ SvxSetItem( const SvxSetItem& rItem, SfxItemPool* pPool = nullptr );
SvxSetItem( const TypedWhichId<SvxSetItem> nId, SfxItemSet&& pSet );
virtual SvxSetItem* Clone( SfxItemPool *pPool = nullptr ) const override;
diff --git a/include/svx/sdasitm.hxx b/include/svx/sdasitm.hxx
index e53e9c3604a2..cb7230afe703 100644
--- a/include/svx/sdasitm.hxx
+++ b/include/svx/sdasitm.hxx
@@ -70,8 +70,6 @@ private:
SdrCustomShapeGeometryItem & operator =(SdrCustomShapeGeometryItem &&) = delete; // due to SfxPoolItem
virtual bool operator==( const SfxPoolItem& ) const override;
- virtual bool operator<( const SfxPoolItem& ) const override;
- virtual bool IsSortable() const override { return true; }
virtual bool GetPresentation(SfxItemPresentation ePresentation,
MapUnit eCoreMetric, MapUnit ePresentationMetric,
diff --git a/include/svx/xbtmpit.hxx b/include/svx/xbtmpit.hxx
index 0882081fb7ca..6d7d75f3de7c 100644
--- a/include/svx/xbtmpit.hxx
+++ b/include/svx/xbtmpit.hxx
@@ -41,8 +41,6 @@ public:
XFillBitmapItem( const XFillBitmapItem& rItem );
virtual bool operator==( const SfxPoolItem& rItem ) const override;
- // no idea why, but this item does not play nice with the sorting optimisation, get failures in sd_import_tests
- virtual bool IsSortable() const override { return false; }
virtual XFillBitmapItem* Clone( SfxItemPool* pPool = nullptr ) const override;
virtual bool QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const override;