diff --git a/compilerplugins/clang/store/staticvar.cxx b/compilerplugins/clang/store/staticvar.cxx index 21cbd0f08172..774ab92245bb 100644 --- a/compilerplugins/clang/store/staticvar.cxx +++ b/compilerplugins/clang/store/staticvar.cxx @@ -53,7 +53,6 @@ public: || fn == SRCDIR "/sal/qa/rtl/digest/rtl_digest.cxx" || fn == SRCDIR "/sal/qa/rtl/strings/test_oustring_endswith.cxx" || fn == SRCDIR "/sal/qa/rtl/strings/test_oustring_convert.cxx" - || fn == SRCDIR "/svl/qa/unit/items/test_itempool.cxx" // contains mutable state || fn == SRCDIR "/vcl/unx/generic/dtrans/X11_selection.cxx" || fn == SRCDIR "/sax/qa/cppunit/xmlimport.cxx" diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx index 4b50b74b8b68..b4ef7edb6791 100644 --- a/cui/source/tabpages/tabarea.cxx +++ b/cui/source/tabpages/tabarea.cxx @@ -83,7 +83,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aColorListItem ); else - mpDrawModel->GetItemPool().DirectPutItemInPool(aColorListItem,SID_COLOR_TABLE); + mpDrawModel->GetItemPool().DirectPutItemInPool(aColorListItem); mpColorList = mpDrawModel->GetColorList(); } if( mpNewGradientList != mpDrawModel->GetGradientList() ) @@ -93,7 +93,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_GRADIENT_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); mpGradientList = mpDrawModel->GetGradientList(); } if( mpNewHatchingList != mpDrawModel->GetHatchList() ) @@ -103,7 +103,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_HATCH_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); mpHatchingList = mpDrawModel->GetHatchList(); } if( mpNewBitmapList != mpDrawModel->GetBitmapList() ) @@ -113,7 +113,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_BITMAP_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); mpBitmapList = mpDrawModel->GetBitmapList(); } if( mpNewPatternList != mpDrawModel->GetPatternList() ) @@ -123,7 +123,7 @@ void SvxAreaTabDialog::SavePalettes() if( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_PATTERN_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); mpPatternList = mpDrawModel->GetPatternList(); } diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx index d63522a555c1..7fa5389475e3 100644 --- a/editeng/source/editeng/impedit4.cxx +++ b/editeng/source/editeng/impedit4.cxx @@ -306,7 +306,9 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel ) else if ( nScriptType == 2 ) nWhich = EE_CHAR_FONTINFO_CTL; - for (const SfxPoolItem* pItem : maEditDoc.GetItemPool().GetItemSurrogates(nWhich)) + ItemSurrogates aSurrogates; + maEditDoc.GetItemPool().GetItemSurrogates(aSurrogates, nWhich); + for (const SfxPoolItem* pItem : aSurrogates) { SvxFontItem const*const pFontItem = static_cast(pItem); bool bAlreadyExist = false; @@ -390,7 +392,9 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel ) { aColorList.push_back(rDefault.GetValue()); } - for (const SfxPoolItem* pItem : maEditDoc.GetItemPool().GetItemSurrogates(EE_CHAR_COLOR)) + ItemSurrogates aSurrogates; + maEditDoc.GetItemPool().GetItemSurrogates(aSurrogates, EE_CHAR_COLOR); + for (const SfxPoolItem* pItem : aSurrogates) { auto pColorItem(dynamic_cast(pItem)); if (pColorItem && pColorItem->GetValue() != COL_AUTO) // may be null! diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx index 2e6c5a9a38d3..0a2153c33267 100644 --- a/include/svl/itempool.hxx +++ b/include/svl/itempool.hxx @@ -29,9 +29,7 @@ #include #include #include - -class SfxBroadcaster; -struct SfxItemPool_Impl; +#include struct SfxItemInfo { @@ -52,14 +50,17 @@ struct SfxItemInfo bool _bShareable : 1; }; -class SfxItemPool; -typedef std::unordered_set registeredSfxPoolItems; - #ifdef DBG_UTIL SVL_DLLPUBLIC size_t getAllDirectlyPooledSfxPoolItemCount(); SVL_DLLPUBLIC size_t getRemainingDirectlyPooledSfxPoolItemCount(); #endif +typedef std::unordered_set registeredSfxItemSets; +class SfxPoolItemHolder; +typedef std::unordered_set registeredSfxPoolItemHolders; +typedef std::unordered_set directPutSfxPoolItemHolders; +typedef std::vector ItemSurrogates; + /** Base class for providers of defaults of SfxPoolItems. * * The derived classes hold the concrete (const) instances which are referenced in several places @@ -69,21 +70,33 @@ SVL_DLLPUBLIC size_t getRemainingDirectlyPooledSfxPoolItemCount(); */ class SVL_DLLPUBLIC SfxItemPool : public salhelper::SimpleReferenceObject { - friend struct SfxItemPool_Impl; friend class SfxItemSet; + friend class SfxPoolItemHolder; friend class SfxAllItemSet; // allow ItemSetTooling to access friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool); - friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*); + friend void implCleanupItemEntry(SfxPoolItem const*); // unit testing friend class PoolItemTest; const SfxItemInfo* pItemInfos; - std::unique_ptr pImpl; + SfxBroadcaster aBC; + OUString aName; + std::vector maPoolDefaults; + std::vector* mpStaticDefaults; + SfxItemPool* mpMaster; + rtl::Reference mpSecondary; + WhichRangesContainer mpPoolRanges; + sal_uInt16 mnStart; + sal_uInt16 mnEnd; + MapUnit eDefMetric; - registeredSfxPoolItems** ppRegisteredSfxPoolItems; + registeredSfxItemSets maRegisteredSfxItemSets; + registeredSfxPoolItemHolders maRegisteredSfxPoolItemHolders; + directPutSfxPoolItemHolders maDirectPutItems; + bool mbPreDeleteDone; private: sal_uInt16 GetIndex_Impl(sal_uInt16 nWhich) const; @@ -94,6 +107,14 @@ private: SVL_DLLPRIVATE bool Shareable_Impl(sal_uInt16 nPos) const { return pItemInfos[nPos]._bShareable; } + void registerItemSet(SfxItemSet& rSet); + void unregisterItemSet(SfxItemSet& rSet); + + void registerPoolItemHolder(SfxPoolItemHolder& rHolder); + void unregisterPoolItemHolder(SfxPoolItemHolder& rHolder); + + void CollectSurrogates(std::unordered_set& rTarget, sal_uInt16 nWhich) const; + public: // for default SfxItemSet::CTOR, set default WhichRanges void FillItemIdRanges_Impl( WhichRangesContainer& pWhichRanges ) const; @@ -112,7 +133,6 @@ public: const SfxItemInfo *pItemInfos, std::vector *pDefaults = nullptr ); -public: virtual ~SfxItemPool(); SfxBroadcaster& BC(); @@ -167,34 +187,24 @@ public: virtual rtl::Reference Clone() const; const OUString& GetName() const; - template const T& DirectPutItemInPool( std::unique_ptr xItem, sal_uInt16 nWhich = 0 ) - { return static_cast(DirectPutItemInPoolImpl( *xItem.release(), nWhich, /*bPassingOwnership*/true)); } - template const T& DirectPutItemInPool( const T& rItem, sal_uInt16 nWhich = 0 ) - { return static_cast(DirectPutItemInPoolImpl( rItem, nWhich, /*bPassingOwnership*/false)); } - void DirectRemoveItemFromPool( const SfxPoolItem& ); + const SfxPoolItem& DirectPutItemInPool(const SfxPoolItem&); + void DirectRemoveItemFromPool(const SfxPoolItem&); const SfxPoolItem& GetDefaultItem( sal_uInt16 nWhich ) const; template const T& GetDefaultItem( TypedWhichId nWhich ) const { return static_cast(GetDefaultItem(sal_uInt16(nWhich))); } - - struct Item2Range - { - o3tl::sorted_vector::const_iterator m_begin; - o3tl::sorted_vector::const_iterator m_end; - o3tl::sorted_vector::const_iterator const & begin() const { return m_begin; } - o3tl::sorted_vector::const_iterator const & end() const { return m_end; } - }; const SfxPoolItem * GetItem2Default(sal_uInt16 nWhich) const; template const T* GetItem2Default( TypedWhichId nWhich ) const { return static_cast(GetItem2Default(sal_uInt16(nWhich))); } - const registeredSfxPoolItems& GetItemSurrogates(sal_uInt16 nWhich) const; +public: + void GetItemSurrogates(ItemSurrogates& rTarget, sal_uInt16 nWhich) const; /* This is only valid for SfxPoolItem that override IsSortable and operator<. Returns a range of items defined by using operator<. @param rNeedle must be the same type or a supertype of the pool items for nWhich. */ - std::vector FindItemSurrogate(sal_uInt16 nWhich, SfxPoolItem const & rNeedle) const; + void FindItemSurrogate(ItemSurrogates& rTarget, sal_uInt16 nWhich, SfxPoolItem const & rNeedle) const; sal_uInt16 GetFirstWhich() const; sal_uInt16 GetLastWhich() const; @@ -230,24 +240,6 @@ public: static bool IsSlot(sal_uInt16 nId) { return nId && nId > SFX_WHICH_MAX; } - // This method will try to register the Item at this Pool. - void registerSfxPoolItem(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: - const SfxPoolItem& DirectPutItemInPoolImpl( const SfxPoolItem&, sal_uInt16 nWhich = 0, bool bPassingOwnership = false ); - private: const SfxItemPool& operator=(const SfxItemPool &) = delete; diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index f3470098d42f..ae97ec991445 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -40,7 +40,7 @@ SVL_DLLPUBLIC size_t getUsedSfxPoolItemHolderCount(); // ItemSet/ItemPool helpers SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource, sal_uInt16 nWhich, bool bPassingOwnership); -void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource); +void implCleanupItemEntry(SfxPoolItem const* pSource); class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxPoolItemHolder { @@ -79,11 +79,12 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet // allow ItemSetTooling to access friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool); - friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*); + friend void implCleanupItemEntry(SfxPoolItem const*); SfxItemPool* m_pPool; ///< pool that stores the items const SfxItemSet* m_pParent; ///< derivation sal_uInt16 m_nCount; ///< number of items + sal_uInt16 m_nRegister; ///< number of items with NeedsPoolRegistration sal_uInt16 m_nTotalCount; ///< number of WhichIDs, also size of m_ppItems array // bitfield (better packaging if a bool needs to be added) @@ -95,6 +96,10 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet // Notification-Callback mechanism for SwAttrSet in SW, functionPtr for callback std::function m_aCallback; + // helpers to keep m_nRegister up-to-date + void checkRemovePoolRegistration(const SfxPoolItem* pItem); + void checkAddPoolRegistration(const SfxPoolItem* pItem); + protected: // Notification-Callback mechanism for SwAttrSet in SW void setCallback(const std::function &func) { m_aCallback = func; } diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx index ce65d63709cf..d2165a49a446 100644 --- a/include/svl/poolitem.hxx +++ b/include/svl/poolitem.hxx @@ -115,7 +115,7 @@ class SVL_DLLPUBLIC SfxPoolItem // allow ItemSetTooling to access friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool); - friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*); + friend void implCleanupItemEntry(SfxPoolItem const*); mutable sal_uInt32 m_nRefCount; sal_uInt16 m_nWhich; @@ -133,13 +133,12 @@ class SVL_DLLPUBLIC SfxPoolItem bool m_bIsVoidItem : 1; // bit 0 bool m_bStaticDefault : 1; // bit 1 bool m_bPoolDefault : 1; // bit 2 - bool m_bRegisteredAtPool : 1; // bit 3 - bool m_bIsSetItem : 1; // bit 5 + bool m_bIsSetItem : 1; // bit 3 protected: #ifdef DBG_UTIL // this flag will make debugging item stuff much simpler - bool m_bDeleted : 1; // bit 6 + bool m_bDeleted : 1; // bit 4 #endif private: @@ -153,7 +152,6 @@ protected: void setIsVoidItem() { m_bIsVoidItem = true; } void setStaticDefault() { m_bStaticDefault = true; } void setPoolDefault() { m_bPoolDefault = true; } - void setRegisteredAtPool(bool bNew) { m_bRegisteredAtPool = bNew; } void setIsSetItem() { m_bIsSetItem = true; } public: @@ -171,7 +169,6 @@ public: bool isVoidItem() const { return m_bIsVoidItem; } bool isStaticDefault() const { return m_bStaticDefault; } bool isPoolDefault() const { return m_bPoolDefault; } - bool isRegisteredAtPool() const { return m_bRegisteredAtPool; } bool isSetItem() const { return m_bIsSetItem; } // version that allows nullptrs diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx index 81086ed358ba..7d75defe957a 100644 --- a/sc/inc/fillinfo.hxx +++ b/sc/inc/fillinfo.hxx @@ -119,7 +119,7 @@ struct ScCellInfo , pConditionSet(nullptr) , pDataBar(nullptr) , pIconSet(nullptr) - , pBackground(nullptr) // TODO: omit? + , maBackground() , pLinesAttr(nullptr) , mpTLBRLine(nullptr) , mpBLTRLine(nullptr) @@ -156,7 +156,7 @@ struct ScCellInfo const ScDataBarInfo* pDataBar; const ScIconSetInfo* pIconSet; - const SvxBrushItem* pBackground; + SfxPoolItemHolder maBackground; const SvxBoxItem* pLinesAttr; /// original item from document. const SvxLineItem* mpTLBRLine; /// original item from document. diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx index a9f04943c0d1..c4c569557ffb 100644 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -546,7 +546,9 @@ void ScDocument::UpdateFontCharSet() return; ScDocumentPool* pPool = mxPoolHelper->GetDocPool(); - for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_FONT)) + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, ATTR_FONT); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFontItem = const_cast(dynamic_cast(pItem)); if ( pFontItem && ( pFontItem->GetCharSet() == eSrcSet || @@ -557,7 +559,8 @@ void ScDocument::UpdateFontCharSet() if ( mpDrawLayer ) { SfxItemPool& rDrawPool = mpDrawLayer->GetItemPool(); - for (const SfxPoolItem* pItem : rDrawPool.GetItemSurrogates(EE_CHAR_FONTINFO)) + rDrawPool.GetItemSurrogates(aSurrogates, EE_CHAR_FONTINFO); + for (const SfxPoolItem* pItem : aSurrogates) { SvxFontItem* pFontItem = const_cast(dynamic_cast(pItem)); if ( pFontItem && ( pFontItem->GetCharSet() == eSrcSet || diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 04e20ce4b8ac..c44672048b39 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -5175,7 +5175,9 @@ static HasAttrFlags OptimizeHasAttrib( HasAttrFlags nMask, const ScDocumentPool* // (as in fillinfo) bool bAnyItem = false; - for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_ROTATE_VALUE)) + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, ATTR_ROTATE_VALUE); + for (const SfxPoolItem* pItem : aSurrogates) { // 90 or 270 degrees is former SvxOrientationItem - only look for other values // (see ScPatternAttr::GetCellOrientation) diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index a1aeef5d7e7b..61c75b5e2cc5 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -191,7 +191,9 @@ std::set ScDocument::GetDocColors() const sal_uInt16 pAttribs[] = {ATTR_BACKGROUND, ATTR_FONT_COLOR}; for (sal_uInt16 nAttrib : pAttribs) { - for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib)) + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, nAttrib); + for (const SfxPoolItem* pItem : aSurrogates) { const SvxColorItem *pColorItem = static_cast(pItem); Color aColor( pColorItem->GetValue() ); diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index 544c58a65e46..8e84d045ff72 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -186,7 +186,9 @@ public: bool isRotateItemUsed(const ScDocumentPool *pPool) { - return pPool->GetItemSurrogates(ATTR_ROTATE_VALUE).size() > 0; + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, ATTR_ROTATE_VALUE); + return aSurrogates.size() > 0; } void initRowInfo(const ScDocument* pDoc, RowInfo* pRowInfo, const SCSIZE nMaxRow, @@ -543,7 +545,7 @@ void ScDocument::FillInfo( ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nCol); ScBasicCellInfo* pBasicInfo = &pThisRowInfo->basicCellInfo(nCol); - pInfo->pBackground = pBackground; + pInfo->maBackground = SfxPoolItemHolder(*pPool, pBackground); pInfo->pPatternAttr = pPattern; pInfo->bMerged = bMerged; pInfo->bHOverlapped = bHOverlapped; @@ -563,7 +565,7 @@ void ScDocument::FillInfo( if (bScenario) { - pInfo->pBackground = ScGlobal::GetButtonBrushItem(); + pInfo->maBackground = SfxPoolItemHolder(*pPool, ScGlobal::GetButtonBrushItem()); pThisRowInfo->bEmptyBack = false; } @@ -664,7 +666,7 @@ void ScDocument::FillInfo( // Background if ( const SvxBrushItem* pItem = pCondSet->GetItemIfSet( ATTR_BACKGROUND ) ) { - pInfo->pBackground = pItem; + pInfo->maBackground = SfxPoolItemHolder(*pPool, pItem); pRowInfo[nArrRow].bEmptyBack = false; } @@ -687,7 +689,8 @@ void ScDocument::FillInfo( if( bAnyCondition && pInfo->mxColorScale) { pRowInfo[nArrRow].bEmptyBack = false; - pInfo->pBackground = &pPool->DirectPutItemInPool(SvxBrushItem(*pInfo->mxColorScale, ATTR_BACKGROUND)); + const SvxBrushItem aBrushItem(*pInfo->mxColorScale, ATTR_BACKGROUND); + pInfo->maBackground = SfxPoolItemHolder(*pPool, &aBrushItem); } } } @@ -725,7 +728,7 @@ void ScDocument::FillInfo( if ( !pStartCond || !(pBrushItem = pStartCond->GetItemIfSet(ATTR_BACKGROUND)) ) pBrushItem = &pStartPattern->GetItem(ATTR_BACKGROUND); - pInfo->pBackground = pBrushItem; + pInfo->maBackground = SfxPoolItemHolder(*pPool, pBrushItem); pRowInfo[nArrRow].bEmptyBack = false; // Shadow diff --git a/sc/source/core/data/poolcach.cxx b/sc/source/core/data/poolcach.cxx index 3ab41d416c49..6db714bb7c12 100644 --- a/sc/source/core/data/poolcach.cxx +++ b/sc/source/core/data/poolcach.cxx @@ -26,7 +26,7 @@ ScItemPoolCache::ScItemPoolCache(CellAttributeHelper& _rHelper, const SfxPoolItem& rPutItem) : rHelper(_rHelper) , pSetToPut(nullptr) -, aItemToPut(_rHelper.GetPool(), &rPutItem) +, aItemToPut(rHelper.GetPool(), &rPutItem) { } diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 9da5da65b7e6..4ec6ab6cdbb6 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -5329,7 +5329,9 @@ XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExp void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib) { - for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib)) + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, nAttrib); + for (const SfxPoolItem* pItem : aSurrogates) { const SvXMLAttrContainerItem *pUnknown(static_cast(pItem)); if( pUnknown->GetAttrCount() > 0 ) diff --git a/sc/source/filter/xml/xmlfonte.cxx b/sc/source/filter/xml/xmlfonte.cxx index ab8e42f4ce60..f6951eddb0b8 100644 --- a/sc/source/filter/xml/xmlfonte.cxx +++ b/sc/source/filter/xml/xmlfonte.cxx @@ -59,7 +59,9 @@ void ScXMLFontAutoStylePool_Impl::AddFontItems(const sal_uInt16* pWhichIds, sal_ pFont->GetFamily(), pFont->GetPitch(), pFont->GetCharSet() ); } - for (const SfxPoolItem* pItem : pItemPool->GetItemSurrogates( nWhichId )) + ItemSurrogates aSurrogates; + pItemPool->GetItemSurrogates( aSurrogates, nWhichId ); + for (const SfxPoolItem* pItem : aSurrogates) { const SvxFontItem *pFont(static_cast(pItem)); Add( pFont->GetFamilyName(), pFont->GetStyleName(), @@ -111,7 +113,9 @@ ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScXMLExport& rExportP, for (sal_uInt16 nPageWhichId : aPageWhichIds) { - for (const SfxPoolItem* pItem : rPagePool.GetItemSurrogates( nPageWhichId )) + ItemSurrogates aSurrogates; + rPagePool.GetItemSurrogates( aSurrogates, nPageWhichId ); + for (const SfxPoolItem* pItem : aSurrogates) { const ScPageHFItem* pPageItem = static_cast(pItem); const EditTextObject* pLeftArea(pPageItem->GetLeftArea()); diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index 4907b6b50c05..03d93088a54d 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -2161,10 +2161,11 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) bool bManaged = false; // Get the pool item stored by Conditional Format Manager Dialog. - auto itemsRange = pTabViewShell->GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA); - if (itemsRange.begin() != itemsRange.end()) + ItemSurrogates aSurrogates; + pTabViewShell->GetPool().GetItemSurrogates(aSurrogates, SCITEM_CONDFORMATDLGDATA); + if (aSurrogates.begin() != aSurrogates.end()) { - const ScCondFormatDlgItem* pDlgItem = static_cast(*itemsRange.begin()); + const ScCondFormatDlgItem* pDlgItem = static_cast(*aSurrogates.begin()); nIndex = pDlgItem->GetIndex(); bManaged = true; } @@ -2873,10 +2874,11 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) ScConditionalFormatList* pList = nullptr; const ScCondFormatDlgItem* pDlgItem = nullptr; - auto itemsRange = pTabViewShell->GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA); - if (itemsRange.begin() != itemsRange.end()) + ItemSurrogates aSurrogates; + pTabViewShell->GetPool().GetItemSurrogates(aSurrogates, SCITEM_CONDFORMATDLGDATA); + if (aSurrogates.begin() != aSurrogates.end()) { - pDlgItem= static_cast(*itemsRange.begin()); + pDlgItem= static_cast(*aSurrogates.begin()); pList = const_cast(pDlgItem)->GetConditionalFormatList(); } diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index edad3a96f0b6..58b6db5107d3 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -823,7 +823,7 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther, else { for ( nX=nX1; nX<=nX2; nX++ ) - if ( !SfxPoolItem::areSame(rFirst.cellInfo(nX).pBackground, rOther.cellInfo(nX).pBackground ) ) + if ( !SfxPoolItem::areSame(rFirst.cellInfo(nX).maBackground.getItem(), rOther.cellInfo(nX).maBackground.getItem() ) ) return false; } @@ -1204,7 +1204,7 @@ void ScOutputData::DrawBackground(vcl::RenderContext& rRenderContext) pBackground = nullptr; } else - pBackground = pInfo->pBackground; + pBackground = static_cast(pInfo->maBackground.getItem()); if ( bPagebreakMode && !pInfo->bPrinted ) pBackground = pProtectedBackground.get(); @@ -1723,7 +1723,7 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext) aPoints[2] = Point(nBotRight, nBottom); aPoints[3] = Point(nBotLeft, nBottom); - const SvxBrushItem* pBackground = pInfo->pBackground; + const SvxBrushItem* pBackground(static_cast(pInfo->maBackground.getItem())); if (!pBackground) pBackground = &pPattern->GetItem(ATTR_BACKGROUND, pCondSet); if (bCellContrast) @@ -2494,7 +2494,7 @@ void ScOutputData::DrawNoteMarks(vcl::RenderContext& rRenderContext) { const bool bIsDarkBackground = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor.IsDark(); - const Color aColor = pInfo->pBackground->GetColor(); + const Color aColor(static_cast(pInfo->maBackground.getItem())->GetColor()); if ( aColor == COL_AUTO ? bIsDarkBackground : aColor.IsDark() ) rRenderContext.SetLineColor(COL_WHITE); else @@ -2794,7 +2794,9 @@ void ScOutputData::DrawClipMarks() tools::Long nMarkPixel = static_cast( SC_CLIPMARK_SIZE * mnPPTX ); Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 ); - const Color aColor = pInfo->pBackground ? pInfo->pBackground->GetColor() : COL_AUTO; + const Color aColor = pInfo->maBackground ? + static_cast(pInfo->maBackground.getItem())->GetColor() : + COL_AUTO; if ( aColor == COL_AUTO ? bIsDarkBackground : aColor.IsDark() ) mpDev->SetDrawMode( nOldDrawMode | DrawModeFlags::WhiteLine ); else diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx index eeb554454eab..1012f1ceb249 100644 --- a/sc/source/ui/view/tabvwshc.cxx +++ b/sc/source/ui/view/tabvwshc.cxx @@ -427,10 +427,11 @@ std::shared_ptr ScTabViewShell::CreateRefDialogCont { const ScCondFormatDlgItem* pDlgItem = nullptr; // Get the pool item stored by Conditional Format Manager Dialog. - auto itemsRange = GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA); - if (itemsRange.begin() != itemsRange.end()) + ItemSurrogates aSurrogates; + GetPool().GetItemSurrogates(aSurrogates, SCITEM_CONDFORMATDLGDATA); + if (aSurrogates.begin() != aSurrogates.end()) { - const SfxPoolItem* pItem = *itemsRange.begin(); + const SfxPoolItem* pItem = *aSurrogates.begin(); pDlgItem = static_cast(pItem); } diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 97d7338ece91..a6d28ecbc37b 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -1049,10 +1049,13 @@ void ScViewFunc::ApplyAttributes( const SfxItemSet& rDialogSet, const SvxBoxInfoItem& rOldInner = rOldSet.Get(ATTR_BORDER_INNER); const SvxBoxInfoItem& rNewInner = rDialogSet.Get(ATTR_BORDER_INNER); SfxItemSet& rNewSet = aNewAttrs.GetItemSet(); - SfxItemPool* pNewPool = rNewSet.GetPool(); - pNewPool->DirectPutItemInPool(rNewOuter); // don't delete yet - pNewPool->DirectPutItemInPool(rNewInner); + // protect referenced Items from disappearing (was: don't delete yet) + const SfxPoolItemHolder aHoldOuter(*rDialogSet.GetPool() , &rNewOuter); + const SfxPoolItemHolder aHoldInner(*rDialogSet.GetPool() , &rNewInner); + (void)aHoldOuter; + (void)aHoldInner; + rNewSet.ClearItem( ATTR_BORDER ); rNewSet.ClearItem( ATTR_BORDER_INNER ); @@ -1096,9 +1099,6 @@ void ScViewFunc::ApplyAttributes( const SfxItemSet& rDialogSet, bDefNewInner ? &rOldInner : &rNewInner ); } - pNewPool->DirectRemoveItemFromPool(rNewOuter); // release - pNewPool->DirectRemoveItemFromPool(rNewInner); - // adjust height only if needed if (bAdjustBlockHeight) AdjustBlockHeight(); diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx index de82a8b95306..328952c577c5 100644 --- a/sd/source/core/drawdoc2.cxx +++ b/sd/source/core/drawdoc2.cxx @@ -268,7 +268,9 @@ void SdDrawDocument::UpdatePageRelativeURLs(std::u16string_view aOldName, std::u return; SfxItemPool& rPool(GetPool()); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(EE_FEATURE_FIELD)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, EE_FEATURE_FIELD); + for (const SfxPoolItem* pItem : aSurrogates) { const SvxFieldItem* pFldItem = dynamic_cast< const SvxFieldItem * > (pItem); @@ -310,7 +312,9 @@ void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * pPage, sal_uInt16 nPo bool bNotes = (pPage->GetPageKind() == PageKind::Notes); SfxItemPool& rPool(GetPool()); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(EE_FEATURE_FIELD)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, EE_FEATURE_FIELD); + for (const SfxPoolItem* pItem : aSurrogates) { const SvxFieldItem* pFldItem; diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index 075ee6e383a7..89efc76df232 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -1391,13 +1391,14 @@ uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( const OUString& Property for(sal_uInt16 nWhichId : aWhichIds) { - const registeredSfxPoolItems& rSurrogates(rPool.GetItemSurrogates(nWhichId)); - const sal_uInt32 nItems(rSurrogates.size()); + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, nWhichId); + const sal_uInt32 nItems(aSurrogates.size()); aSeq.realloc( aSeq.getLength() + nItems*5 + 5 ); auto pSeq = aSeq.getArray(); - for (const SfxPoolItem* pItem : rSurrogates) + for (const SfxPoolItem* pItem : aSurrogates) { const SvxFontItem *pFont = static_cast(pItem); diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index a9690468cb89..5581b9486be0 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -10965,7 +10965,6 @@ svgio/source/svgreader/svgtspannode.cxx svgio/source/svgreader/svgusenode.cxx svgio/source/svguno/xsvgparser.cxx svl/qa/unit/items/test_IndexedStyleSheets.cxx -svl/qa/unit/items/test_itempool.cxx svl/qa/unit/svl.cxx svl/qa/unit/test_INetContentType.cxx svl/qa/unit/test_URIHelper.cxx @@ -10985,7 +10984,6 @@ svl/source/fsstor/oinputstreamcontainer.hxx svl/source/fsstor/ostreamcontainer.cxx svl/source/fsstor/ostreamcontainer.hxx svl/source/inc/fsfactory.hxx -svl/source/inc/poolio.hxx svl/source/items/IndexedStyleSheets.cxx svl/source/items/aeitem.cxx svl/source/items/cenumitm.cxx diff --git a/svl/CppunitTest_svl_itempool.mk b/svl/CppunitTest_svl_itempool.mk deleted file mode 100644 index 892107e906ca..000000000000 --- a/svl/CppunitTest_svl_itempool.mk +++ /dev/null @@ -1,34 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# - -$(eval $(call gb_CppunitTest_CppunitTest,svl_itempool)) - -$(eval $(call gb_CppunitTest_use_external,svl_itempool,boost_headers)) - -$(eval $(call gb_CppunitTest_use_sdk_api,svl_itempool)) - -$(eval $(call gb_CppunitTest_add_exception_objects,svl_itempool, \ - svl/qa/unit/items/test_itempool \ -)) - -$(eval $(call gb_CppunitTest_use_libraries,svl_itempool, \ - svl \ - comphelper \ - sal \ - salhelper \ - cppu \ - cppuhelper \ -)) - -$(eval $(call gb_CppunitTest_set_include,svl_itempool,\ - -I$(SRCDIR)/svl/source/inc \ - $$(INCLUDE) \ -)) - -# vim: set noet sw=4 ts=4: diff --git a/svl/Module_svl.mk b/svl/Module_svl.mk index 45bf74915c14..71fc8d08120f 100644 --- a/svl/Module_svl.mk +++ b/svl/Module_svl.mk @@ -32,7 +32,6 @@ $(eval $(call gb_Module_add_l10n_targets,svl,\ $(eval $(call gb_Module_add_check_targets,svl,\ CppunitTest_svl_adrparse \ CppunitTest_svl_inetcontenttype \ - CppunitTest_svl_itempool \ CppunitTest_svl_items \ CppunitTest_svl_lngmisc \ CppunitTest_svl_lockfiles \ diff --git a/svl/qa/unit/items/test_itempool.cxx b/svl/qa/unit/items/test_itempool.cxx deleted file mode 100644 index 2cb751d4fd77..000000000000 --- a/svl/qa/unit/items/test_itempool.cxx +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include -#include -#include - -#include -#include -#include -#include - -class PoolItemTest : public CppUnit::TestFixture -{ - public: - PoolItemTest() {} - - void testPool(); - - // Adds code needed to register the test suite - CPPUNIT_TEST_SUITE(PoolItemTest); - - CPPUNIT_TEST(testPool); - - // End of test suite definition - CPPUNIT_TEST_SUITE_END(); -}; - -void PoolItemTest::testPool() -{ - SfxItemInfo const aItems[] = - { - // _nSID, _bNeedsPoolRegistration, _bShareable - { 4, true, true }, - { 3, true, false /* test NeedsPoolRegistration */ }, - { 2, false, false }, - { 1, true, false /* test NeedsPoolRegistration */} - }; - - rtl::Reference pPool = new SfxItemPool("testpool", 1, 4, aItems); - - // Poolable - SfxVoidItem aItemOne( 1 ); - SfxVoidItem aNotherOne( 1 ); - - { - CPPUNIT_ASSERT(nullptr == pPool->ppRegisteredSfxPoolItems); - const SfxPoolItem &rVal = pPool->DirectPutItemInPool(aItemOne); - CPPUNIT_ASSERT(bool(rVal == aItemOne)); - CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems); - CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems[0]); - CPPUNIT_ASSERT(!pPool->ppRegisteredSfxPoolItems[0]->empty()); - const SfxPoolItem &rVal2 = pPool->DirectPutItemInPool(aNotherOne); - CPPUNIT_ASSERT(bool(rVal2 == rVal)); - - // ITEM: With leaving the paradigm that internally an already - // existing Item with true = operator==() (which is very - // expensive) the ptr's are no longer required to be equal, - // but the content-compare *is* - CPPUNIT_ASSERT(SfxPoolItem::areSame(rVal, rVal2)); - - // Clones on Put ... - // ptr compare OK, we want to check just the ptrs here - CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &aItemOne)); - CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &aNotherOne)); - CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal, &aItemOne)); - CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal, &aNotherOne)); - } - - // non-poolable - SfxVoidItem aItemTwo( 2 ); - SfxVoidItem aNotherTwo( 2 ); - { - CPPUNIT_ASSERT(nullptr == pPool->ppRegisteredSfxPoolItems[1]); - const SfxPoolItem &rVal = pPool->DirectPutItemInPool(aItemTwo); - CPPUNIT_ASSERT(bool(rVal == aItemTwo)); - CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems[1]); - CPPUNIT_ASSERT(!pPool->ppRegisteredSfxPoolItems[1]->empty()); - const SfxPoolItem &rVal2 = pPool->DirectPutItemInPool(aNotherTwo); - CPPUNIT_ASSERT(bool(rVal2 == rVal)); - // ptr compare OK, we want to check just the ptrs here - CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &rVal)); - } - - // Test removal. - SfxVoidItem aRemoveFour(4); - SfxVoidItem aNotherFour(4); - - const SfxPoolItem &rKeyFour = pPool->DirectPutItemInPool(aRemoveFour); - pPool->DirectPutItemInPool(aNotherFour); - CPPUNIT_ASSERT(pPool->ppRegisteredSfxPoolItems[3]->size() > 0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), pPool->ppRegisteredSfxPoolItems[3]->size()); - pPool->DirectRemoveItemFromPool(rKeyFour); - CPPUNIT_ASSERT_EQUAL(static_cast(1), pPool->ppRegisteredSfxPoolItems[3]->size()); - pPool->DirectPutItemInPool(aNotherFour); - CPPUNIT_ASSERT_EQUAL(static_cast(2), pPool->ppRegisteredSfxPoolItems[3]->size()); -} - - -CPPUNIT_TEST_SUITE_REGISTRATION(PoolItemTest); - -CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx deleted file mode 100644 index 118deaf50e2e..000000000000 --- a/svl/source/inc/poolio.hxx +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SVL_SOURCE_INC_POOLIO_HXX -#define INCLUDED_SVL_SOURCE_INC_POOLIO_HXX - -#include -#include -#include -#include -#include -#include -#include - -class SfxPoolItem; -class SfxItemPoolUser; - -struct SfxItemPool_Impl -{ - SfxBroadcaster aBC; - OUString aName; - std::vector maPoolDefaults; - std::vector* mpStaticDefaults; - SfxItemPool* mpMaster; - rtl::Reference mpSecondary; - WhichRangesContainer mpPoolRanges; - sal_uInt16 mnStart; - sal_uInt16 mnEnd; - MapUnit eDefMetric; - - SfxItemPool_Impl( SfxItemPool* pMaster, OUString _aName, sal_uInt16 nStart, sal_uInt16 nEnd ) - : aName(std::move(_aName)) - , maPoolDefaults(nEnd - nStart + 1) - , mpStaticDefaults(nullptr) - , mpMaster(pMaster) - , mnStart(nStart) - , mnEnd(nEnd) - , eDefMetric(MapUnit::MapCM) - { - DBG_ASSERT(mnStart, "Start-Which-Id must be greater 0" ); - } - - ~SfxItemPool_Impl() - { - DeleteItems(); - } - - void DeleteItems() - { - maPoolDefaults.clear(); - mpPoolRanges.reset(); - } -}; - -#endif // INCLUDED_SVL_SOURCE_INC_POOLIO_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx index e697a5e9a1f2..0fd59788a711 100644 --- a/svl/source/items/itempool.cxx +++ b/svl/source/items/itempool.cxx @@ -28,8 +28,7 @@ #include #include #include - -#include +#include #include #include @@ -236,7 +235,7 @@ lcl_CheckSlots2(std::map & rSlotMap, #define CHECK_SLOTS() \ do { \ std::map slotmap; \ - for (SfxItemPool * p = pImpl->mpMaster; p; p = p->pImpl->mpSecondary.get()) \ + for (SfxItemPool * p = mpMaster; p; p = p->mpSecondary.get()) \ { \ lcl_CheckSlots2(slotmap, *p, p->pItemInfos); \ } \ @@ -246,43 +245,107 @@ do { \ #define CHECK_SLOTS() do {} while (false) #endif +void SfxItemPool::registerItemSet(SfxItemSet& rSet) +{ + registeredSfxItemSets& rTarget(GetMasterPool()->maRegisteredSfxItemSets); +#ifdef DBG_UTIL + const size_t nBefore(rTarget.size()); +#endif + rTarget.insert(&rSet); +#ifdef DBG_UTIL + const size_t nAfter(rTarget.size()); + if (nBefore + 1 != nAfter) + { + SAL_WARN("svl.items", "SfxItemPool::registerItemSet: ItemSet was already registered (!)"); + } +#endif +} + +void SfxItemPool::unregisterItemSet(SfxItemSet& rSet) +{ + registeredSfxItemSets& rTarget(GetMasterPool()->maRegisteredSfxItemSets); +#ifdef DBG_UTIL + const size_t nBefore(rTarget.size()); +#endif + rTarget.erase(&rSet); +#ifdef DBG_UTIL + const size_t nAfter(rTarget.size()); + if (nBefore != nAfter + 1) + { + SAL_WARN("svl.items", "SfxItemPool::unregisterItemSet: ItemSet was not registered (!)"); + } +#endif +} + +void SfxItemPool::registerPoolItemHolder(SfxPoolItemHolder& rHolder) +{ + registeredSfxPoolItemHolders& rTarget(GetMasterPool()->maRegisteredSfxPoolItemHolders); +#ifdef DBG_UTIL + const size_t nBefore(rTarget.size()); +#endif + rTarget.insert(&rHolder); +#ifdef DBG_UTIL + const size_t nAfter(rTarget.size()); + if (nBefore + 1 != nAfter) + { + SAL_WARN("svl.items", "SfxItemPool::registerPoolItemHolder: SfxPoolItemHolder was already registered (!)"); + } +#endif +} + +void SfxItemPool::unregisterPoolItemHolder(SfxPoolItemHolder& rHolder) +{ + registeredSfxPoolItemHolders& rTarget(GetMasterPool()->maRegisteredSfxPoolItemHolders); +#ifdef DBG_UTIL + const size_t nBefore(rTarget.size()); +#endif + rTarget.erase(&rHolder); +#ifdef DBG_UTIL + const size_t nAfter(rTarget.size()); + if (nBefore != nAfter + 1) + { + SAL_WARN("svl.items", "SfxItemPool::unregisterPoolItemHolder: SfxPoolItemHolder was not registered (!)"); + } +#endif +} + sal_uInt16 SfxItemPool::GetFirstWhich() const { - return pImpl->mnStart; + return mnStart; } sal_uInt16 SfxItemPool::GetLastWhich() const { - return pImpl->mnEnd; + return mnEnd; } bool SfxItemPool::IsInRange( sal_uInt16 nWhich ) const { - return nWhich >= pImpl->mnStart && nWhich <= pImpl->mnEnd; + return nWhich >= mnStart && nWhich <= mnEnd; } sal_uInt16 SfxItemPool::GetIndex_Impl(sal_uInt16 nWhich) const { - if (nWhich < pImpl->mnStart || nWhich > pImpl->mnEnd) + if (nWhich < mnStart || nWhich > mnEnd) { assert(false && "missing bounds check before use"); return 0; } - return nWhich - pImpl->mnStart; + return nWhich - mnStart; } sal_uInt16 SfxItemPool::GetSize_Impl() const { - return pImpl->mnEnd - pImpl->mnStart + 1; + return mnEnd - mnStart + 1; } const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const { const SfxPoolItem* pRet; if( IsInRange( nWhich ) ) - pRet = pImpl->maPoolDefaults[GetIndex_Impl(nWhich)]; - else if( pImpl->mpSecondary ) - pRet = pImpl->mpSecondary->GetPoolDefaultItem( nWhich ); + pRet = maPoolDefaults[GetIndex_Impl(nWhich)]; + else if( mpSecondary ) + pRet = mpSecondary->GetPoolDefaultItem( nWhich ); else { assert(false && "unknown WhichId - cannot get pool default"); @@ -297,12 +360,12 @@ bool SfxItemPool::NeedsPoolRegistration(sal_uInt16 nWhich) const if (!IsInRange(nWhich)) { // get to correct pool - if (pImpl->mpSecondary) - return pImpl->mpSecondary->NeedsPoolRegistration(nWhich); + if (mpSecondary) + return mpSecondary->NeedsPoolRegistration(nWhich); return false; } - return NeedsPoolRegistration_Impl(nWhich - pImpl->mnStart); + return NeedsPoolRegistration_Impl(nWhich - mnStart); } bool SfxItemPool::Shareable(sal_uInt16 nWhich) const @@ -310,18 +373,18 @@ bool SfxItemPool::Shareable(sal_uInt16 nWhich) const if (!IsInRange(nWhich)) { // get to correct pool - if (pImpl->mpSecondary) - return pImpl->mpSecondary->Shareable(nWhich); + if (mpSecondary) + return mpSecondary->Shareable(nWhich); return false; } - return Shareable_Impl(nWhich - pImpl->mnStart); + return Shareable_Impl(nWhich - mnStart); } SfxBroadcaster& SfxItemPool::BC() { - return pImpl->aBC; + return aBC; } @@ -357,12 +420,22 @@ SfxItemPool::SfxItemPool pDefaults /* Pointer to static Defaults; is directly referenced by the Pool, but no transfer of ownership */ -) : - pItemInfos(pInfo), - pImpl( new SfxItemPool_Impl( this, rName, nStartWhich, nEndWhich ) ), - ppRegisteredSfxPoolItems(nullptr) +) +: salhelper::SimpleReferenceObject() +,pItemInfos(pInfo) +, aName(rName) +, maPoolDefaults(nEndWhich - nStartWhich + 1) +, mpStaticDefaults(nullptr) +, mpMaster(this) +, mnStart(nStartWhich) +, mnEnd(nEndWhich) +, eDefMetric(MapUnit::MapCM) +, maRegisteredSfxItemSets() +, maRegisteredSfxPoolItemHolders() +, maDirectPutItems() +, mbPreDeleteDone(false) { - pImpl->eDefMetric = MapUnit::MapTwip; + eDefMetric = MapUnit::MapTwip; if ( pDefaults ) SetDefaults(pDefaults); @@ -400,68 +473,75 @@ SfxItemPool::SfxItemPool false Take over static Defaults */ -) : - salhelper::SimpleReferenceObject(), - pItemInfos(rPool.pItemInfos), - pImpl( new SfxItemPool_Impl( this, rPool.pImpl->aName, rPool.pImpl->mnStart, rPool.pImpl->mnEnd ) ), - ppRegisteredSfxPoolItems(nullptr) +) +: salhelper::SimpleReferenceObject() +, pItemInfos(rPool.pItemInfos) +, aName(rPool.aName) +, maPoolDefaults(rPool.mnEnd - rPool.mnStart + 1) +, mpStaticDefaults(nullptr) +, mpMaster(this) +, mnStart(rPool.mnStart) +, mnEnd(rPool.mnEnd) +, eDefMetric(MapUnit::MapCM) +, maRegisteredSfxItemSets() +, maRegisteredSfxPoolItemHolders() +, maDirectPutItems() +, mbPreDeleteDone(false) { - pImpl->eDefMetric = rPool.pImpl->eDefMetric; + eDefMetric = rPool.eDefMetric; // Take over static Defaults if ( bCloneStaticDefaults ) { - std::vector* ppDefaults = new std::vector(pImpl->mnEnd-pImpl->mnStart+1); - for ( sal_uInt16 n = 0; n <= pImpl->mnEnd - pImpl->mnStart; ++n ) + std::vector* ppDefaults = new std::vector(mnEnd-mnStart+1); + for ( sal_uInt16 n = 0; n <= mnEnd - mnStart; ++n ) { - (*ppDefaults)[n] = (*rPool.pImpl->mpStaticDefaults)[n]->Clone(this); + (*ppDefaults)[n] = (*rPool.mpStaticDefaults)[n]->Clone(this); (*ppDefaults)[n]->setStaticDefault(); } SetDefaults( ppDefaults ); } else - SetDefaults( rPool.pImpl->mpStaticDefaults ); + SetDefaults( rPool.mpStaticDefaults ); // Copy Pool Defaults - for (size_t n = 0; n < pImpl->maPoolDefaults.size(); ++n ) - if (rPool.pImpl->maPoolDefaults[n]) + for (size_t n = 0; n < maPoolDefaults.size(); ++n ) + if (rPool.maPoolDefaults[n]) { - pImpl->maPoolDefaults[n] = rPool.pImpl->maPoolDefaults[n]->Clone(this); //resets kind - pImpl->maPoolDefaults[n]->setPoolDefault(); + maPoolDefaults[n] = rPool.maPoolDefaults[n]->Clone(this); //resets kind + maPoolDefaults[n]->setPoolDefault(); } // Repair linkage - if ( rPool.pImpl->mpSecondary ) - SetSecondaryPool( rPool.pImpl->mpSecondary->Clone().get() ); + if ( rPool.mpSecondary ) + SetSecondaryPool( rPool.mpSecondary->Clone().get() ); } void SfxItemPool::SetDefaults( std::vector* pDefaults ) { DBG_ASSERT( pDefaults, "first we ask for it, and then we don't give back..." ); - DBG_ASSERT( !pImpl->mpStaticDefaults, "already have Defaults" ); + DBG_ASSERT( !mpStaticDefaults, "already have Defaults" ); - pImpl->mpStaticDefaults = pDefaults; + mpStaticDefaults = pDefaults; //! if ((*mpStaticDefaults)->GetKind() != SfxItemKind::StaticDefault) //! FIXME: Probably doesn't work with SetItems at the end { - DBG_ASSERT( (*pImpl->mpStaticDefaults)[0]->GetRefCount() == 0 || - IsDefaultItem( (*pImpl->mpStaticDefaults)[0] ), + DBG_ASSERT( (*mpStaticDefaults)[0]->GetRefCount() == 0 || + IsDefaultItem( (*mpStaticDefaults)[0] ), "these are not static" ); - for ( sal_uInt16 n = 0; n <= pImpl->mnEnd - pImpl->mnStart; ++n ) + for ( sal_uInt16 n = 0; n <= mnEnd - mnStart; ++n ) { - assert( ((*pImpl->mpStaticDefaults)[n]->Which() == n + pImpl->mnStart) + assert( ((*mpStaticDefaults)[n]->Which() == n + mnStart) && "items ids in pool-ranges and in static-defaults do not match" ); - (*pImpl->mpStaticDefaults)[n]->setStaticDefault(); - DBG_ASSERT(nullptr == ppRegisteredSfxPoolItems || nullptr == ppRegisteredSfxPoolItems[n] - || ppRegisteredSfxPoolItems[n]->empty(), "defaults with setitems with items?!" ); + (*mpStaticDefaults)[n]->setStaticDefault(); } } } void SfxItemPool::ClearDefaults() { - pImpl->mpStaticDefaults = nullptr; + mpStaticDefaults = nullptr; } /** @@ -482,12 +562,12 @@ void SfxItemPool::ReleaseDefaults { - DBG_ASSERT( pImpl->mpStaticDefaults, "requirements not met" ); - ReleaseDefaults( pImpl->mpStaticDefaults, bDelete ); + DBG_ASSERT( mpStaticDefaults, "requirements not met" ); + ReleaseDefaults( mpStaticDefaults, bDelete ); // mpStaticDefaults points to deleted memory if bDelete == true. if ( bDelete ) - pImpl->mpStaticDefaults = nullptr; + mpStaticDefaults = nullptr; } @@ -536,73 +616,39 @@ void SfxItemPool::ReleaseDefaults SfxItemPool::~SfxItemPool() { // Need to be deleted? - // Caution: ppRegisteredSfxPoolItems is on-demand created and can be nullptr - if ( nullptr != ppRegisteredSfxPoolItems || !pImpl->maPoolDefaults.empty() ) + if (!mbPreDeleteDone)//maPoolDefaults.empty()) Delete(); - if (pImpl->mpMaster != nullptr && pImpl->mpMaster != this) + if (mpMaster != nullptr && mpMaster != this) { // This condition indicates an error. - // A pImpl->mpMaster->SetSecondaryPool(...) call should have been made + // A mpMaster->SetSecondaryPool(...) call should have been made // earlier to prevent this. At this point we can only try to // prevent a crash later on. - DBG_ASSERT( pImpl->mpMaster == this, "destroying active Secondary-Pool" ); - if (pImpl->mpMaster->pImpl->mpSecondary == this) - pImpl->mpMaster->pImpl->mpSecondary = nullptr; + DBG_ASSERT( mpMaster == this, "destroying active Secondary-Pool" ); + if (mpMaster->mpSecondary == this) + mpMaster->mpSecondary = nullptr; } } void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool ) { // Reset Master in attached Pools - if ( pImpl->mpSecondary ) + if ( mpSecondary ) { -#ifdef DBG_UTIL - if (nullptr != pImpl->mpStaticDefaults - && nullptr != ppRegisteredSfxPoolItems - && nullptr != pImpl->mpSecondary->ppRegisteredSfxPoolItems) - // Delete() did not yet run? - { - // Does the Master have SetItems? - bool bHasSetItems(false); - - for (sal_uInt16 i(0); !bHasSetItems && i < pImpl->mnEnd - pImpl->mnStart; ++i) - { - const SfxPoolItem* pStaticDefaultItem((*pImpl->mpStaticDefaults)[i]); - bHasSetItems = pStaticDefaultItem->isSetItem(); - } - - if (bHasSetItems) - { - // Detached Pools must be empty - registeredSfxPoolItems** ppSet(pImpl->mpSecondary->ppRegisteredSfxPoolItems); - - for (sal_uInt16 a(0); a < pImpl->mpSecondary->GetSize_Impl(); a++, ppSet++) - { - if (nullptr != *ppSet && !(*ppSet)->empty()) - { - SAL_WARN("svl.items", "old secondary pool: " << pImpl->mpSecondary->pImpl->aName - << " of pool: " << pImpl->aName << " must be empty."); - break; - } - } - } - } -#endif - - pImpl->mpSecondary->pImpl->mpMaster = pImpl->mpSecondary.get(); - for ( SfxItemPool *p = pImpl->mpSecondary->pImpl->mpSecondary.get(); p; p = p->pImpl->mpSecondary.get() ) - p->pImpl->mpMaster = pImpl->mpSecondary.get(); + mpSecondary->mpMaster = mpSecondary.get(); + for ( SfxItemPool *p = mpSecondary->mpSecondary.get(); p; p = p->mpSecondary.get() ) + p->mpMaster = mpSecondary.get(); } // Set Master of new Secondary Pools - DBG_ASSERT( !pPool || pPool->pImpl->mpMaster == pPool, "Secondary is present in two Pools" ); - SfxItemPool *pNewMaster = GetMasterPool() ? pImpl->mpMaster : this; - for ( SfxItemPool *p = pPool; p; p = p->pImpl->mpSecondary.get() ) - p->pImpl->mpMaster = pNewMaster; + DBG_ASSERT( !pPool || pPool->mpMaster == pPool, "Secondary is present in two Pools" ); + SfxItemPool *pNewMaster = GetMasterPool() ? mpMaster : this; + for ( SfxItemPool *p = pPool; p; p = p->mpSecondary.get() ) + p->mpMaster = pNewMaster; // Remember new Secondary Pool - pImpl->mpSecondary = pPool; + mpSecondary = pPool; CHECK_SLOTS(); } @@ -616,24 +662,24 @@ void SfxItemPool::SetItemInfos(SfxItemInfo const*const pInfo) MapUnit SfxItemPool::GetMetric( sal_uInt16 ) const { - return pImpl->eDefMetric; + return eDefMetric; } void SfxItemPool::SetDefaultMetric( MapUnit eNewMetric ) { // assert((pImpl->eDefMetric == eNewMetric || !pImpl->mpPoolRanges) && "pool already frozen, cannot change metric"); - pImpl->eDefMetric = eNewMetric; + eDefMetric = eNewMetric; } MapUnit SfxItemPool::GetDefaultMetric() const { - return pImpl->eDefMetric; + return eDefMetric; } const OUString& SfxItemPool::GetName() const { - return pImpl->aName; + return aName; } @@ -659,74 +705,20 @@ rtl::Reference SfxItemPool::Clone() const void SfxItemPool::Delete() { // Already deleted? - // Caution: ppRegisteredSfxPoolItems is on-demand created and can be nullptr - if (nullptr == ppRegisteredSfxPoolItems && pImpl->maPoolDefaults.empty()) + if (mbPreDeleteDone)//maPoolDefaults.empty()) return; + mbPreDeleteDone = true; // Inform e.g. running Requests - pImpl->aBC.Broadcast( SfxHint( SfxHintId::Dying ) ); + aBC.Broadcast( SfxHint( SfxHintId::Dying ) ); - // Iterate through twice: first for the SetItems. - if (nullptr != pImpl->mpStaticDefaults && nullptr != ppRegisteredSfxPoolItems) - { - for (size_t n = 0; n < GetSize_Impl(); ++n) - { - // *mpStaticDefaultItem could've already been deleted in a class derived - // from SfxItemPool - // This causes chaos in Itempool! - const SfxPoolItem* pStaticDefaultItem((*pImpl->mpStaticDefaults)[n]); - if (pStaticDefaultItem->isSetItem() && nullptr != ppRegisteredSfxPoolItems[n]) - { - // SfxSetItem found, remove PoolItems (and defaults) with same ID - auto& rArray(*(ppRegisteredSfxPoolItems[n])); - for (auto& rItemPtr : rArray) - { - ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor - delete rItemPtr; - } - rArray.clear(); - // let pImpl->DeleteItems() delete item arrays in maPoolItems - auto& rItemPtr = pImpl->maPoolDefaults[n]; - if (rItemPtr) - { -#ifdef DBG_UTIL - ClearRefCount(*rItemPtr); -#endif - delete rItemPtr; - rItemPtr = nullptr; - } - } - } - } - - if (nullptr != ppRegisteredSfxPoolItems) - { - registeredSfxPoolItems** ppSet(ppRegisteredSfxPoolItems); - - for (sal_uInt16 a(0); a < GetSize_Impl(); a++, ppSet++) - { - if (nullptr != *ppSet) - { - for (auto& rCandidate : **ppSet) - { - if (nullptr != rCandidate && !IsDefaultItem(rCandidate)) - { - ReleaseRef(*rCandidate, rCandidate->GetRefCount()); // for RefCount check in dtor - delete rCandidate; - } - } - - delete *ppSet; - *ppSet = nullptr; - } - } - - delete[] ppRegisteredSfxPoolItems; - ppRegisteredSfxPoolItems = nullptr; - } + // delete direct put items, may assert here when not empty + for (const auto& rCand : maDirectPutItems) + delete rCand; + maDirectPutItems.clear(); // default items - for (auto rItemPtr : pImpl->maPoolDefaults) + for (auto rItemPtr : maPoolDefaults) { if (rItemPtr) { @@ -738,7 +730,8 @@ void SfxItemPool::Delete() } } - pImpl->DeleteItems(); + maPoolDefaults.clear(); + mpPoolRanges.reset(); } @@ -747,7 +740,7 @@ void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem) if ( IsInRange(rItem.Which()) ) { auto& rOldDefault = - pImpl->maPoolDefaults[GetIndex_Impl(rItem.Which())]; + maPoolDefaults[GetIndex_Impl(rItem.Which())]; SfxPoolItem *pNewDefault = rItem.Clone(this); pNewDefault->setPoolDefault(); if (rOldDefault) @@ -758,8 +751,8 @@ void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem) } rOldDefault = pNewDefault; } - else if ( pImpl->mpSecondary ) - pImpl->mpSecondary->SetPoolDefaultItem(rItem); + else if ( mpSecondary ) + mpSecondary->SetPoolDefaultItem(rItem); else { assert(false && "unknown WhichId - cannot set pool default"); @@ -775,7 +768,7 @@ void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId ) if ( IsInRange(nWhichId) ) { auto& rOldDefault = - pImpl->maPoolDefaults[GetIndex_Impl(nWhichId)]; + maPoolDefaults[GetIndex_Impl(nWhichId)]; if (rOldDefault) { rOldDefault->SetRefCount(0); @@ -783,30 +776,24 @@ void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId ) rOldDefault = nullptr; } } - else if ( pImpl->mpSecondary ) - pImpl->mpSecondary->ResetPoolDefaultItem(nWhichId); + else if ( mpSecondary ) + mpSecondary->ResetPoolDefaultItem(nWhichId); else { assert(false && "unknown WhichId - cannot reset pool default"); } } -const SfxPoolItem& SfxItemPool::DirectPutItemInPoolImpl(const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership) +const SfxPoolItem& SfxItemPool::DirectPutItemInPool(const SfxPoolItem& rItem) { #ifdef DBG_UTIL nAllDirectlyPooledSfxPoolItemCount++; nRemainingDirectlyPooledSfxPoolItemCount++; #endif - - // make sure to use 'master'-pool, that's the one used by SfxItemSets - const SfxPoolItem* pRetval(implCreateItemEntry(*GetMasterPool(), &rItem, nWhich, bPassingOwnership)); - - // For the moment, as long as DirectPutItemInPoolImpl is used, make sure that - // the changes in implCreateItemEntry do not change anything, that would - // risc memory leaks by not (ab)using the garbage collector aspect of the pool. - registerSfxPoolItem(*pRetval); - - return *pRetval; + // use SfxPoolItemHolder now to secure lifetime + SfxPoolItemHolder* pHolder(new SfxPoolItemHolder(*GetMasterPool(), &rItem)); + GetMasterPool()->maDirectPutItems.insert(pHolder); + return *pHolder->getItem(); } void SfxItemPool::DirectRemoveItemFromPool(const SfxPoolItem& rItem) @@ -814,31 +801,36 @@ void SfxItemPool::DirectRemoveItemFromPool(const SfxPoolItem& rItem) #ifdef DBG_UTIL nRemainingDirectlyPooledSfxPoolItemCount--; #endif - - // make sure to use 'master'-pool, that's the one used by SfxItemSets - implCleanupItemEntry(*GetMasterPool(), &rItem); + directPutSfxPoolItemHolders& rDirects(GetMasterPool()->maDirectPutItems); + for (directPutSfxPoolItemHolders::iterator aIter(rDirects.begin()); aIter != rDirects.end(); aIter++) + if ((*aIter)->getItem() == &rItem) + { + delete *aIter; + rDirects.erase(aIter); + break; + } } const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const { if ( !IsInRange(nWhich) ) { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->GetDefaultItem( nWhich ); + if ( mpSecondary ) + return mpSecondary->GetDefaultItem( nWhich ); assert(!"unknown which - don't ask me for defaults"); } - DBG_ASSERT( pImpl->mpStaticDefaults, "no defaults known - don't ask me for defaults" ); + DBG_ASSERT( mpStaticDefaults, "no defaults known - don't ask me for defaults" ); sal_uInt16 nPos = GetIndex_Impl(nWhich); - SfxPoolItem* pDefault = pImpl->maPoolDefaults[nPos]; + SfxPoolItem* pDefault = maPoolDefaults[nPos]; if ( pDefault ) return *pDefault; - return *(*pImpl->mpStaticDefaults)[nPos]; + return *(*mpStaticDefaults)[nPos]; } SfxItemPool* SfxItemPool::GetSecondaryPool() const { - return pImpl->mpSecondary.get(); + return mpSecondary.get(); } /* get the last pool by following the GetSecondaryPool chain */ @@ -852,7 +844,7 @@ SfxItemPool* SfxItemPool::GetLastPoolInChain() SfxItemPool* SfxItemPool::GetMasterPool() const { - return pImpl->mpMaster; + return mpMaster; } /** @@ -864,125 +856,95 @@ SfxItemPool* SfxItemPool::GetMasterPool() const */ void SfxItemPool::FreezeIdRanges() { - assert(pImpl->mpPoolRanges.empty() && "pool already frozen, cannot freeze twice"); - FillItemIdRanges_Impl( pImpl->mpPoolRanges ); + assert(mpPoolRanges.empty() && "pool already frozen, cannot freeze twice"); + FillItemIdRanges_Impl( mpPoolRanges ); } void SfxItemPool::FillItemIdRanges_Impl( WhichRangesContainer& pWhichRanges ) const { - DBG_ASSERT( pImpl->mpPoolRanges.empty(), "GetFrozenRanges() would be faster!" ); + DBG_ASSERT( mpPoolRanges.empty(), "GetFrozenRanges() would be faster!" ); pWhichRanges.reset(); // Merge all ranges, keeping them sorted - for (const SfxItemPool* pPool = this; pPool; pPool = pPool->pImpl->mpSecondary.get()) - pWhichRanges = pWhichRanges.MergeRange(pPool->pImpl->mnStart, pPool->pImpl->mnEnd); + for (const SfxItemPool* pPool = this; pPool; pPool = pPool->mpSecondary.get()) + pWhichRanges = pWhichRanges.MergeRange(pPool->mnStart, pPool->mnEnd); } const WhichRangesContainer& SfxItemPool::GetFrozenIdRanges() const { - return pImpl->mpPoolRanges; + return mpPoolRanges; } const SfxPoolItem *SfxItemPool::GetItem2Default(sal_uInt16 nWhich) const { if ( !IsInRange(nWhich) ) { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->GetItem2Default( nWhich ); + if ( mpSecondary ) + return mpSecondary->GetItem2Default( nWhich ); assert(false && "unknown WhichId - cannot resolve surrogate"); return nullptr; } - return (*pImpl->mpStaticDefaults)[ GetIndex_Impl(nWhich) ]; + return (*mpStaticDefaults)[ GetIndex_Impl(nWhich) ]; } -#ifdef DBG_UTIL -static void warnForMissingPoolRegistration(const SfxItemPool& rPool, sal_uInt16 nWhich) +void SfxItemPool::CollectSurrogates(std::unordered_set& rTarget, sal_uInt16 nWhich) const { - if (!rPool.NeedsPoolRegistration(nWhich)) - SAL_INFO("svl.items", "ITEM: ItemSurrogate requested for WhichID " << nWhich << - " class " << typeid(rPool.GetDefaultItem(nWhich)).name() << - ": needs _bNeedsPoolRegistration==true in SfxItemInfo for that slot"); -} -#endif + rTarget.clear(); -const registeredSfxPoolItems& SfxItemPool::GetItemSurrogates(sal_uInt16 nWhich) const -{ - static const registeredSfxPoolItems EMPTY; + if (0 == nWhich) + return; - if (!IsInRange(nWhich)) - { - if (pImpl->mpSecondary) - return pImpl->mpSecondary->GetItemSurrogates(nWhich); - return EMPTY; - } + // 1st source for surrogates + const registeredSfxItemSets& rSets(GetMasterPool()->maRegisteredSfxItemSets); + const SfxPoolItem* pItem(nullptr); + for (const auto& rCand : rSets) + if (SfxItemState::SET == rCand->GetItemState(nWhich, false, &pItem)) + rTarget.insert(pItem); - if (nullptr == ppRegisteredSfxPoolItems) - { + // 2nd source for surrogates + const registeredSfxPoolItemHolders& rHolders(GetMasterPool()->maRegisteredSfxPoolItemHolders); + for (const auto& rCand : rHolders) + if (rCand->Which() == nWhich && nullptr != rCand->getItem()) + rTarget.insert(rCand->getItem()); + + // the 3rd source for surrogates is the list of direct put items + // but since these use SfxPoolItemHolder now they are automatically + // registered at 2nd source - IF NeedsPoolRegistration is set. So + // as long as we have this DirectPutItem stuff, iterate here and + // warn if an Item was added + const directPutSfxPoolItemHolders& rDirects(GetMasterPool()->maDirectPutItems); #ifdef DBG_UTIL - warnForMissingPoolRegistration(*this, nWhich); + const size_t aBefore(rTarget.size()); #endif - return EMPTY; - } - - registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nWhich - pImpl->mnStart]); - - if (nullptr == pSet) - { + for (const auto& rCand : rDirects) + if (rCand->Which() == nWhich && nullptr != rCand->getItem()) + rTarget.insert(rCand->getItem()); #ifdef DBG_UTIL - warnForMissingPoolRegistration(*this, nWhich); -#endif - return EMPTY; + const size_t aAfter(rTarget.size()); + if (aBefore != aAfter) + { + SAL_WARN("svl.items", "SfxItemPool: Found non-automatically registered Item for Surrogates in DirectPutItems (!)"); } - - return *pSet; +#endif } -std::vector SfxItemPool::FindItemSurrogate(sal_uInt16 nWhich, SfxPoolItem const & rSample) const +void SfxItemPool::GetItemSurrogates(ItemSurrogates& rTarget, sal_uInt16 nWhich) const { - static const std::vector EMPTY; + std::unordered_set aNewSurrogates; + CollectSurrogates(aNewSurrogates, nWhich); + rTarget = ItemSurrogates(aNewSurrogates.begin(), aNewSurrogates.end()); +} - if (nullptr == ppRegisteredSfxPoolItems) - return EMPTY; - - if ( !IsInRange(nWhich) ) - { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->FindItemSurrogate( nWhich, rSample ); - assert(false && "unknown WhichId - cannot resolve surrogate"); - return EMPTY; - } - - // get index (must exist due to checks above) - const sal_uInt16 nIndex(rSample.Which() - pImpl->mnStart); - - if (nullptr == ppRegisteredSfxPoolItems) - { -#ifdef DBG_UTIL - warnForMissingPoolRegistration(*this, nWhich); -#endif - return EMPTY; - } - - // get registeredSfxPoolItems container - registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); - - if (nullptr == pSet) - { -#ifdef DBG_UTIL - warnForMissingPoolRegistration(*this, nWhich); -#endif - return EMPTY; - } - - std::vector rv; - - for (const SfxPoolItem* p : *pSet) - if (rSample == *p) - rv.push_back(p); - - return rv; +void SfxItemPool::FindItemSurrogate(ItemSurrogates& rTarget, sal_uInt16 nWhich, SfxPoolItem const & rSample) const +{ + std::unordered_set aNewSurrogates; + CollectSurrogates(aNewSurrogates, nWhich); + rTarget.clear(); + for (const auto& rCand : aNewSurrogates) + if (rSample == *rCand) + rTarget.push_back(rCand); } sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, bool bDeep ) const @@ -990,12 +952,12 @@ sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, bool bDeep ) const if ( !IsSlot(nSlotId) ) return nSlotId; - sal_uInt16 nCount = pImpl->mnEnd - pImpl->mnStart + 1; + sal_uInt16 nCount = mnEnd - mnStart + 1; for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs ) if ( pItemInfos[nOfs]._nSID == nSlotId ) - return nOfs + pImpl->mnStart; - if ( pImpl->mpSecondary && bDeep ) - return pImpl->mpSecondary->GetWhich(nSlotId); + return nOfs + mnStart; + if ( mpSecondary && bDeep ) + return mpSecondary->GetWhich(nSlotId); return nSlotId; } @@ -1007,13 +969,13 @@ sal_uInt16 SfxItemPool::GetSlotId( sal_uInt16 nWhich ) const if ( !IsInRange( nWhich ) ) { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->GetSlotId(nWhich); + if ( mpSecondary ) + return mpSecondary->GetSlotId(nWhich); assert(false && "unknown WhichId - cannot get slot-id"); return 0; } - sal_uInt16 nSID = pItemInfos[nWhich - pImpl->mnStart]._nSID; + sal_uInt16 nSID = pItemInfos[nWhich - mnStart]._nSID; return nSID ? nSID : nWhich; } @@ -1023,12 +985,12 @@ sal_uInt16 SfxItemPool::GetTrueWhich( sal_uInt16 nSlotId, bool bDeep ) const if ( !IsSlot(nSlotId) ) return 0; - sal_uInt16 nCount = pImpl->mnEnd - pImpl->mnStart + 1; + sal_uInt16 nCount = mnEnd - mnStart + 1; for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs ) if ( pItemInfos[nOfs]._nSID == nSlotId ) - return nOfs + pImpl->mnStart; - if ( pImpl->mpSecondary && bDeep ) - return pImpl->mpSecondary->GetTrueWhich(nSlotId); + return nOfs + mnStart; + if ( mpSecondary && bDeep ) + return mpSecondary->GetTrueWhich(nSlotId); return 0; } @@ -1040,192 +1002,12 @@ sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich ) const if ( !IsInRange( nWhich ) ) { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->GetTrueSlotId(nWhich); + if ( mpSecondary ) + return mpSecondary->GetTrueSlotId(nWhich); assert(false && "unknown WhichId - cannot get slot-id"); return 0; } - return pItemInfos[nWhich - pImpl->mnStart]._nSID; -} - -void SfxItemPool::registerSfxPoolItem(const SfxPoolItem& rItem) -{ - assert(rItem.Which() != 0); - - if (IsSlot(rItem.Which())) - // do not register SlotItems - return; - - if (rItem.isRegisteredAtPool()) - // already registered, done - return; - - if (!IsInRange(rItem.Which())) - { - // get to the right pool - if (pImpl->mpSecondary) - { - pImpl->mpSecondary->registerSfxPoolItem(rItem); - return; - } - - return; - } - - if (nullptr == ppRegisteredSfxPoolItems) - // on-demand allocate array of registeredSfxPoolItems and init to nullptr - ppRegisteredSfxPoolItems = new registeredSfxPoolItems*[GetSize_Impl()]{}; - - // get correct registeredSfxPoolItems - const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart); - registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); - - if (nullptr == pSet) - // on-demand allocate - ppRegisteredSfxPoolItems[nIndex] = pSet = new registeredSfxPoolItems; - - // insert to registeredSfxPoolItems and set flag at Item - pSet->insert(&rItem); - const_cast(rItem).setRegisteredAtPool(true); -} - -void SfxItemPool::unregisterSfxPoolItem(const SfxPoolItem& rItem) -{ - if (!rItem.isRegisteredAtPool()) - // Item is not registered, done - return; - - if (!IsInRange(rItem.Which())) - { - // get to the right pool - if (pImpl->mpSecondary) - { - pImpl->mpSecondary->unregisterSfxPoolItem(rItem); - return; - } - - assert(false && "unknown WhichId - cannot execute unregisterSfxPoolItem"); - return; - } - - // we need a valid WhichID and the array of containers has to exist - assert(rItem.Which() != 0); - assert(nullptr != ppRegisteredSfxPoolItems); - - // get index (must exist due to checks above) - const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart); - - // a valid registeredSfxPoolItems container has to exist - registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); - assert(nullptr != pSet); - - // remove registered Item and reset flag at Item - pSet->erase(&rItem); - const_cast(rItem).setRegisteredAtPool(false); -} - -bool SfxItemPool::isSfxPoolItemRegisteredAtThisPool(const SfxPoolItem& rItem) const -{ - if (!rItem.isRegisteredAtPool()) - // Item is not registered at all, so also not at this Pool - return false; - - if (IsSlot(rItem.Which())) - // do not check being registered for SlotItems - return false; - - if (!IsInRange(rItem.Which())) - { - // get to the right pool - if (pImpl->mpSecondary) - return pImpl->mpSecondary->isSfxPoolItemRegisteredAtThisPool(rItem); - return false; - } - - // we need a valid WhichID - assert(rItem.Which() != 0); - - if (nullptr == ppRegisteredSfxPoolItems) - // when no array of containers exists the Item is not registered - return false; - - // get index (must exist due to checks above) - const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart); - - // get registeredSfxPoolItems container - registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); - - if (nullptr == pSet) - // when no registeredSfxPoolItems container exists the Item is not registered - return false; - - // test if Item is registered - return pSet->find(&rItem) != pSet->end(); -} - -const SfxPoolItem* SfxItemPool::tryToGetEqualItem(const SfxPoolItem& rItem, sal_uInt16 nWhich) const -{ - if (IsSlot(nWhich)) - // SlotItems are not registered @pool and not in any range - return nullptr; - - if (!IsInRange(nWhich)) - { - // get to the right pool - if (pImpl->mpSecondary) - return pImpl->mpSecondary->tryToGetEqualItem(rItem, nWhich); - return nullptr; - } - - if (nullptr == ppRegisteredSfxPoolItems) - // no Items at all - return nullptr; - - // get index (must exist due to checks above) - const sal_uInt16 nIndex(nWhich - pImpl->mnStart); - - if (!Shareable_Impl(nIndex)) - // not shareable - return nullptr; - - // get registeredSfxPoolItems container - registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); - - if (nullptr == pSet) - // no registeredSfxPoolItems for this WhichID - return nullptr; - - for (const auto& rCandidate : *pSet) - if (*rCandidate == rItem) - return rCandidate; - - return nullptr; -} - -void SfxItemPool::dumpAsXml(xmlTextWriterPtr pWriter) const -{ - (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxItemPool")); - - if (nullptr != ppRegisteredSfxPoolItems) - { - registeredSfxPoolItems** ppSet(ppRegisteredSfxPoolItems); - - for (sal_uInt16 a(0); a < GetSize_Impl(); a++, ppSet++) - { - if (nullptr != *ppSet) - { - for (auto& rCandidate : **ppSet) - { - if (nullptr != rCandidate) - { - rCandidate->dumpAsXml(pWriter); - } - } - } - } - } - - (void)xmlTextWriterEndElement(pWriter); + return pItemInfos[nWhich - mnStart]._nSID; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx index 3b8a77f8186f..41051a981aa4 100644 --- a/svl/source/items/itemset.cxx +++ b/svl/source/items/itemset.cxx @@ -50,7 +50,6 @@ size_t getUsedSfxPoolItemHolderCount() { return nUsedSfxPoolItemHolderCount; } // ScPatternAttr). Still keep it so that when errors // come up to this change be able to quickly check using the // fallback flag 'ITEM_CLASSIC_MODE' -static bool g_bItemClassicMode(getenv("ITEM_CLASSIC_MODE")); // I thought about this constructor a while, but when there is no // Item we need no cleanup at destruction (what we would need the @@ -83,7 +82,9 @@ SfxPoolItemHolder::SfxPoolItemHolder(SfxItemPool& rPool, const SfxPoolItem* pIte nUsedSfxPoolItemHolderCount++; #endif if (nullptr != m_pItem) - m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), bPassingOwnership); + m_pItem = implCreateItemEntry(getPool(), m_pItem, m_pItem->Which(), bPassingOwnership); + if (nullptr != m_pItem && getPool().NeedsPoolRegistration(m_pItem->Which())) + getPool().registerPoolItemHolder(*this); } SfxPoolItemHolder::SfxPoolItemHolder(const SfxPoolItemHolder& rHolder) @@ -99,7 +100,9 @@ SfxPoolItemHolder::SfxPoolItemHolder(const SfxPoolItemHolder& rHolder) nUsedSfxPoolItemHolderCount++; #endif if (nullptr != m_pItem) - m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), false); + m_pItem = implCreateItemEntry(getPool(), m_pItem, m_pItem->Which(), false); + if (nullptr != m_pItem && getPool().NeedsPoolRegistration(m_pItem->Which())) + getPool().registerPoolItemHolder(*this); } SfxPoolItemHolder::~SfxPoolItemHolder() @@ -108,8 +111,10 @@ SfxPoolItemHolder::~SfxPoolItemHolder() assert(!isDeleted() && "Destructed instance used (!)"); nAllocatedSfxPoolItemHolderCount--; #endif + if (nullptr != m_pItem && getPool().NeedsPoolRegistration(m_pItem->Which())) + getPool().unregisterPoolItemHolder(*this); if (nullptr != m_pItem) - implCleanupItemEntry(*m_pPool, m_pItem); + implCleanupItemEntry(m_pItem); #ifdef DBG_UTIL m_bDeleted = true; #endif @@ -122,14 +127,18 @@ const SfxPoolItemHolder& SfxPoolItemHolder::operator=(const SfxPoolItemHolder& r if (this == &rHolder || *this == rHolder) return *this; + if (nullptr != m_pItem && getPool().NeedsPoolRegistration(m_pItem->Which())) + getPool().unregisterPoolItemHolder(*this); if (nullptr != m_pItem) - implCleanupItemEntry(*m_pPool, m_pItem); + implCleanupItemEntry(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); + m_pItem = implCreateItemEntry(getPool(), m_pItem, m_pItem->Which(), false); + if (nullptr != m_pItem && getPool().NeedsPoolRegistration(m_pItem->Which())) + getPool().registerPoolItemHolder(*this); return *this; } @@ -154,6 +163,7 @@ SfxItemSet::SfxItemSet(SfxItemPool& rPool) : m_pPool(&rPool) , m_pParent(nullptr) , m_nCount(0) + , m_nRegister(0) , m_nTotalCount(svl::detail::CountRanges(rPool.GetFrozenIdRanges())) , m_bItemsFixed(false) , m_ppItems(new SfxPoolItem const *[m_nTotalCount]{}) @@ -171,6 +181,7 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, SfxAllItemSetFlag ) : m_pPool(&rPool) , m_pParent(nullptr) , m_nCount(0) + , m_nRegister(0) , m_nTotalCount(0) , m_bItemsFixed(false) , m_ppItems(nullptr) @@ -188,6 +199,7 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, WhichRangesContainer&& ranges, SfxPo : m_pPool(&rPool) , m_pParent(nullptr) , m_nCount(0) + , m_nRegister(0) , m_nTotalCount(nTotalCount) , m_bItemsFixed(true) , m_ppItems(ppItems) @@ -209,6 +221,7 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rOther, : m_pPool(rOther.m_pPool) , m_pParent(rOther.m_pParent) , m_nCount(rOther.m_nCount) + , m_nRegister(rOther.m_nRegister) , m_nTotalCount(rOther.m_nTotalCount) , m_bItemsFixed(true) , m_ppItems(ppMyItems) @@ -234,12 +247,16 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rOther, *ppDst = implCreateItemEntry(*GetPool(), rSource, 0, false); ppDst++; } + + if (0 != m_nRegister) + GetPool()->registerItemSet(*this); } SfxItemSet::SfxItemSet(SfxItemPool& pool, WhichRangesContainer wids) : m_pPool(&pool) , m_pParent(nullptr) , m_nCount(0) + , m_nRegister(0) , m_nTotalCount(svl::detail::CountRanges(wids)) , m_bItemsFixed(false) , m_ppItems(new SfxPoolItem const *[m_nTotalCount]{}) @@ -278,9 +295,13 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pS // return pSource; if (0 == pSource->Which()) + { // These *should* be SfxVoidItem(0) the only Items with 0 == WhichID, // these need to be cloned (currently...) + if (bPassingOwnership) + return pSource; return pSource->Clone(); + } // get correct target WhichID if (0 == nWhich) @@ -321,6 +342,46 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pS return pSource; } + // // currently need to check if pSource is a default Item and + // // avoid it to leave the Pool. This is necessary since Pools + // // currently delete their default items hard, resetting RefCnt + // // and killing them. This might change after a Pool refinement. + // // For now, replace them with the local Pool default. It *might* + // // be even necessary to replace with a cloned non-default instance + // // if the defaults differ. + // // NOTE: Currently even some Pools have no 'real' StaticDefaults, + // // but these also get deleted (sigh) + // if (IsStaticDefaultItem(pSource)) + // { + // assert(!bPassingOwnership && "ITEM: PassingOwnership not possible combined with StaticDefault (!)"); + // const SfxPoolItem* pStatic(pTargetPool->GetItem2Default(nWhich)); + // if (nullptr != pStatic) + // { + // if (SfxPoolItem::areSame(pSource, pStatic)) + // pSource = pStatic; + // else + // { + // pSource = pSource->Clone(pMasterPool); + // bPassingOwnership = true; + // } + // } + // } + // else if (IsDefaultItem(pSource)) + // { + // assert(!bPassingOwnership && "ITEM: PassingOwnership not possible combined with DynaimcDefault (!)"); + // const SfxPoolItem* pDynamic(pTargetPool->GetPoolDefaultItem(nWhich)); + // if (nullptr != pDynamic) + // { + // if (SfxPoolItem::areSame(pSource, pDynamic)) + // pSource = pDynamic; + // else + // { + // pSource = pSource->Clone(pMasterPool); + // bPassingOwnership = true; + // } + // } + // } + // CAUTION: Shareable_Impl and NeedsPoolRegistration_Impl // use index, not WhichID (one more reason to change the Pools) const sal_uInt16 nIndex(pTargetPool->GetIndex_Impl(nWhich)); @@ -351,49 +412,11 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pS if (pSource->isSetItem() && static_cast(pSource)->GetItemSet().GetPool() != pMasterPool) break; - // If the Item is registered it is pool-dependent, so do not share when - // it is registered but not at this pool - if (pSource->isRegisteredAtPool() && !pTargetPool->isSfxPoolItemRegisteredAtThisPool(*pSource)) - break; - // If we get here we can share the Item pSource->AddRef(); return pSource; } - // g_bItemClassicMode: try finding already existing item - // NOTE: the UnitTest testIteratorsDefPattern claims that that Item "can be - // edited by the user" which explains why it breaks so many rules for Items, - // it behaves like an alien. That Item in the SC Pool claims to be a - // 'StaticDefault' and gets changed (..?) - - // only do this if classic mode or required (calls from Pool::Direct*) - while(g_bItemClassicMode) - { - if (!pTargetPool->Shareable_Impl(nIndex)) - // not shareable, so no need to search for identical item - break; - - // try to get equal Item. This is the expensive part... - const SfxPoolItem* pExisting(pTargetPool->tryToGetEqualItem(*pSource, nWhich)); - - if (nullptr == pExisting) - // none found, done - break; - - if (0 == pExisting->GetRefCount()) - // do not share not-yet shared Items (should not happen) - break; - - if (bPassingOwnership) - // need to cleanup if we are offered to own pSource - delete pSource; - - // If we get here we can share the found Item - pExisting->AddRef(); - return pExisting; - } - // check if the handed over and to be directly used item is a // SfxSetItem, that would make it pool-dependent. It then must have // the same target-pool, ensure that by the cost of cloning it @@ -419,30 +442,10 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pS // increase RefCnt 0->1 pSource->AddRef(); - // try to register @Pool (only needed if not yet registered) - if (!pSource->isRegisteredAtPool()) - { - bool bRegisterAtPool(false); - - if (g_bItemClassicMode) - { - // in classic mode register only/all shareable items - bRegisterAtPool = pTargetPool->Shareable_Impl(nIndex); - } - else - { - // in new mode register only/all items marked as need to be registered - bRegisterAtPool = pTargetPool->NeedsPoolRegistration_Impl(nIndex); - } - - if (bRegisterAtPool) - pTargetPool->registerSfxPoolItem(*pSource); - } - return pSource; } -void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource) +void implCleanupItemEntry(SfxPoolItem const* pSource) { if (nullptr == pSource) // no entry, done @@ -454,10 +457,6 @@ void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource) if (0 == pSource->Which()) { - // de-register when registered @pool - if (pSource->isRegisteredAtPool()) - rPool.unregisterSfxPoolItem(*pSource); - // These *should* be SfxVoidItem(0) the only Items with 0 == WhichID // and need to be deleted delete pSource; @@ -479,10 +478,6 @@ void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource) // good to find other errors) pSource->ReleaseRef(); - // de-register before deletion when registered @pool - if (pSource->isRegisteredAtPool()) - rPool.unregisterSfxPoolItem(*pSource); - // delete Item delete pSource; } @@ -491,6 +486,7 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) : m_pPool( rASet.m_pPool ) , m_pParent( rASet.m_pParent ) , m_nCount( rASet.m_nCount ) + , m_nRegister( rASet.m_nRegister ) , m_nTotalCount( rASet.m_nTotalCount ) , m_bItemsFixed(false) , m_ppItems(nullptr) @@ -502,9 +498,7 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) nUsedSfxItemSetCount++; #endif if (rASet.GetRanges().empty()) - { return; - } if (0 == rASet.Count()) { @@ -527,12 +521,15 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) } assert(svl::detail::validRanges2(m_pWhichRanges)); + if (0 != m_nRegister) + GetPool()->registerItemSet(*this); } SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept : m_pPool( rASet.m_pPool ) , m_pParent( rASet.m_pParent ) , m_nCount( rASet.m_nCount ) + , m_nRegister( rASet.m_nRegister ) , m_nTotalCount( rASet.m_nTotalCount ) , m_bItemsFixed(false) , m_ppItems( rASet.m_ppItems ) @@ -550,18 +547,27 @@ SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept // can just copy the pointers, the ones in the original m_ppItems // array will no longer be used/referenced (unused mem, but not lost, - // it's part of the ItemSet-derived object) + // it's part of the ItemSet-derived object). std::copy(rASet.m_ppItems, rASet.m_ppItems + TotalCount(), m_ppItems); } - else - { - // taking over ownership - rASet.m_nTotalCount = 0; - rASet.m_ppItems = nullptr; - } + + // deregister if rASet is registered before ptrs vanish + if (0 != rASet.m_nRegister) + rASet.GetPool()->unregisterItemSet(rASet); + + // register if new set needs that + if (0 != m_nRegister) + GetPool()->registerItemSet(*this); + + // taking over ownership rASet.m_pPool = nullptr; rASet.m_pParent = nullptr; rASet.m_nCount = 0; + rASet.m_nRegister = 0; + rASet.m_nTotalCount = 0; + rASet.m_ppItems = nullptr; + rASet.m_pWhichRanges.reset(); + rASet.m_aCallback = nullptr; assert(svl::detail::validRanges2(m_pWhichRanges)); } @@ -614,6 +620,65 @@ sal_uInt16 SfxItemSet::ClearSingleItem_ForWhichID( sal_uInt16 nWhich ) return 0; } +void SfxItemSet::checkRemovePoolRegistration(const SfxPoolItem* pItem) +{ + if (nullptr == pItem) + // no Item, done + return; + + if (IsInvalidItem(pItem) || pItem->isVoidItem() || 0 == pItem->Which()) + // checks IsInvalidItem/SfxVoidItem(0) + return; + + if (SfxItemPool::IsSlot(pItem->Which())) + // no slots, these do not support NeedsPoolRegistration + return; + + if(!GetPool()->NeedsPoolRegistration(pItem->Which())) + // not needed for this item, done + return; + + // there must be a registered one + assert(0 != m_nRegister); + + // decrement counter + m_nRegister--; + + // deregister when no more Items that NeedsPoolRegistration exist + if (0 == m_nRegister) + GetPool()->unregisterItemSet(*this); +} + +void SfxItemSet::checkAddPoolRegistration(const SfxPoolItem* pItem) +{ + if (nullptr == pItem) + // no Item, done + return; + + if (IsInvalidItem(pItem) || pItem->isVoidItem() || 0 == pItem->Which()) + // checks IsInvalidItem/SfxVoidItem(0) + return; + + if (SfxItemPool::IsSlot(pItem->Which())) + // no slots, these do not support NeedsPoolRegistration + return; + + if(!GetPool()->NeedsPoolRegistration(pItem->Which())) + // not needed for this item, done + return; + + // there cannot be more than m_nCount, *but* use one more to + // allow paired Remove/Add calls (see SfxItemSet::PutImpl) + assert(m_nRegister <= m_nCount); + + // register when first Item that NeedsPoolRegistration exist + if (0 == m_nRegister) + GetPool()->registerItemSet(*this); + + // increment counter + m_nRegister++; +} + sal_uInt16 SfxItemSet::ClearSingleItem_ForOffset( sal_uInt16 nOffset ) { assert(nOffset < TotalCount()); @@ -633,8 +698,11 @@ sal_uInt16 SfxItemSet::ClearSingleItem_ForOffset( sal_uInt16 nOffset ) m_aCallback(*aEntry, nullptr); } + // check register for remove + checkRemovePoolRegistration(*aEntry); + // cleanup item & reset ptr - implCleanupItemEntry(*GetPool(), *aEntry); + implCleanupItemEntry(*aEntry); *aEntry = nullptr; return 1; @@ -654,12 +722,19 @@ sal_uInt16 SfxItemSet::ClearAllItemsImpl() m_aCallback(rCandidate, nullptr); } - implCleanupItemEntry(*GetPool(), rCandidate); + implCleanupItemEntry(rCandidate); } // remember count before resetting it, that is the retval const sal_uInt16 nRetval(Count()); m_nCount = 0; + + if (0 != m_nRegister) + { + GetPool()->unregisterItemSet(*this); + m_nRegister = 0; + } + return nRetval; } @@ -811,8 +886,13 @@ const SfxPoolItem* SfxItemSet::PutImpl(const SfxPoolItem& rItem, sal_uInt16 nWhi m_aCallback(*aEntry, pNew); } + // check register for add/remove. add first so that unregister/register + // is avoided when an Item is replaced (increase, decrease, do not reach 0) + checkAddPoolRegistration(pNew); + checkRemovePoolRegistration(*aEntry); + // cleanup old entry & set entry at m_ppItems array - implCleanupItemEntry(*GetPool(), *aEntry); + implCleanupItemEntry(*aEntry); *aEntry = pNew; return pNew; @@ -1173,15 +1253,10 @@ const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const { if (IsInvalidItem(*aFoundOne)) { - //FIXME: The following code is duplicated further down - assert(m_pPool); - //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich); - //!return aDefault; return GetPool()->GetDefaultItem(nWhich); } #ifdef DBG_UTIL - const SfxPoolItem *pItem = *aFoundOne; - if ( pItem->isVoidItem() || !pItem->Which() ) + if ((*aFoundOne)->isVoidItem()) SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item"); #endif return **aFoundOne; @@ -1215,7 +1290,7 @@ void SfxItemSet::Intersect( const SfxItemSet& rSet ) if (!rSet.Count()) { // no Items contained in rSet -> Delete everything - ClearItem(); + ClearAllItemsImpl(); return; } @@ -1272,7 +1347,7 @@ void SfxItemSet::Differentiate(const SfxItemSet& rSet) if (this == &rSet) { // same ItemSet, all Items are contained -> Delete everything - ClearItem(); + ClearAllItemsImpl(); return; } @@ -1416,7 +1491,10 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p // *ppFnd1 = &GetPool()->Put( *pFnd2 ); if ( *ppFnd1 ) + { ++m_nCount; + checkAddPoolRegistration(*ppFnd1); + } } // 1st Item set? @@ -1429,7 +1507,8 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p **ppFnd1 != GetPool()->GetDefaultItem((*ppFnd1)->Which()) ) { // Decision table: set, default, !=, sal_False - implCleanupItemEntry(*GetPool(), *ppFnd1); + checkRemovePoolRegistration(*ppFnd1); + implCleanupItemEntry(*ppFnd1); // GetPool()->Remove( **ppFnd1 ); *ppFnd1 = INVALID_POOL_ITEM; } @@ -1442,7 +1521,8 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p { // Decision table: set, dontcare, doesn't matter, sal_False // or: set, dontcare, !=, sal_True - implCleanupItemEntry(*GetPool(), *ppFnd1); + checkRemovePoolRegistration(*ppFnd1); + implCleanupItemEntry(*ppFnd1); // GetPool()->Remove( **ppFnd1 ); *ppFnd1 = INVALID_POOL_ITEM; } @@ -1453,7 +1533,8 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p if ( **ppFnd1 != *pFnd2 ) { // Decision table: set, set, !=, doesn't matter - implCleanupItemEntry(*GetPool(), *ppFnd1); + checkRemovePoolRegistration(*ppFnd1); + implCleanupItemEntry(*ppFnd1); // GetPool()->Remove( **ppFnd1 ); *ppFnd1 = INVALID_POOL_ITEM; } @@ -1551,7 +1632,8 @@ void SfxItemSet::InvalidateItem_ForOffset(sal_uInt16 nOffset) return; // cleanup entry - implCleanupItemEntry(*GetPool(), *aFoundOne); + checkRemovePoolRegistration(*aFoundOne); + implCleanupItemEntry(*aFoundOne); } // set new entry diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx index b563abfd8b7c..41b85ba60889 100644 --- a/svl/source/items/poolitem.cxx +++ b/svl/source/items/poolitem.cxx @@ -497,7 +497,6 @@ SfxPoolItem::SfxPoolItem(sal_uInt16 const nWhich) , m_bIsVoidItem(false) , m_bStaticDefault(false) , m_bPoolDefault(false) - , m_bRegisteredAtPool(false) , m_bIsSetItem(false) #ifdef DBG_UTIL , m_bDeleted(false) diff --git a/svx/source/unodraw/UnoNameItemTable.cxx b/svx/source/unodraw/UnoNameItemTable.cxx index 67b1dcc7d59c..ef7f193c40d5 100644 --- a/svx/source/unodraw/UnoNameItemTable.cxx +++ b/svx/source/unodraw/UnoNameItemTable.cxx @@ -182,7 +182,9 @@ void SAL_CALL SvxUnoNameItemTable::replaceByName( const OUString& aApiName, cons if (mpModelPool) { SampleItem aSample(mnWhich, aName); - for (const SfxPoolItem* pNameOrIndex : mpModelPool->FindItemSurrogate(mnWhich, aSample)) + ItemSurrogates aSurrogates; + mpModelPool->FindItemSurrogate(aSurrogates, mnWhich, aSample); + for (const SfxPoolItem* pNameOrIndex : aSurrogates) if (isValid(static_cast(pNameOrIndex))) { const_cast(pNameOrIndex)->PutValue( aElement, mnMemberId ); @@ -210,7 +212,9 @@ uno::Any SAL_CALL SvxUnoNameItemTable::getByName( const OUString& aApiName ) if (mpModelPool && !aName.isEmpty()) { SampleItem aSample(mnWhich, aName); - for (const SfxPoolItem* pFindItem : mpModelPool->FindItemSurrogate(mnWhich, aSample)) + ItemSurrogates aSurrogates; + mpModelPool->FindItemSurrogate(aSurrogates, mnWhich, aSample); + for (const SfxPoolItem* pFindItem : aSurrogates) if (isValid(static_cast(pFindItem))) { uno::Any aAny; @@ -230,7 +234,10 @@ uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( ) if (mpModelPool) - for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, mnWhich); + for (const SfxPoolItem* pItem : aSurrogates) { const NameOrIndex *pNameOrIndex = static_cast(pItem); @@ -240,6 +247,7 @@ uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( ) OUString aApiName = SvxUnogetApiNameForItem(mnWhich, pNameOrIndex->GetName()); aNameSet.insert(aApiName); } + } return comphelper::containerToSequence(aNameSet); } @@ -257,7 +265,9 @@ sal_Bool SAL_CALL SvxUnoNameItemTable::hasByName( const OUString& aApiName ) return false; SampleItem aSample(mnWhich, aName); - for (const SfxPoolItem* pFindItem : mpModelPool->FindItemSurrogate(mnWhich, aSample)) + ItemSurrogates aSurrogates; + mpModelPool->FindItemSurrogate(aSurrogates, mnWhich, aSample); + for (const SfxPoolItem* pFindItem : aSurrogates) if (isValid(static_cast(pFindItem))) return true; return false; @@ -268,13 +278,17 @@ sal_Bool SAL_CALL SvxUnoNameItemTable::hasElements( ) SolarMutexGuard aGuard; if (mpModelPool) - for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, mnWhich); + for (const SfxPoolItem* pItem : aSurrogates) { const NameOrIndex *pNameOrIndex = static_cast(pItem); if( isValid( pNameOrIndex ) ) return true; } + } return false; } diff --git a/svx/source/unodraw/UnoNamespaceMap.cxx b/svx/source/unodraw/UnoNamespaceMap.cxx index b013c5a8ab6b..f022bad6a270 100644 --- a/svx/source/unodraw/UnoNamespaceMap.cxx +++ b/svx/source/unodraw/UnoNamespaceMap.cxx @@ -127,9 +127,10 @@ NamespaceIteratorImpl::NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool mnItem = -1; if (mpWhichId && (0 != *mpWhichId) && mpPool) { - const registeredSfxPoolItems& rSurrogates(mpPool->GetItemSurrogates(*mpWhichId)); - mvItems.reserve(rSurrogates.size()); - for (const SfxPoolItem* pItem : rSurrogates) + ItemSurrogates aSurrogates; + mpPool->GetItemSurrogates(aSurrogates, *mpWhichId); + mvItems.reserve(aSurrogates.size()); + for (const SfxPoolItem* pItem : aSurrogates) mvItems.push_back(static_cast(pItem)); } } @@ -163,9 +164,10 @@ bool NamespaceIteratorImpl::next( OUString& rPrefix, OUString& rURL ) mvItems.clear(); if (mpPool) { - const registeredSfxPoolItems& rSurrogates(mpPool->GetItemSurrogates(*mpWhichId)); - mvItems.reserve(rSurrogates.size()); - for (const SfxPoolItem* pItem2 : rSurrogates) + ItemSurrogates aSurrogates; + mpPool->GetItemSurrogates(aSurrogates, *mpWhichId); + mvItems.reserve(aSurrogates.size()); + for (const SfxPoolItem* pItem2 : aSurrogates) mvItems.push_back(static_cast(pItem2)); } return next( rPrefix, rURL ); diff --git a/svx/source/unodraw/unomtabl.cxx b/svx/source/unodraw/unomtabl.cxx index 60b858f38a6f..27699ea651f7 100644 --- a/svx/source/unodraw/unomtabl.cxx +++ b/svx/source/unodraw/unomtabl.cxx @@ -246,7 +246,10 @@ void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const bool bFound = false; if (mpModelPool) - for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { NameOrIndex *pItem = const_cast(static_cast(p)); if( pItem && pItem->GetName() == aName ) @@ -256,9 +259,13 @@ void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const break; } } + } if (mpModelPool) - for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { NameOrIndex *pItem = const_cast(static_cast(p)); if( pItem && pItem->GetName() == aName ) @@ -268,6 +275,7 @@ void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const break; } } + } if( !bFound ) throw container::NoSuchElementException(); @@ -278,7 +286,10 @@ void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const static bool getByNameFromPool( std::u16string_view rSearchName, SfxItemPool const * pPool, sal_uInt16 nWhich, uno::Any& rAny ) { if (pPool) - for (const SfxPoolItem* p : pPool->GetItemSurrogates(nWhich)) + { + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, nWhich); + for (const SfxPoolItem* p : aSurrogates) { const NameOrIndex *pItem = static_cast(p); @@ -288,6 +299,7 @@ static bool getByNameFromPool( std::u16string_view rSearchName, SfxItemPool cons return true; } } + } return false; } @@ -321,7 +333,9 @@ uno::Any SAL_CALL SvxUnoMarkerTable::getByName( const OUString& aApiName ) static void createNamesForPool( SfxItemPool const * pPool, sal_uInt16 nWhich, std::set< OUString >& rNameSet ) { - for (const SfxPoolItem* p : pPool->GetItemSurrogates(nWhich)) + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, nWhich); + for (const SfxPoolItem* p : aSurrogates) { const NameOrIndex* pItem = static_cast(p); @@ -361,21 +375,29 @@ sal_Bool SAL_CALL SvxUnoMarkerTable::hasByName( const OUString& aName ) aSearchName = SvxUnogetInternalNameForItem(XATTR_LINESTART, aName); if (mpModelPool) - for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { pItem = static_cast(p); if( pItem && pItem->GetName() == aSearchName ) return true; } + } aSearchName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aName); if (mpModelPool) - for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { pItem = static_cast(p); if( pItem && pItem->GetName() == aSearchName ) return true; } + } return false; } @@ -393,20 +415,28 @@ sal_Bool SAL_CALL SvxUnoMarkerTable::hasElements( ) const NameOrIndex *pItem; if (mpModelPool) - for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { pItem = static_cast(p); if( pItem && !pItem->GetName().isEmpty() ) return true; } + } if (mpModelPool) - for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND)) + { + ItemSurrogates aSurrogates; + mpModelPool->GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { pItem = static_cast(p); if( pItem && !pItem->GetName().isEmpty() ) return true; } + } return false; } diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx index f0e1f89ce132..90ff0eeb4275 100644 --- a/svx/source/unodraw/unoshape.cxx +++ b/svx/source/unodraw/unoshape.cxx @@ -1438,7 +1438,9 @@ bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName, SfxItem return false; } - for (const SfxPoolItem* p : rSet.GetPool()->GetItemSurrogates(nWID)) + ItemSurrogates aSurrogates; + rSet.GetPool()->GetItemSurrogates(aSurrogates, nWID); + for (const SfxPoolItem* p : aSurrogates) { const NameOrIndex* pItem = static_cast(p); if( pItem->GetName() == aName ) diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx index 957f6d0ffb26..e712be7632f2 100644 --- a/svx/source/xoutdev/xattr.cxx +++ b/svx/source/xoutdev/xattr.cxx @@ -142,7 +142,9 @@ OUString NameOrIndex::CheckNamedItem( const NameOrIndex* pCheckItem, const sal_u if (!aUniqueName.isEmpty() && pPool1) { - for (const SfxPoolItem* pItem : pPool1->GetItemSurrogates(nWhich)) + ItemSurrogates aSurrogates; + pPool1->GetItemSurrogates(aSurrogates, nWhich); + for (const SfxPoolItem* pItem : aSurrogates) { const NameOrIndex *pNameOrIndex = static_cast(pItem); @@ -227,7 +229,9 @@ OUString NameOrIndex::CheckNamedItem( const NameOrIndex* pCheckItem, const sal_u if (aUniqueName.isEmpty() && pPool1) { - for (const SfxPoolItem* pItem : pPool1->GetItemSurrogates(nWhich)) + ItemSurrogates aSurrogates; + pPool1->GetItemSurrogates(aSurrogates, nWhich); + for (const SfxPoolItem* pItem : aSurrogates) { const NameOrIndex *pNameOrIndex = static_cast(pItem); @@ -1248,7 +1252,9 @@ std::unique_ptr XLineStartItem::checkForUniqueItem( SdrModel* pM const SfxItemPool& rPool1 = pModel->GetItemPool(); if (!aUniqueName.isEmpty()) { - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART)) + ItemSurrogates aSurrogates; + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1268,7 +1274,8 @@ std::unique_ptr XLineStartItem::checkForUniqueItem( SdrModel* pM if( !bForceNew ) { - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND)) + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1291,7 +1298,9 @@ std::unique_ptr XLineStartItem::checkForUniqueItem( SdrModel* pM const SfxItemPool* pPool2 = pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : nullptr; if( !aUniqueName.isEmpty() && pPool2) { - for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINESTART)) + ItemSurrogates aSurrogates; + pPool2->GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1311,7 +1320,8 @@ std::unique_ptr XLineStartItem::checkForUniqueItem( SdrModel* pM if( !bForceNew ) { - for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINEEND)) + pPool2->GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1340,7 +1350,9 @@ std::unique_ptr XLineStartItem::checkForUniqueItem( SdrModel* pM sal_Int32 nUserIndex = 1; const OUString aUser(SvxResId(RID_SVXSTR_LINEEND)); - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART)) + ItemSurrogates aSurrogates; + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1362,7 +1374,8 @@ std::unique_ptr XLineStartItem::checkForUniqueItem( SdrModel* pM } } - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND)) + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1487,7 +1500,9 @@ std::unique_ptr XLineEndItem::checkForUniqueItem( SdrModel* pModel const SfxItemPool& rPool1 = pModel->GetItemPool(); if (!aUniqueName.isEmpty()) { - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART)) + ItemSurrogates aSurrogates; + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1507,7 +1522,8 @@ std::unique_ptr XLineEndItem::checkForUniqueItem( SdrModel* pModel if( !bForceNew ) { - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND)) + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1530,7 +1546,9 @@ std::unique_ptr XLineEndItem::checkForUniqueItem( SdrModel* pModel const SfxItemPool* pPool2 = pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : nullptr; if( !aUniqueName.isEmpty() && pPool2) { - for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINESTART)) + ItemSurrogates aSurrogates; + pPool2->GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1550,7 +1568,8 @@ std::unique_ptr XLineEndItem::checkForUniqueItem( SdrModel* pModel if( !bForceNew ) { - for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINEEND)) + pPool2->GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1579,7 +1598,9 @@ std::unique_ptr XLineEndItem::checkForUniqueItem( SdrModel* pModel sal_Int32 nUserIndex = 1; const OUString aUser(SvxResId(RID_SVXSTR_LINEEND)); - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART)) + ItemSurrogates aSurrogates; + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINESTART); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); @@ -1601,7 +1622,8 @@ std::unique_ptr XLineEndItem::checkForUniqueItem( SdrModel* pModel } } - for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND)) + rPool1.GetItemSurrogates(aSurrogates, XATTR_LINEEND); + for (const SfxPoolItem* p : aSurrogates) { auto pItem = dynamic_cast(p); diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index 41437f04b84c..00c1c2e61c6d 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -416,13 +416,14 @@ bool SwCursorShell::GotoNxtPrvTableFormula( bool bNext, bool bOnlyErrors ) &rPos, &tmp) ); } - const registeredSfxPoolItems& rSurrogates(GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)); - const sal_uInt32 nMaxItems(rSurrogates.size()); + ItemSurrogates aSurrogates; + GetDoc()->GetAttrPool().GetItemSurrogates(aSurrogates, RES_BOXATR_FORMULA); + const sal_uInt32 nMaxItems(aSurrogates.size()); if( nMaxItems > 0 ) { sal_uInt8 nMaxDo = 2; do { - for (const SfxPoolItem* pItem : rSurrogates) + for (const SfxPoolItem* pItem : aSurrogates) { const SwTableBox* pTBox; auto pFormulaItem = dynamic_cast(pItem); @@ -522,8 +523,9 @@ bool SwCursorShell::GotoNxtPrvTOXMark( bool bNext ) const SwTextNode* pTextNd; const SwTextTOXMark* pTextTOX; - const registeredSfxPoolItems& rSurrogates(GetDoc()->GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK)); - const sal_uInt32 nMaxItems(rSurrogates.size()); + ItemSurrogates aSurrogates; + GetDoc()->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_TOXMARK); + const sal_uInt32 nMaxItems(aSurrogates.size()); if( nMaxItems == 0 ) { SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound ); @@ -531,7 +533,7 @@ bool SwCursorShell::GotoNxtPrvTOXMark( bool bNext ) } do { - for (const SfxPoolItem* pItem : rSurrogates) + for (const SfxPoolItem* pItem : aSurrogates) { auto pToxMarkItem = dynamic_cast(pItem); if( !pToxMarkItem ) diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx index 66f65438c095..f2faaa4bac73 100644 --- a/sw/source/core/doc/DocumentFieldsManager.cxx +++ b/sw/source/core/doc/DocumentFieldsManager.cxx @@ -614,7 +614,9 @@ void DocumentFieldsManager::UpdateTableFields(const SwTable* pTable) } } // process all table box formulas - for (const SfxPoolItem* pItem : m_rDoc.GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)) + ItemSurrogates aSurrogates; + m_rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_BOXATR_FORMULA); + for (const SfxPoolItem* pItem : aSurrogates) { auto pBoxFormula = const_cast(pItem->DynamicWhichCast(RES_BOXATR_FORMULA)); if(pBoxFormula && pBoxFormula->GetDefinedIn()) @@ -713,7 +715,8 @@ void DocumentFieldsManager::UpdateTableFields(const SwTable* pTable) } // calculate the formula at the boxes - for (const SfxPoolItem* pItem : m_rDoc.GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)) + m_rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_BOXATR_FORMULA); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFormula = const_cast(pItem->DynamicWhichCast(RES_BOXATR_FORMULA)); if(!pFormula || !pFormula->GetDefinedIn() || pFormula->IsValid()) diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index 4bcb2a35e856..845421629fe5 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -1071,7 +1071,9 @@ void SwDoc::CalculatePagePairsForProspectPrinting( /// @return the reference in the doc for the name const SwFormatRefMark* SwDoc::GetRefMark( std::u16string_view rName ) const { - for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFormatRef = dynamic_cast(pItem); if(!pFormatRef) @@ -1091,7 +1093,9 @@ const SwFormatRefMark* SwDoc::GetRefMark( sal_uInt16 nIndex ) const const SwFormatRefMark* pRet = nullptr; sal_uInt32 nCount = 0; - for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); + for (const SfxPoolItem* pItem : aSurrogates) { auto pRefMark = dynamic_cast(pItem); if( !pRefMark ) @@ -1116,7 +1120,9 @@ const SwFormatRefMark* SwDoc::GetRefMark( sal_uInt16 nIndex ) const sal_uInt16 SwDoc::GetRefMarks( std::vector* pNames ) const { sal_uInt16 nCount = 0; - for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); + for (const SfxPoolItem* pItem : aSurrogates) { auto pRefMark = dynamic_cast(pItem); if( !pRefMark ) @@ -1247,7 +1253,9 @@ void SwDoc::InvalidateAutoCompleteFlag() const SwFormatINetFormat* SwDoc::FindINetAttr( std::u16string_view rName ) const { - for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_INETFMT); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFormatItem = dynamic_cast(pItem); if( !pFormatItem || pFormatItem->GetName() != rName ) diff --git a/sw/source/core/doc/docbasic.cxx b/sw/source/core/doc/docbasic.cxx index 19f757535d09..155a28f73d60 100644 --- a/sw/source/core/doc/docbasic.cxx +++ b/sw/source/core/doc/docbasic.cxx @@ -140,7 +140,9 @@ sal_uInt16 SwDoc::CallEvent( SvMacroItemId nEvent, const SwCallMouseEvent& rCall case EVENT_OBJECT_INETATTR: if( bCheckPtr ) { - for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_INETFMT); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFormatItem = dynamic_cast(pItem); if( pFormatItem && SfxPoolItem::areSame(rCallEvent.PTR.pINetAttr, pFormatItem) ) diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx index c723ee162e3a..317063be07f2 100644 --- a/sw/source/core/doc/docfld.cxx +++ b/sw/source/core/doc/docfld.cxx @@ -469,7 +469,9 @@ void SwDoc::GetAllUsedDB( std::vector& rDBNameList, for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD }) { - for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(nWhichHint)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, nWhichHint); + for (const SfxPoolItem* pItem : aSurrogates) { const SwFormatField* pFormatField = static_cast(pItem); const SwTextField* pTextField = pFormatField->GetTextField(); @@ -625,7 +627,9 @@ void SwDoc::ChangeDBFields( const std::vector& rOldNames, for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD }) { - for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(nWhichHint)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, nWhichHint); + for (const SfxPoolItem* pItem : aSurrogates) { SwFormatField* pFormatField = const_cast(static_cast(pItem)); SwTextField* pTextField = pFormatField->GetTextField(); @@ -937,7 +941,9 @@ void SwDocUpdateField::MakeFieldList_( SwDoc& rDoc, int eGetMode ) for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD }) { - for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(nWhichHint)) + ItemSurrogates aSurrogates; + rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, nWhichHint); + for (const SfxPoolItem* pItem : aSurrogates) { const SwFormatField* pFormatField = static_cast(pItem); const SwTextField* pTextField = pFormatField->GetTextField(); diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 26a9e2a5f69a..dc0f72031b3a 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -637,7 +637,9 @@ void SwDoc::SetDefault( const SfxItemSet& rSet ) nOldWidth = aOld.Get(RES_PARATR_TABSTOP)[ 0 ].GetTabPos(); bool bChg = false; - for (const SfxPoolItem* pItem2 : GetAttrPool().GetItemSurrogates(RES_PARATR_TABSTOP)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, RES_PARATR_TABSTOP); + for (const SfxPoolItem* pItem2 : aSurrogates) { if(auto pTabStopItem = pItem2->DynamicWhichCast(RES_PARATR_TABSTOP)) bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth, @@ -2039,7 +2041,9 @@ std::set SwDoc::GetDocColors() const sal_uInt16 pAttribs[] = {RES_CHRATR_COLOR, RES_CHRATR_HIGHLIGHT, RES_BACKGROUND}; for (sal_uInt16 nAttrib : pAttribs) { - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nAttrib)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, nAttrib); + for (const SfxPoolItem* pItem : aSurrogates) { auto pColorItem = static_cast(pItem); Color aColor( pColorItem->GetValue() ); diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx index 5caf0a3f9bd3..746da06379df 100644 --- a/sw/source/core/doc/doctxm.cxx +++ b/sw/source/core/doc/doctxm.cxx @@ -89,7 +89,9 @@ void SwDoc::GetTOIKeys(SwTOIKeyType eTyp, std::vector& rArr, rArr.clear(); // Look up all Primary and Secondary via the Pool - for (const SfxPoolItem* pPoolItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK)) + ItemSurrogates aSurrogates; + GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_TOXMARK); + for (const SfxPoolItem* pPoolItem : aSurrogates) { const SwTOXMark* pItem = dynamic_cast(pPoolItem); if( !pItem ) diff --git a/sw/source/core/doc/visiturl.cxx b/sw/source/core/doc/visiturl.cxx index 24db9230b308..377a7d06d657 100644 --- a/sw/source/core/doc/visiturl.cxx +++ b/sw/source/core/doc/visiturl.cxx @@ -57,7 +57,9 @@ void SwURLStateChanged::Notify( SfxBroadcaster& , const SfxHint& rHint ) sBkmk = "#" + pIURL->GetMark(); bool bAction = false, bUnLockView = false; - for (const SfxPoolItem* pItem : m_rDoc.GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT)) + ItemSurrogates aSurrogates; + m_rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_INETFMT); + for (const SfxPoolItem* pItem : aSurrogates) { const SwFormatINetFormat* pFormatItem = dynamic_cast(pItem); if( pFormatItem != nullptr && diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx index 75aa5e9c0736..dd4ffbcec57c 100644 --- a/sw/source/core/docnode/node.cxx +++ b/sw/source/core/docnode/node.cxx @@ -696,7 +696,9 @@ const SwPageDesc* SwNode::FindPageDesc( SwNodeOffset* pPgDescNdIdx ) const { SwFindNearestNode aInfo( *pNd ); // Over all Nodes of all PageDescs - for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(RES_PAGEDESC)) + ItemSurrogates aSurrogates; + rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_PAGEDESC); + for (const SfxPoolItem* pItem : aSurrogates) { auto pPageDescItem = dynamic_cast(pItem); if( pPageDescItem && pPageDescItem->GetDefinedIn() ) diff --git a/sw/source/core/edit/edfld.cxx b/sw/source/core/edit/edfld.cxx index f77ae8d97e07..908e7f9a3c40 100644 --- a/sw/source/core/edit/edfld.cxx +++ b/sw/source/core/edit/edfld.cxx @@ -171,7 +171,9 @@ static SwTextField* lcl_FindInputField( SwDoc* pDoc, const SwField& rField ) && (static_cast(rField.GetTyp())->GetType() & nsSwGetSetExpType::GSE_STRING))) { - for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INPUTFIELD)) + ItemSurrogates aSurrogates; + pDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_INPUTFIELD); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFormatField = dynamic_cast(pItem); if( pFormatField && pFormatField->GetField() == &rField ) @@ -184,7 +186,9 @@ static SwTextField* lcl_FindInputField( SwDoc* pDoc, const SwField& rField ) else if( SwFieldIds::SetExp == rField.Which() && static_cast(rField).GetInputFlag() ) { - for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD)) + ItemSurrogates aSurrogates; + pDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_FIELD); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFormatField = dynamic_cast(pItem); if( pFormatField && pFormatField->GetField() == &rField ) diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx index ba5f45beceec..376820d45d76 100644 --- a/sw/source/core/fields/docufld.cxx +++ b/sw/source/core/fields/docufld.cxx @@ -141,7 +141,9 @@ void SwPageNumberFieldType::ChangeExpansion( SwDoc* pDoc, // check the flag since the layout NEVER sets it back const SfxItemPool &rPool = pDoc->GetAttrPool(); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_PAGEDESC)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, RES_PAGEDESC); + for (const SfxPoolItem* pItem : aSurrogates) { auto pDesc = dynamic_cast(pItem); if( pDesc && pDesc->GetNumOffset() && pDesc->GetDefinedIn() ) diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index 7944d79cb880..2ed1c0b23900 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -1840,7 +1840,9 @@ sal_uInt16 SwFrame::GetVirtPageNum() const const SwPageFrame *pVirtPage = nullptr; const SwFrame *pFrame = nullptr; const SfxItemPool &rPool = pPage->GetFormat()->GetDoc()->GetAttrPool(); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_PAGEDESC)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, RES_PAGEDESC); + for (const SfxPoolItem* pItem : aSurrogates) { const SwFormatPageDesc *pDesc = dynamic_cast(pItem); if ( !pDesc ) diff --git a/sw/source/core/table/swnewtable.cxx b/sw/source/core/table/swnewtable.cxx index 1a21a9e0354b..ac057a7ae938 100644 --- a/sw/source/core/table/swnewtable.cxx +++ b/sw/source/core/table/swnewtable.cxx @@ -2383,7 +2383,9 @@ bool SwTable::CanConvertSubtables() const { return false; // no formulas in fields yet } - if (!pDoc->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA).empty()) + ItemSurrogates aSurrogates; + pDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_BOXATR_FORMULA); + if (!aSurrogates.empty()) { return false; // no table box formulas yet } diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx index cfa9f52a206c..9654c6dc5b61 100644 --- a/sw/source/core/table/swtable.cxx +++ b/sw/source/core/table/swtable.cxx @@ -1630,7 +1630,9 @@ bool SwTable::IsDeleted() const void SwTable::GatherFormulas(std::vector& rvFormulas) { - for(const SfxPoolItem* pItem: GetFrameFormat()->GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)) + ItemSurrogates aSurrogates; + GetFrameFormat()->GetDoc()->GetAttrPool().GetItemSurrogates(aSurrogates, RES_BOXATR_FORMULA); + for(const SfxPoolItem* pItem: aSurrogates) { auto pBoxFormula = dynamic_cast(pItem); assert(pBoxFormula); // use StaticWhichCast instead? @@ -1720,7 +1722,9 @@ void SwTable::UpdateFields(TableFormulaUpdateFlags eFlags) } } // process all table box formulas - for(const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)) + ItemSurrogates aSurrogates; + pDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_BOXATR_FORMULA); + for(const SfxPoolItem* pItem : aSurrogates) { auto pBoxFormula = const_cast(pItem->DynamicWhichCast(RES_BOXATR_FORMULA)); if(pBoxFormula && pBoxFormula->GetDefinedIn()) diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx index 7e694e21b7d2..a9c626eb5be0 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -683,11 +683,12 @@ void SwUndoResetAttr::RedoImpl(::sw::UndoRedoContext & rContext) break; case RES_TXTATR_REFMARK: { - const registeredSfxPoolItems& aRange(rDoc.GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)); + ItemSurrogates aSurrogates; + rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); SwHistoryHint* pHistoryHint = GetHistory()[0]; if (pHistoryHint && HSTRY_SETREFMARKHNT == pHistoryHint->Which()) { - for (const SfxPoolItem* pItem : aRange) + for (const SfxPoolItem* pItem : aSurrogates) { assert(dynamic_cast(pItem)); const auto pFormatRefMark = static_cast(pItem); diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx index 23b6d85141d5..c4fa8a3f4668 100644 --- a/sw/source/core/unocore/unostyle.cxx +++ b/sw/source/core/unocore/unostyle.cxx @@ -3797,7 +3797,9 @@ SwAutoStylesEnumImpl::SwAutoStylesEnumImpl( SwDoc& rInitDoc, IStyleAccess::SwAut // do this in two phases otherwise we invalidate the iterators when we insert into the pool std::vector vRubyItems; - for (const SfxPoolItem* pItem : rAttrPool.GetItemSurrogates(RES_TXTATR_CJK_RUBY)) + ItemSurrogates aSurrogates; + rAttrPool.GetItemSurrogates(aSurrogates, RES_TXTATR_CJK_RUBY); + for (const SfxPoolItem* pItem : aSurrogates) { auto pRubyItem = dynamic_cast(pItem); if ( pRubyItem && pRubyItem->GetTextRuby() ) diff --git a/sw/source/core/view/vprint.cxx b/sw/source/core/view/vprint.cxx index 008e2e1ce1bc..c26e5b9aff20 100644 --- a/sw/source/core/view/vprint.cxx +++ b/sw/source/core/view/vprint.cxx @@ -599,7 +599,9 @@ void SwViewShell::PrtOle2( SwDoc *pDoc, const SwViewOption *pOpt, const SwPrintD /// Check if the DocNodesArray contains fields. bool SwViewShell::IsAnyFieldInDoc() const { - for (const SfxPoolItem* pItem : mxDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD)) + ItemSurrogates aSurrogates; + mxDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_FIELD); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFormatField = dynamic_cast(pItem); if(pFormatField) @@ -612,7 +614,8 @@ bool SwViewShell::IsAnyFieldInDoc() const } } - for (const SfxPoolItem* pItem : mxDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INPUTFIELD)) + mxDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_INPUTFIELD); + for (const SfxPoolItem* pItem : aSurrogates) { const SwFormatField* pFormatField = dynamic_cast(pItem); if(pFormatField) diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx index ef3e4b19c35b..90b59d4c090b 100644 --- a/sw/source/filter/html/htmlflywriter.cxx +++ b/sw/source/filter/html/htmlflywriter.cxx @@ -2218,7 +2218,9 @@ void SwHTMLWriter::CollectLinkTargets() { const SwTextINetFormat* pTextAttr; - for (const SfxPoolItem* pItem : m_pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT)) + ItemSurrogates aSurrogates; + m_pDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_INETFMT); + for (const SfxPoolItem* pItem : aSurrogates) { auto pINetFormat = dynamic_cast(pItem); const SwTextNode* pTextNd; @@ -2232,7 +2234,8 @@ void SwHTMLWriter::CollectLinkTargets() } } - for (const SfxPoolItem* pItem : m_pDoc->GetAttrPool().GetItemSurrogates(RES_URL)) + m_pDoc->GetAttrPool().GetItemSurrogates(aSurrogates, RES_URL); + for (const SfxPoolItem* pItem : aSurrogates) { auto pURL = dynamic_cast(pItem); if( pURL ) diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx index b5671f5f92aa..043baa06782b 100644 --- a/sw/source/filter/writer/writer.cxx +++ b/sw/source/filter/writer/writer.cxx @@ -45,12 +45,12 @@ struct Writer_Impl SvStream * m_pStream; std::map maFileNameMap; - std::vector aFontRemoveLst; + std::vector aFontRemoveLst; SwBookmarkNodeTable aBkmkNodePos; Writer_Impl(); - void RemoveFontList( SwDoc& rDoc ); + void RemoveFontList(); void InsertBkmk( const ::sw::mark::IMark& rBkmk ); }; @@ -59,12 +59,9 @@ Writer_Impl::Writer_Impl() { } -void Writer_Impl::RemoveFontList( SwDoc& rDoc ) +void Writer_Impl::RemoveFontList() { - for( const auto& rpFontItem : aFontRemoveLst ) - { - rDoc.GetAttrPool().DirectRemoveItemFromPool( *rpFontItem ); - } + aFontRemoveLst.clear(); } void Writer_Impl::InsertBkmk(const ::sw::mark::IMark& rBkmk) @@ -119,7 +116,7 @@ const IDocumentStylePoolAccess& Writer::getIDocumentStylePoolAccess() const { re void Writer::ResetWriter() { - m_pImpl->RemoveFontList( *m_pDoc ); + m_pImpl->RemoveFontList(); m_pImpl.reset(new Writer_Impl); if( m_pCurrentPam ) @@ -372,28 +369,28 @@ void Writer::AddFontItems_( SfxItemPool& rPool, sal_uInt16 nW ) if( nullptr != pFont ) AddFontItem( rPool, *pFont ); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nW)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, nW); + for (const SfxPoolItem* pItem : aSurrogates) AddFontItem( rPool, *static_cast(pItem) ); } void Writer::AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont ) { - const SvxFontItem* pItem; + SfxPoolItemHolder aItem; if( RES_CHRATR_FONT != rFont.Which() ) { SvxFontItem aFont( rFont ); aFont.SetWhich( RES_CHRATR_FONT ); - pItem = &rPool.DirectPutItemInPool( aFont ); - assert(pItem != &aFont && "Pointer to local outside scope (pushed to aFontRemoveLst)"); + aItem = SfxPoolItemHolder(rPool, &aFont); + assert(aItem.getItem() != &aFont && "Pointer to local outside scope (pushed to aFontRemoveLst)"); } else - pItem = &rPool.DirectPutItemInPool( rFont ); + aItem = SfxPoolItemHolder(rPool, &rFont); - if( 1 < pItem->GetRefCount() ) - rPool.DirectRemoveItemFromPool( *pItem ); - else + if(1 == aItem.getItem()->GetRefCount()) { - m_pImpl->aFontRemoveLst.push_back( pItem ); + m_pImpl->aFontRemoveLst.push_back(aItem); } } diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx index 6063eb343248..09b16b6f8344 100644 --- a/sw/source/filter/ww8/rtfexport.cxx +++ b/sw/source/filter/ww8/rtfexport.cxx @@ -1252,6 +1252,7 @@ void RtfExport::OutColorTable() InsColor(COL_BROWN); InsColor(COL_GRAY); InsColor(COL_LIGHTGRAY); + ItemSurrogates aSurrogates; // char color { @@ -1260,7 +1261,8 @@ void RtfExport::OutColorTable() pCol = rPool.GetPoolDefaultItem(RES_CHRATR_COLOR); if (pCol) InsColor(pCol->GetValue()); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_COLOR)) + rPool.GetItemSurrogates(aSurrogates, RES_CHRATR_COLOR); + for (const SfxPoolItem* pItem : aSurrogates) { pCol = dynamic_cast(pItem); if (pCol) @@ -1269,7 +1271,8 @@ void RtfExport::OutColorTable() auto pUnder = GetDfltAttr(RES_CHRATR_UNDERLINE); InsColor(pUnder->GetColor()); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_UNDERLINE)) + rPool.GetItemSurrogates(aSurrogates, RES_CHRATR_UNDERLINE); + for (const SfxPoolItem* pItem : aSurrogates) { pUnder = dynamic_cast(pItem); if (pUnder) @@ -1278,7 +1281,8 @@ void RtfExport::OutColorTable() auto pOver = GetDfltAttr(RES_CHRATR_OVERLINE); InsColor(pOver->GetColor()); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_OVERLINE)) + rPool.GetItemSurrogates(aSurrogates, RES_CHRATR_OVERLINE); + for (const SfxPoolItem* pItem : aSurrogates) { pOver = dynamic_cast(pItem); if (pOver) @@ -1298,7 +1302,8 @@ void RtfExport::OutColorTable() { InsColor(pBackground->GetColor()); } - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(*pIds)) + rPool.GetItemSurrogates(aSurrogates, *pIds); + for (const SfxPoolItem* pItem : aSurrogates) { pBackground = static_cast(pItem); if (pBackground) @@ -1317,7 +1322,8 @@ void RtfExport::OutColorTable() { InsColor(pShadow->GetColor()); } - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_SHADOW)) + rPool.GetItemSurrogates(aSurrogates, RES_SHADOW); + for (const SfxPoolItem* pItem : aSurrogates) { pShadow = dynamic_cast(pItem); if (pShadow) @@ -1332,7 +1338,8 @@ void RtfExport::OutColorTable() const SvxBoxItem* pBox = rPool.GetPoolDefaultItem(RES_BOX); if (nullptr != pBox) InsColorLine(*pBox); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_BOX)) + rPool.GetItemSurrogates(aSurrogates, RES_BOX); + for (const SfxPoolItem* pItem : aSurrogates) { pBox = dynamic_cast(pItem); if (pBox) @@ -1344,7 +1351,8 @@ void RtfExport::OutColorTable() const SvxBoxItem* pCharBox = rPool.GetPoolDefaultItem(RES_CHRATR_BOX); if (pCharBox) InsColorLine(*pCharBox); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_BOX)) + rPool.GetItemSurrogates(aSurrogates, RES_CHRATR_BOX); + for (const SfxPoolItem* pItem : aSurrogates) { pCharBox = dynamic_cast(pItem); if (pCharBox) @@ -1353,7 +1361,8 @@ void RtfExport::OutColorTable() } // TextFrame or paragraph background solid fill. - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(XATTR_FILLCOLOR)) + rPool.GetItemSurrogates(aSurrogates, XATTR_FILLCOLOR); + for (const SfxPoolItem* pItem : aSurrogates) { if (auto pColorItem = dynamic_cast(pItem)) InsColor(pColorItem->GetColorValue()); diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index 9ee7b7532d13..3c8b29aa1a37 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -938,7 +938,9 @@ void wwFontHelper::InitFontTable(const SwDoc& rDoc) const sal_uInt16 aTypes[] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT, 0 }; for (const sal_uInt16* pId = aTypes; *pId; ++pId) { - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(*pId)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, *pId); + for (const SfxPoolItem* pItem : aSurrogates) { pFont = static_cast(pItem); GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(), diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 170d4bd497c1..1bd86a382f31 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -3342,7 +3342,9 @@ void MSWordExportBase::AddLinkTarget(std::u16string_view rURL) void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc) { - for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT)) + ItemSurrogates aSurrogates; + rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_INETFMT); + for (const SfxPoolItem* pItem : aSurrogates) { auto pINetFormat = dynamic_cast(pItem); if (!pINetFormat) @@ -3362,7 +3364,8 @@ void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc) AddLinkTarget( pINetFormat->GetValue() ); } - for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(RES_URL)) + rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_URL); + for (const SfxPoolItem* pItem : aSurrogates) { auto pURL = dynamic_cast(pItem); if (!pURL) diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx index 434eb8c07312..5523b40cce78 100644 --- a/sw/source/filter/xml/xmlexp.cxx +++ b/sw/source/filter/xml/xmlexp.cxx @@ -149,7 +149,9 @@ ErrCode SwXMLExport::exportDoc( enum XMLTokenEnum eClass ) for( int j=0; j < nWhichIds; ++j ) { const sal_uInt16 nWhichId = aWhichIds[j]; - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, nWhichId); + for (const SfxPoolItem* pItem : aSurrogates) { auto pUnknown = dynamic_cast( pItem ); OSL_ENSURE( pUnknown, "illegal attribute container item" ); diff --git a/sw/source/filter/xml/xmlfonte.cxx b/sw/source/filter/xml/xmlfonte.cxx index c6a9c89cb6ca..5aefd4b751e4 100644 --- a/sw/source/filter/xml/xmlfonte.cxx +++ b/sw/source/filter/xml/xmlfonte.cxx @@ -70,7 +70,9 @@ SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& _rExport, const SvxFontItem& rFont = static_cast(rPool.GetDefaultItem( nWhichId )); aFonts.push_back(&rFont); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId)) + ItemSurrogates aSurrogates; + rPool.GetItemSurrogates(aSurrogates, nWhichId); + for (const SfxPoolItem* pItem : aSurrogates) { auto pFont = static_cast(pItem); aFonts.push_back(pFont); diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index c927a75e952f..831642462675 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -5554,8 +5554,9 @@ void SwContentTree::EditEntry(const weld::TreeIter& rEntry, EditEntryMode nMode) if(nMode == EditEntryMode::DELETE) { const OUString& rName = pCnt->GetName(); - for (const SfxPoolItem* pItem : - m_pActiveShell->GetDoc()->GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)) + ItemSurrogates aSurrogates; + m_pActiveShell->GetDoc()->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); + for (const SfxPoolItem* pItem : aSurrogates) { assert(dynamic_cast(pItem)); const auto pFormatRefMark = static_cast(pItem); @@ -6230,8 +6231,9 @@ void SwContentTree::BringEntryToAttention(const weld::TreeIter& rEntry) else if (nType == ContentTypeId::REFERENCE) { std::vector aTextAttrArr; - for (const SfxPoolItem* pItem : - m_pActiveShell->GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)) + ItemSurrogates aSurrogates; + m_pActiveShell->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); + for (const SfxPoolItem* pItem : aSurrogates) { if (const auto pRefMark = dynamic_cast(pItem)) { diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx index bda9559036a5..b1685450a5d8 100644 --- a/vcl/win/gdi/gdiimpl.cxx +++ b/vcl/win/gdi/gdiimpl.cxx @@ -1267,8 +1267,6 @@ void WinSalGraphicsImpl::setClipRegion( const vcl::Region& i_rClip ) // debug code if you want to check range of the newly applied ClipRegion //RECT aBound; //const int aRegionType = GetRgnBox(mrParent.mhRegion, &aBound); - - //bool bBla = true; } else {