include/svl/itemset.hxx | 5 + include/svl/poolitem.hxx | 94 ++++++++++++++---------------- include/svl/voiditem.hxx | 8 -- sc/source/ui/cctrl/tbzoomsliderctrl.cxx | 2 sd/source/ui/app/scalectrl.cxx | 3 sd/source/ui/app/tmplctrl.cxx | 3 sfx2/source/control/ctrlitem.cxx | 2 sfx2/source/control/dispatch.cxx | 4 - sfx2/source/control/itemdel.cxx | 2 sfx2/source/control/unoctitm.cxx | 6 - sfx2/source/doc/objxtor.cxx | 2 sfx2/source/statbar/stbitem.cxx | 2 sfx2/source/toolbox/tbxitem.cxx | 2 svl/source/items/itempool.cxx | 16 ++--- svl/source/items/itemset.cxx | 40 +++++++++++- svl/source/items/poolitem.cxx | 11 ++- svl/source/items/voiditem.cxx | 15 ++++ svx/source/stbctrls/zoomsliderctrl.cxx | 2 sw/source/uibase/docvw/romenu.cxx | 2 sw/source/uibase/utlui/bookctrl.cxx | 2 sw/source/uibase/utlui/viewlayoutctrl.cxx | 2 vcl/source/app/svapp.cxx | 5 + 22 files changed, 143 insertions(+), 87 deletions(-)
New commits: commit 5f7a3126fcad1b490b6e1ef6775b31bac99f3c18 Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Sun Sep 10 20:35:26 2023 +0200 Commit: Armin Le Grand <armin.le.gr...@me.com> CommitDate: Mon Sep 11 12:59:53 2023 +0200 ITEM: Diverse further changes/cleanups/preparation Added a counter for SfxItemSet usages, similar to the already added one for SfxPoolItems to allow quick info about evtl. problems/drawbacks of changes. Replaced enum SfxItemKind in favour of settable boolean flags directly at SfxPoolItem. These are organized as bitfield, do not need more space as the enum and allow to be set separately and multiple ones at the same time. Flags for PoolDefault/StaticDefault/DeleteOnIdle use this now and are quickly accessible booleans. It is not a problem that theoretically the flags for PoolDefault/StaticDefault could now both be set - this is internal to SfxItem stuff and not accessible from normal code, so can be managed. Added for debug build a bitfield boolean m_bDeleted that will be set in the SfxPoolItem destructor. Of course it's usability will depend on the freed space not yet being re-used, but will hopefully help in the debugger to detect reasons for failure (would have helped at least me before). Added for replacement of virtual method IsVoidItem() another bitfield bool m_bIsVoidItem that is set in the constructors of SfxVoidItem. Also had to add some constructors to do that which were defaulted before. This is mainly because the base class SfxPoolItem does *not* have a copy-constructor that copies the members (flags/RefCnt/WhichID) and we should keep that 'indirect reset' when Cloning. isVoidItem() is now a simple boolean member access - the bitfield does the needed masking. This spares one entry in the virtual function table of SfxPoolItem which is derived more than 500 times. Used the results of the experiment at https://gerrit.libreoffice.org/c/core/+/156774 to change some accesses to IsVoidItem() to use SfxItemState instead. This is for preparation of splitting up the two usages of SfxVoidItems, see commit text in the experiment. If this shows problems in the future those six places documented there may have to be changed back to use the new isVoidItem(), but should also check the ptr this time to be non-zero. Removed SFX_ITEMS_SPECIAL that is no more used anywhere. Change-Id: Ib687ca2362d72a4651c75aee0c67029088f68947 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156805 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index ba14c21b8e6c..6d95ec505c0f 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -33,6 +33,11 @@ class SfxItemPool; +#ifdef DBG_UTIL +SVL_DLLPUBLIC size_t getAllocatedSfxItemSetCount(); +SVL_DLLPUBLIC size_t getUsedSfxItemSetCount(); +#endif + class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet { friend class SfxItemIter; diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx index 46dd8b0a76f5..ce4d94e782f9 100644 --- a/include/svl/poolitem.hxx +++ b/include/svl/poolitem.hxx @@ -35,17 +35,8 @@ class IntlWrapper; -enum class SfxItemKind : sal_Int8 -{ - NONE, - DeleteOnIdle, - StaticDefault, - PoolDefault -}; - #define SFX_ITEMS_OLD_MAXREF 0xffef #define SFX_ITEMS_MAXREF 0xfffffffe -#define SFX_ITEMS_SPECIAL 0xffffffff #define CONVERT_TWIPS 0x80 // Uno conversion for measurement (for MemberId) @@ -124,15 +115,51 @@ friend class SfxItemSet; mutable sal_uInt32 m_nRefCount; sal_uInt16 m_nWhich; - SfxItemKind m_nKind; + + // bitfield for flags (instead of SfxItemKind) + bool m_bIsVoidItem : 1; + bool m_bDeleteOnIdle : 1; + bool m_bStaticDefault : 1; + bool m_bPoolDefault : 1; +#ifdef DBG_UTIL + // this flag will make debugging item stuff much simpler + bool m_bDeleted : 1; +#endif private: - inline void SetRefCount(sal_uInt32 n); - inline void SetKind( SfxItemKind n ); + inline void SetRefCount(sal_uInt32 n) + { + m_nRefCount = n; + m_bStaticDefault = m_bPoolDefault = false; + } + +protected: + void setVoidItem() { m_bIsVoidItem = true; } + void setDeleteOnIdle() { m_bDeleteOnIdle = true; } + void setStaticDefault() { m_bStaticDefault = true; } + void setPoolDefault() { m_bPoolDefault = true; } + public: - inline void AddRef(sal_uInt32 n = 1) const; + inline void AddRef(sal_uInt32 n = 1) const + { + assert(m_nRefCount <= SFX_ITEMS_MAXREF && "AddRef with non-Pool-Item"); + assert(n <= SFX_ITEMS_MAXREF - m_nRefCount && "AddRef: refcount overflow"); + m_nRefCount += n; + } + + bool isVoidItem() const { return m_bIsVoidItem; } + bool isDeleteOnIdle() const { return m_bDeleteOnIdle; } + bool isStaticDefault() const { return m_bStaticDefault; } + bool isPoolDefault() const { return m_bPoolDefault; } + private: - inline sal_uInt32 ReleaseRef(sal_uInt32 n = 1) const; + inline sal_uInt32 ReleaseRef(sal_uInt32 n = 1) const + { + assert(m_nRefCount <= SFX_ITEMS_MAXREF && "ReleaseRef with non-Pool-Item"); + assert(n <= m_nRefCount); + m_nRefCount -= n; + return m_nRefCount; + } protected: explicit SfxPoolItem( sal_uInt16 nWhich = 0 ); @@ -226,61 +253,28 @@ public: } sal_uInt32 GetRefCount() const { return m_nRefCount; } - SfxItemKind GetKind() const { return m_nKind; } virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; virtual boost::property_tree::ptree dumpAsJSON() const; - /** Only SfxVoidItem shall and must return true for this. - - This avoids costly calls to dynamic_cast<const SfxVoidItem*>() - specifically in SfxItemSet::GetItemState() - */ - virtual bool IsVoidItem() const; - private: SfxPoolItem& operator=( const SfxPoolItem& ) = delete; }; -inline void SfxPoolItem::SetRefCount(sal_uInt32 n) -{ - m_nRefCount = n; - m_nKind = SfxItemKind::NONE; -} -inline void SfxPoolItem::SetKind( SfxItemKind n ) -{ - m_nRefCount = SFX_ITEMS_SPECIAL; - m_nKind = n; -} - -inline void SfxPoolItem::AddRef(sal_uInt32 n) const -{ - assert(m_nRefCount <= SFX_ITEMS_MAXREF && "AddRef with non-Pool-Item"); - assert(n <= SFX_ITEMS_MAXREF - m_nRefCount && "AddRef: refcount overflow"); - m_nRefCount += n; -} - -inline sal_uInt32 SfxPoolItem::ReleaseRef(sal_uInt32 n) const -{ - assert(m_nRefCount <= SFX_ITEMS_MAXREF && "ReleaseRef with non-Pool-Item"); - assert(n <= m_nRefCount); - m_nRefCount -= n; - return m_nRefCount; -} inline bool IsPoolDefaultItem(const SfxPoolItem *pItem ) { - return pItem && pItem->GetKind() == SfxItemKind::PoolDefault; + return pItem && pItem->isPoolDefault(); } inline bool IsStaticDefaultItem(const SfxPoolItem *pItem ) { - return pItem && pItem->GetKind() == SfxItemKind::StaticDefault; + return pItem && pItem->isStaticDefault(); } inline bool IsDefaultItem( const SfxPoolItem *pItem ) { - return pItem && (pItem->GetKind() == SfxItemKind::StaticDefault || pItem->GetKind() == SfxItemKind::PoolDefault); + return pItem && (pItem->isPoolDefault() || pItem->isStaticDefault()); } inline bool IsPooledItem( const SfxPoolItem *pItem ) diff --git a/include/svl/voiditem.hxx b/include/svl/voiditem.hxx index b06f28e84b2e..911c691470fb 100644 --- a/include/svl/voiditem.hxx +++ b/include/svl/voiditem.hxx @@ -26,11 +26,12 @@ class SVL_DLLPUBLIC SfxVoidItem final : public SfxPoolItem { public: static SfxPoolItem* CreateDefault(); + explicit SfxVoidItem(sal_uInt16 nWhich); + SfxVoidItem(const SfxVoidItem& rCopy); + SfxVoidItem(SfxVoidItem&& rOrig); virtual ~SfxVoidItem() override; - SfxVoidItem(SfxVoidItem const&) = default; - SfxVoidItem(SfxVoidItem&&) = default; SfxVoidItem& operator=(SfxVoidItem const&) = delete; // due to SfxPoolItem SfxVoidItem& operator=(SfxVoidItem&&) = delete; // due to SfxPoolItem @@ -43,9 +44,6 @@ public: // create a copy of itself virtual SfxVoidItem* Clone(SfxItemPool* pPool = nullptr) const override; - - /** Always returns true as this is an SfxVoidItem. */ - virtual bool IsVoidItem() const override; }; #endif diff --git a/sc/source/ui/cctrl/tbzoomsliderctrl.cxx b/sc/source/ui/cctrl/tbzoomsliderctrl.cxx index 0168eaf3e93a..4ec776de100c 100644 --- a/sc/source/ui/cctrl/tbzoomsliderctrl.cxx +++ b/sc/source/ui/cctrl/tbzoomsliderctrl.cxx @@ -59,7 +59,7 @@ void ScZoomSliderControl::StateChangedAtToolBoxControl( sal_uInt16 /*nSID*/, Sfx ScZoomSliderWnd* pBox = static_cast<ScZoomSliderWnd*>(rTbx.GetItemWindow( nId )); OSL_ENSURE( pBox ,"Control not found!" ); - if ( SfxItemState::DEFAULT != eState || pState->IsVoidItem() ) + if (SfxItemState::DEFAULT != eState || SfxItemState::DISABLED == eState) { SvxZoomSliderItem aZoomSliderItem( 100 ); pBox->Disable(); diff --git a/sd/source/ui/app/scalectrl.cxx b/sd/source/ui/app/scalectrl.cxx index 84667f41cebb..c2d3f034a031 100644 --- a/sd/source/ui/app/scalectrl.cxx +++ b/sd/source/ui/app/scalectrl.cxx @@ -47,8 +47,9 @@ SdScaleControl::~SdScaleControl() {} void SdScaleControl::StateChangedAtStatusBarControl(sal_uInt16 /*nSID*/, SfxItemState eState, const SfxPoolItem* pState) { - if (eState != SfxItemState::DEFAULT || pState->IsVoidItem()) + if (eState != SfxItemState::DEFAULT || SfxItemState::DISABLED == eState) return; + auto pStringItem = dynamic_cast<const SfxStringItem*>(pState); if (!pStringItem) { diff --git a/sd/source/ui/app/tmplctrl.cxx b/sd/source/ui/app/tmplctrl.cxx index c8a8da9e5027..ffc79e923c71 100644 --- a/sd/source/ui/app/tmplctrl.cxx +++ b/sd/source/ui/app/tmplctrl.cxx @@ -51,8 +51,9 @@ SdTemplateControl::~SdTemplateControl() void SdTemplateControl::StateChangedAtStatusBarControl( sal_uInt16 /*nSID*/, SfxItemState eState, const SfxPoolItem* pState ) { - if( eState != SfxItemState::DEFAULT || pState->IsVoidItem() ) + if (eState != SfxItemState::DEFAULT || SfxItemState::DISABLED == eState) GetStatusBar().SetItemText( GetId(), OUString() ); + else if ( auto pStringItem = dynamic_cast< const SfxStringItem *>( pState ) ) { msTemplate = pStringItem->GetValue(); diff --git a/sfx2/source/control/ctrlitem.cxx b/sfx2/source/control/ctrlitem.cxx index 21618056469a..9a8c6e0203a2 100644 --- a/sfx2/source/control/ctrlitem.cxx +++ b/sfx2/source/control/ctrlitem.cxx @@ -293,7 +293,7 @@ SfxItemState SfxControllerItem::GetItemState ? SfxItemState::DISABLED : IsInvalidItem(pState) ? SfxItemState::DONTCARE - : pState->IsVoidItem() && !pState->Which() + : pState->isVoidItem() && !pState->Which() ? SfxItemState::UNKNOWN : SfxItemState::DEFAULT; } diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index af57a5e3ab2f..c047f854a810 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -1694,7 +1694,7 @@ bool SfxDispatcher::FillState_(const SfxSlotServer& rSvr, SfxItemSet& rState, pItem; pItem = aIter.NextItem() ) { - if ( !IsInvalidItem(pItem) && !pItem->IsVoidItem() ) + if ( !IsInvalidItem(pItem) && !pItem->isVoidItem() ) { sal_uInt16 nSlotId = rState.GetPool()->GetSlotId(pItem->Which()); SAL_INFO_IF( @@ -1995,7 +1995,7 @@ SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSID, css::uno::Any& rAny ) else { css::uno::Any aState; - if ( !pItem->IsVoidItem() ) + if ( !pItem->isVoidItem() ) { sal_uInt16 nSubId( 0 ); SfxItemPool& rPool = pShell->GetPool(); diff --git a/sfx2/source/control/itemdel.cxx b/sfx2/source/control/itemdel.cxx index c96a9d0f4ba3..ce6f4e1b9303 100644 --- a/sfx2/source/control/itemdel.cxx +++ b/sfx2/source/control/itemdel.cxx @@ -31,7 +31,7 @@ class SfxItemDisruptor_Impl public: static void DeleteItemOnIdle(std::unique_ptr<SfxPoolItem> pItem) { - pItem->SetKind(SfxItemKind::DeleteOnIdle); + pItem->setDeleteOnIdle(); Application::PostUserEvent(LINK(nullptr, SfxItemDisruptor_Impl, Delete), pItem.release()); // coverity[leaked_storage] - pDisruptor takes care of its own destruction at idle time } diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx index 9b75d0a51118..89e94caff794 100644 --- a/sfx2/source/control/unoctitm.cxx +++ b/sfx2/source/control/unoctitm.cxx @@ -670,7 +670,7 @@ void SfxDispatchController_Impl::dispatch( const css::util::URL& aURL, { if (const SfxBoolItem* pBoolItem = dynamic_cast<const SfxBoolItem*>(pItem)) bSuccess = pBoolItem->GetValue(); - else if ( !pItem->IsVoidItem() ) + else if ( !pItem->isVoidItem() ) bSuccess = true; // all other types are true } // else bSuccess = false look to line 664 it is false @@ -733,7 +733,7 @@ void SfxDispatchController_Impl::dispatch( const css::util::URL& aURL, aEvent.State = css::frame::DispatchResultState::FAILURE; aEvent.Source = static_cast<css::frame::XDispatch*>(pDispatch); - if ( bSuccess && pItem && !pItem->IsVoidItem() ) + if ( bSuccess && pItem && !pItem->isVoidItem() ) { sal_uInt16 nSubId( 0 ); if ( eMapUnit == MapUnit::MapTwip ) @@ -834,7 +834,7 @@ void SfxDispatchController_Impl::StateChanged( sal_uInt16 nSID, SfxItemState eSt return; css::uno::Any aState; - if ( ( eState >= SfxItemState::DEFAULT ) && pState && !IsInvalidItem( pState ) && !pState->IsVoidItem() ) + if ( ( eState >= SfxItemState::DEFAULT ) && pState && !IsInvalidItem( pState ) && !pState->isVoidItem() ) { // Retrieve metric from pool to have correct sub ID when calling QueryValue sal_uInt16 nSubId( 0 ); diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx index 917935d907d1..8c3029edd128 100644 --- a/sfx2/source/doc/objxtor.cxx +++ b/sfx2/source/doc/objxtor.cxx @@ -587,7 +587,7 @@ bool SfxObjectShell::PrepareClose pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs ); } - if ( !pPoolItem || pPoolItem->IsVoidItem() ) + if ( !pPoolItem || pPoolItem->isVoidItem() ) return false; if ( auto pBoolItem = dynamic_cast< const SfxBoolItem *>( pPoolItem ) ) if ( !pBoolItem->GetValue() ) diff --git a/sfx2/source/statbar/stbitem.cxx b/sfx2/source/statbar/stbitem.cxx index 2387557d6ba9..6e9ee1bcaa95 100644 --- a/sfx2/source/statbar/stbitem.cxx +++ b/sfx2/source/statbar/stbitem.cxx @@ -376,7 +376,7 @@ void SfxStatusBarControl::StateChangedAtStatusBarControl pBar->SetItemText( nSID, pStr->GetValue() ); else { - DBG_ASSERT( eState != SfxItemState::DEFAULT || pState->IsVoidItem(), + DBG_ASSERT( eState != SfxItemState::DEFAULT || pState->isVoidItem(), "wrong SfxPoolItem subclass in SfxStatusBarControl" ); pBar->SetItemText( nSID, OUString() ); } diff --git a/sfx2/source/toolbox/tbxitem.cxx b/sfx2/source/toolbox/tbxitem.cxx index f355806aaa00..bf01be5e1921 100644 --- a/sfx2/source/toolbox/tbxitem.cxx +++ b/sfx2/source/toolbox/tbxitem.cxx @@ -234,7 +234,7 @@ SfxItemState SfxToolBoxControl::GetItemState( ? SfxItemState::DISABLED : IsInvalidItem(pState) ? SfxItemState::DONTCARE - : pState->IsVoidItem() && !pState->Which() + : pState->isVoidItem() && !pState->Which() ? SfxItemState::UNKNOWN : SfxItemState::DEFAULT; } diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx index 3cef59683ad7..525adf309fb8 100644 --- a/svl/source/items/itempool.cxx +++ b/svl/source/items/itempool.cxx @@ -281,7 +281,7 @@ SfxItemPool::SfxItemPool for ( sal_uInt16 n = 0; n <= pImpl->mnEnd - pImpl->mnStart; ++n ) { (*ppDefaults)[n] = (*rPool.pImpl->mpStaticDefaults)[n]->Clone(this); - (*ppDefaults)[n]->SetKind(SfxItemKind::StaticDefault); + (*ppDefaults)[n]->setStaticDefault(); } SetDefaults( ppDefaults ); @@ -294,7 +294,7 @@ SfxItemPool::SfxItemPool if (rPool.pImpl->maPoolDefaults[n]) { pImpl->maPoolDefaults[n] = rPool.pImpl->maPoolDefaults[n]->Clone(this); //resets kind - pImpl->maPoolDefaults[n]->SetKind(SfxItemKind::PoolDefault); + pImpl->maPoolDefaults[n]->setPoolDefault(); } // Repair linkage @@ -318,7 +318,7 @@ void SfxItemPool::SetDefaults( std::vector<SfxPoolItem*>* pDefaults ) { assert( ((*pImpl->mpStaticDefaults)[n]->Which() == n + pImpl->mnStart) && "items ids in pool-ranges and in static-defaults do not match" ); - (*pImpl->mpStaticDefaults)[n]->SetKind(SfxItemKind::StaticDefault); + (*pImpl->mpStaticDefaults)[n]->setStaticDefault(); DBG_ASSERT( pImpl->maPoolItemArrays[n].empty(), "defaults with setitems with items?!" ); } } @@ -589,7 +589,7 @@ void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem) auto& rOldDefault = pImpl->maPoolDefaults[GetIndex_Impl(rItem.Which())]; SfxPoolItem *pNewDefault = rItem.Clone(this); - pNewDefault->SetKind(SfxItemKind::PoolDefault); + pNewDefault->setPoolDefault(); if (rOldDefault) { rOldDefault->SetRefCount(0); @@ -650,7 +650,7 @@ const SfxPoolItem& SfxItemPool::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nW if (bSID) { assert((rItem.Which() != nWhich || - !IsDefaultItem(&rItem) || rItem.GetKind() == SfxItemKind::DeleteOnIdle) + !IsDefaultItem(&rItem) || rItem.isDeleteOnIdle()) && "a non Pool Item is Default?!"); SfxPoolItem *pPoolItem = rItem.Clone(pImpl->mpMaster); pPoolItem->SetWhich(nWhich); @@ -776,14 +776,16 @@ void SfxItemPool::Remove( const SfxPoolItem& rItem ) return; } - assert(rItem.GetRefCount() && "RefCount == 0, Remove impossible"); - const sal_uInt16 nIndex = GetIndex_Impl(nWhich); // Static Defaults are just there if ( IsStaticDefaultItem(&rItem) && &rItem == (*pImpl->mpStaticDefaults)[nIndex]) return; + // moved below StaticDefaultItem detection - StaticDefaultItems + // do not need a RefCnt of SFX_ITEMS_SPECIAL (0xffffffff) anymore + assert(rItem.GetRefCount() && "RefCount == 0, Remove impossible"); + // Find Item in own Pool SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[nIndex]; diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx index 7be410c2bd78..4f71a8aafb5e 100644 --- a/svl/source/items/itemset.cxx +++ b/svl/source/items/itemset.cxx @@ -36,6 +36,13 @@ #include <items_helper.hxx> +#ifdef DBG_UTIL +static size_t nAllocatedSfxItemSetCount(0); +static size_t nUsedSfxItemSetCount(0); +size_t getAllocatedSfxItemSetCount() { return nAllocatedSfxItemSetCount; } +size_t getUsedSfxItemSetCount() { return nUsedSfxItemSetCount; } +#endif + /** * Ctor for a SfxItemSet with exactly the Which Ranges, which are known to * the supplied SfxItemPool. @@ -55,6 +62,10 @@ SfxItemSet::SfxItemSet(SfxItemPool& rPool) , m_pWhichRanges(rPool.GetFrozenIdRanges()) , m_aCallback() { +#ifdef DBG_UTIL + nAllocatedSfxItemSetCount++; + nUsedSfxItemSetCount++; +#endif assert(svl::detail::validRanges2(m_pWhichRanges)); } @@ -68,6 +79,10 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, SfxAllItemSetFlag ) , m_pWhichRanges() , m_aCallback() { +#ifdef DBG_UTIL + nAllocatedSfxItemSetCount++; + nUsedSfxItemSetCount++; +#endif } /** special constructor for SfxItemSetFixed */ @@ -81,6 +96,10 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, WhichRangesContainer&& ranges, SfxPo , m_pWhichRanges(std::move(ranges)) , m_aCallback() { +#ifdef DBG_UTIL + nAllocatedSfxItemSetCount++; + nUsedSfxItemSetCount++; +#endif assert(ppItems); assert(m_pWhichRanges.size() > 0); assert(svl::detail::validRanges2(m_pWhichRanges)); @@ -96,6 +115,10 @@ SfxItemSet::SfxItemSet(SfxItemPool& pool, WhichRangesContainer wids) , m_pWhichRanges(std::move(wids)) , m_aCallback() { +#ifdef DBG_UTIL + nAllocatedSfxItemSetCount++; + nUsedSfxItemSetCount++; +#endif assert(svl::detail::CountRanges(m_pWhichRanges) != 0); assert(svl::detail::validRanges2(m_pWhichRanges)); } @@ -186,6 +209,10 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) , m_pWhichRanges( rASet.m_pWhichRanges ) , m_aCallback(rASet.m_aCallback) { +#ifdef DBG_UTIL + nAllocatedSfxItemSetCount++; + nUsedSfxItemSetCount++; +#endif if (rASet.GetRanges().empty()) { return; @@ -217,6 +244,10 @@ SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept , m_pWhichRanges( std::move(rASet.m_pWhichRanges) ) , m_aCallback(rASet.m_aCallback) { +#ifdef DBG_UTIL + nAllocatedSfxItemSetCount++; + nUsedSfxItemSetCount++; +#endif if (rASet.m_bItemsFixed) { // have to make a copy @@ -242,6 +273,9 @@ SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept SfxItemSet::~SfxItemSet() { +#ifdef DBG_UTIL + nAllocatedSfxItemSetCount--; +#endif // cleanup items. No std::fill needed, we are done with this ItemSet. // the callback is not set in destructor, so no worries about that ClearAllItemsImpl(); @@ -289,7 +323,7 @@ sal_uInt16 SfxItemSet::ClearSingleItem_ForOffset( sal_uInt16 nOffset ) { assert(nOffset < TotalCount()); const_iterator aEntry(begin() + nOffset); - assert(nullptr == *aEntry || IsInvalidItem(*aEntry) || (*aEntry)->IsVoidItem() || 0 != (*aEntry)->Which()); + assert(nullptr == *aEntry || IsInvalidItem(*aEntry) || (*aEntry)->isVoidItem() || 0 != (*aEntry)->Which()); if (nullptr == *aEntry) // no entry, done @@ -399,7 +433,7 @@ SfxItemState SfxItemSet::GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPo // Different ones are present return SfxItemState::DONTCARE; - if (pCandidate->IsVoidItem()) + if (pCandidate->isVoidItem()) // Item is Disabled return SfxItemState::DISABLED; @@ -864,7 +898,7 @@ const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const } #ifdef DBG_UTIL const SfxPoolItem *pItem = *aFoundOne; - if ( pItem->IsVoidItem() || !pItem->Which() ) + if ( pItem->isVoidItem() || !pItem->Which() ) SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item"); #endif return **aFoundOne; diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx index 9a45e8803448..a4f02d19b4e3 100644 --- a/svl/source/items/poolitem.cxx +++ b/svl/source/items/poolitem.cxx @@ -471,7 +471,13 @@ size_t getUsedSfxPoolItemCount() { return nUsedSfxPoolItemCount; } SfxPoolItem::SfxPoolItem(sal_uInt16 const nWhich) : m_nRefCount(0) , m_nWhich(nWhich) - , m_nKind(SfxItemKind::NONE) + , m_bIsVoidItem(false) + , m_bDeleteOnIdle(false) + , m_bStaticDefault(false) + , m_bPoolDefault(false) +#ifdef DBG_UTIL + , m_bDeleted(false) +#endif { #ifdef DBG_UTIL nAllocatedSfxPoolItemCount++; @@ -484,6 +490,7 @@ SfxPoolItem::~SfxPoolItem() { #ifdef DBG_UTIL nAllocatedSfxPoolItemCount--; + m_bDeleted = true; #endif assert((m_nRefCount == 0 || m_nRefCount > SFX_ITEMS_MAXREF) && "destroying item in use"); } @@ -574,8 +581,6 @@ std::unique_ptr<SfxPoolItem> SfxPoolItem::CloneSetWhich(sal_uInt16 nNewWhich) co return pItem; } -bool SfxPoolItem::IsVoidItem() const { return false; } - void SfxPoolItem::ScaleMetrics(tools::Long /*lMult*/, tools::Long /*lDiv*/) {} bool SfxPoolItem::HasMetrics() const { return false; } diff --git a/svl/source/items/voiditem.cxx b/svl/source/items/voiditem.cxx index 3afa64de5332..6977c28553d3 100644 --- a/svl/source/items/voiditem.cxx +++ b/svl/source/items/voiditem.cxx @@ -25,6 +25,19 @@ SfxPoolItem* SfxVoidItem::CreateDefault() { return new SfxVoidItem(0); } SfxVoidItem::SfxVoidItem(sal_uInt16 which) : SfxPoolItem(which) { + setVoidItem(); +} + +SfxVoidItem::SfxVoidItem(const SfxVoidItem& rCopy) + : SfxPoolItem(rCopy.Which()) +{ + setVoidItem(); +} + +SfxVoidItem::SfxVoidItem(SfxVoidItem&& rOrig) + : SfxPoolItem(rOrig) +{ + setVoidItem(); } bool SfxVoidItem::operator==(const SfxPoolItem& rCmp) const @@ -52,8 +65,6 @@ void SfxVoidItem::dumpAsXml(xmlTextWriterPtr pWriter) const SfxVoidItem* SfxVoidItem::Clone(SfxItemPool*) const { return new SfxVoidItem(*this); } -bool SfxVoidItem::IsVoidItem() const { return true; } - SfxVoidItem::~SfxVoidItem() {} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/stbctrls/zoomsliderctrl.cxx b/svx/source/stbctrls/zoomsliderctrl.cxx index 215c0556fc87..475f1da245bf 100644 --- a/svx/source/stbctrls/zoomsliderctrl.cxx +++ b/svx/source/stbctrls/zoomsliderctrl.cxx @@ -162,7 +162,7 @@ SvxZoomSliderControl::~SvxZoomSliderControl() void SvxZoomSliderControl::StateChangedAtStatusBarControl( sal_uInt16 /*nSID*/, SfxItemState eState, const SfxPoolItem* pState ) { - if ( (SfxItemState::DEFAULT != eState) || pState->IsVoidItem() ) + if (SfxItemState::DEFAULT != eState || SfxItemState::DISABLED == eState) { GetStatusBar().SetItemText( GetId(), "" ); mxImpl->mbValuesSet = false; diff --git a/sw/source/uibase/docvw/romenu.cxx b/sw/source/uibase/docvw/romenu.cxx index 02b4b1ebe7d9..05d352f181c3 100644 --- a/sw/source/uibase/docvw/romenu.cxx +++ b/sw/source/uibase/docvw/romenu.cxx @@ -60,7 +60,7 @@ void SwReadOnlyPopup::Check( sal_uInt16 nMID, sal_uInt16 nSID, SfxDispatcher con m_xMenu->EnableItem(nMID); if (_pItem) { - m_xMenu->CheckItem(nMID, !_pItem->IsVoidItem() && + m_xMenu->CheckItem(nMID, !_pItem->isVoidItem() && dynamic_cast< const SfxBoolItem *>( _pItem.get() ) != nullptr && static_cast<SfxBoolItem*>(_pItem.get())->GetValue()); //remove full screen entry when not in full screen mode diff --git a/sw/source/uibase/utlui/bookctrl.cxx b/sw/source/uibase/utlui/bookctrl.cxx index f7460b15d3e7..e79821022abc 100644 --- a/sw/source/uibase/utlui/bookctrl.cxx +++ b/sw/source/uibase/utlui/bookctrl.cxx @@ -48,7 +48,7 @@ SwBookmarkControl::~SwBookmarkControl() void SwBookmarkControl::StateChangedAtStatusBarControl( sal_uInt16 /*nSID*/, SfxItemState eState, const SfxPoolItem* pState ) { - if( eState != SfxItemState::DEFAULT || pState->IsVoidItem() ) + if (eState != SfxItemState::DEFAULT || SfxItemState::DISABLED == eState) { GetStatusBar().SetItemText(GetId(), OUString()); GetStatusBar().SetQuickHelpText(GetId(), OUString()); diff --git a/sw/source/uibase/utlui/viewlayoutctrl.cxx b/sw/source/uibase/utlui/viewlayoutctrl.cxx index 453dcd91a2eb..89dcc30175c2 100644 --- a/sw/source/uibase/utlui/viewlayoutctrl.cxx +++ b/sw/source/uibase/utlui/viewlayoutctrl.cxx @@ -63,7 +63,7 @@ SwViewLayoutControl::~SwViewLayoutControl() void SwViewLayoutControl::StateChangedAtStatusBarControl( sal_uInt16 /*nSID*/, SfxItemState eState, const SfxPoolItem* pState ) { - if ( SfxItemState::DEFAULT != eState || pState->IsVoidItem() ) + if (SfxItemState::DEFAULT != eState || SfxItemState::DISABLED == eState) { GetStatusBar().SetItemText( GetId(), OUString() ); mpImpl->mnState = 4; //tdf#148441 switch off, if disabled diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 020a1315ea89..19b8cd52b7e7 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -77,6 +77,7 @@ #ifdef DBG_UTIL #include <svl/poolitem.hxx> +#include <svl/itemset.hxx> #endif #include <cassert> @@ -193,6 +194,10 @@ Application::~Application() // would show in dramatically higher numbers then immediately SAL_WARN("vcl", "ITEM: " << getAllocatedSfxPoolItemCount() << " SfxPoolItems still allocated at shutdown"); SAL_WARN("vcl", "ITEM: " << getUsedSfxPoolItemCount() << " SfxPoolItems were incarnated during office usage"); + + // Same mechanism for SfxItemSet(s) + SAL_WARN("vcl", "ITEM: " << getAllocatedSfxItemSetCount() << " SfxItemSets still allocated at shutdown"); + SAL_WARN("vcl", "ITEM: " << getUsedSfxItemSetCount() << " SfxItemSets were incarnated during office usage"); #endif }