summaryrefslogtreecommitdiff
path: root/svl/source/items/itemset.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svl/source/items/itemset.cxx')
-rw-r--r--svl/source/items/itemset.cxx1155
1 files changed, 345 insertions, 810 deletions
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 4b1207a697aa..334fe60e2a70 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -263,14 +263,15 @@ bool SfxPoolItemHolder::operator==(const SfxPoolItemHolder &rHolder) const
* contain any Items with SlotIds as Which values.
*/
SfxItemSet::SfxItemSet(SfxItemPool& rPool)
- : m_pPool(&rPool)
- , m_pParent(nullptr)
- , m_nCount(0)
- , m_nRegister(0)
- , m_bItemsFixed(false)
- , m_ppItems(new const SfxPoolItem*[rPool.GetMergedIdRanges().TotalCount()]{})
- , m_aWhichRanges(rPool.GetMergedIdRanges())
- , m_aCallback()
+: m_pPool(&rPool)
+, m_pParent(nullptr)
+, m_nRegister(0)
+#ifdef DBG_UTIL
+, m_nRegisteredSfxItemIter(0)
+#endif
+, m_aWhichRanges(rPool.GetMergedIdRanges())
+, m_aPoolItemMap()
+, m_aCallback()
{
#ifdef DBG_UTIL
nAllocatedSfxItemSetCount++;
@@ -279,96 +280,99 @@ SfxItemSet::SfxItemSet(SfxItemPool& rPool)
assert(m_aWhichRanges.validRanges2());
}
-SfxItemSet::SfxItemSet( SfxItemPool& rPool, SfxAllItemSetFlag )
- : m_pPool(&rPool)
- , m_pParent(nullptr)
- , m_nCount(0)
- , m_nRegister(0)
- , m_bItemsFixed(false)
- , m_ppItems(nullptr)
- , m_aWhichRanges()
- , m_aCallback()
-{
+SfxItemSet::SfxItemSet(SfxItemPool& pool, WhichRangesContainer wids)
+: m_pPool(&pool)
+, m_pParent(nullptr)
+, m_nRegister(0)
#ifdef DBG_UTIL
- nAllocatedSfxItemSetCount++;
- nUsedSfxItemSetCount++;
+, m_nRegisteredSfxItemIter(0)
#endif
-}
-
-/** special constructor for SfxItemSetFixed */
-SfxItemSet::SfxItemSet( SfxItemPool& rPool, WhichRangesContainer&& ranges, SfxPoolItem const ** ppItems)//, sal_uInt16 nTotalCount )
- : m_pPool(&rPool)
- , m_pParent(nullptr)
- , m_nCount(0)
- , m_nRegister(0)
- , m_bItemsFixed(true)
- , m_ppItems(ppItems)
- , m_aWhichRanges(std::move(ranges))
- , m_aCallback()
+, m_aWhichRanges(std::move(wids))
+, m_aPoolItemMap()
+, m_aCallback()
{
#ifdef DBG_UTIL
nAllocatedSfxItemSetCount++;
nUsedSfxItemSetCount++;
#endif
- assert(ppItems);
- assert(m_aWhichRanges.size() > 0);
+ assert(m_aWhichRanges.TotalCount() != 0);
assert(m_aWhichRanges.validRanges2());
}
-/** special constructor for SfxItemSetFixed copy constructor */
-SfxItemSet::SfxItemSet( const SfxItemSet& rOther,
- SfxPoolItem const ** ppMyItems )
- : m_pPool(rOther.m_pPool)
- , m_pParent(rOther.m_pParent)
- , m_nCount(rOther.m_nCount)
- , m_nRegister(rOther.m_nRegister)
- , m_bItemsFixed(true)
- , m_ppItems(ppMyItems)
- , m_aWhichRanges(rOther.m_aWhichRanges)
- , m_aCallback(rOther.m_aCallback)
+SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
+: m_pPool( rASet.m_pPool )
+, m_pParent( rASet.m_pParent )
+, m_nRegister( rASet.m_nRegister )
+#ifdef DBG_UTIL
+, m_nRegisteredSfxItemIter(0)
+#endif
+, m_aWhichRanges( rASet.m_aWhichRanges )
+, m_aPoolItemMap()
+, m_aCallback(rASet.m_aCallback)
{
#ifdef DBG_UTIL
nAllocatedSfxItemSetCount++;
nUsedSfxItemSetCount++;
#endif
- assert(ppMyItems);
- assert(m_aWhichRanges.size() > 0);
- assert(m_aWhichRanges.validRanges2());
-
- if (0 == rOther.Count())
+ if (rASet.GetRanges().empty())
return;
- // Copy attributes
- SfxPoolItem const** ppDst(m_ppItems);
-
- for (const auto& rSource : rOther)
- {
- *ppDst = implCreateItemEntry(*GetPool(), rSource, false);
- ppDst++;
- }
+ for (const auto& rSource : rASet.m_aPoolItemMap)
+ m_aPoolItemMap[rSource.first] = implCreateItemEntry(*GetPool(), rSource.second, false);
+ assert(m_aWhichRanges.validRanges2());
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_bItemsFixed(false)
- , m_ppItems(new const SfxPoolItem*[wids.TotalCount()]{})
- , m_aWhichRanges(std::move(wids))
- , m_aCallback()
+SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept
+: m_pPool( rASet.m_pPool )
+, m_pParent( rASet.m_pParent )
+, m_nRegister( rASet.m_nRegister )
+#ifdef DBG_UTIL
+, m_nRegisteredSfxItemIter(0)
+#endif
+, m_aWhichRanges( std::move(rASet.m_aWhichRanges) )
+, m_aPoolItemMap( std::move(rASet.m_aPoolItemMap) )
+, m_aCallback(rASet.m_aCallback)
{
#ifdef DBG_UTIL
nAllocatedSfxItemSetCount++;
nUsedSfxItemSetCount++;
+ assert(0 == rASet.m_nRegisteredSfxItemIter && "ITEM: SfxItemSet MOVE constructor with active SfxItemIters (!)");
#endif
- assert(m_aWhichRanges.TotalCount() != 0);
+ // 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_nRegister = 0;
+ rASet.m_aWhichRanges.reset();
+ rASet.m_aCallback = nullptr;
+
assert(m_aWhichRanges.validRanges2());
}
+SfxItemSet::~SfxItemSet()
+{
+#ifdef DBG_UTIL
+ nAllocatedSfxItemSetCount--;
+ addArrayUsage(Count(), TotalCount());
+#endif
+ // cleanup items. No std::fill needed, we are done with this ItemSet.
+ // the callback is not set in destructor, so no worries about that
+ ClearAllItemsImpl();
+
+ // for invariant-testing
+ m_aWhichRanges.reset();
+}
+
// Class that implements global Item sharing. It uses rtti to
// associate every Item-derivation with a possible incarnation
// of a DefaultItemInstanceManager. This is the default, it will
@@ -532,16 +536,6 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pS
// just use/return nullptr
return nullptr;
- // if (IsInvalidItem(pSource))
- // // SfxItemState::INVALID aka INVALID_POOL_ITEM
- // // just use pSource which equals INVALID_POOL_ITEM
- // return pSource;
-
- // if (IsDisabledItem(pSource))
- // // SfxItemState::DISABLED aka DISABLED_POOL_ITEM
- // // just use pSource which equals DISABLED_POOL_ITEM
- // return pSource;
-
if (pSource->isStaticDefault())
// static default Items can just be used without RefCounting
// NOTE: This now includes IsInvalidItem/IsDisabledItem
@@ -595,46 +589,6 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pS
SfxItemPool* pMasterPool(rPool.GetMasterPool());
assert(nullptr != pMasterPool);
- // // 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->GetPoolDefaultItem(pSource->Which()));
- // 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 DynamicDefault (!)");
- // const SfxPoolItem* pDynamic(pTargetPool->GetUserDefaultItem(pSource->Which()));
- // if (nullptr != pDynamic)
- // {
- // if (SfxPoolItem::areSame(pSource, pDynamic))
- // pSource = pDynamic;
- // else
- // {
- // pSource = pSource->Clone(pMasterPool);
- // bPassingOwnership = true;
- // }
- // }
- // }
-
// The Item itself is shareable when it is used/added at an instance
// that RefCounts the Item, SfxItemPool or SfxPoolItemHolder. Try
// to share items that are already shared
@@ -721,22 +675,12 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pS
return pSource;
}
-void implCleanupItemEntry(SfxPoolItem const* pSource)
+void implCleanupItemEntry(const SfxPoolItem* pSource)
{
if (nullptr == pSource)
// no entry, done
return;
- // if (IsInvalidItem(pSource))
- // // SfxItemState::INVALID aka INVALID_POOL_ITEM
- // // nothing to do for invalid item entries
- // return;
-
- // if (IsDisabledItem(pSource))
- // // SfxItemState::INVALID aka DISABLED_POOL_ITEM
- // // nothing to do for disabled item entries
- // return;
-
if (pSource->isStaticDefault())
// static default Items can just be used without RefCounting
// NOTE: This now includes IsInvalidItem/IsDisabledItem
@@ -788,140 +732,52 @@ void implCleanupItemEntry(SfxPoolItem const* pSource)
delete pSource;
}
-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_bItemsFixed(false)
- , m_ppItems(nullptr)
- , m_aWhichRanges( rASet.m_aWhichRanges )
- , m_aCallback(rASet.m_aCallback)
+// Delete single Items or all Items (nWhich == 0)
+sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
{
-#ifdef DBG_UTIL
- nAllocatedSfxItemSetCount++;
- nUsedSfxItemSetCount++;
-#endif
- if (rASet.GetRanges().empty())
- return;
-
- if (0 == rASet.Count())
- {
- // no Items set in source ItemSet, allocate new array
- // *plus* init to nullptr
- m_ppItems = new const SfxPoolItem* [TotalCount()]{};
- return;
- }
-
- // allocate new array (no need to initialize, will be done below)
- m_ppItems = new const SfxPoolItem* [TotalCount()];
-
- // Copy attributes
- SfxPoolItem const** ppDst(m_ppItems);
+ if( !Count() )
+ return 0;
- for (const auto& rSource : rASet)
- {
- *ppDst = implCreateItemEntry(*GetPool(), rSource, false);
- ppDst++;
- }
+ if( nWhich )
+ return ClearSingleItem_ForWhichID(nWhich);
- assert(m_aWhichRanges.validRanges2());
- if (0 != m_nRegister)
- GetPool()->registerItemSet(*this);
+ // clear all & reset to nullptr
+ return ClearAllItemsImpl();
}
-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_bItemsFixed(false)
- , m_ppItems( rASet.m_ppItems )
- , m_aWhichRanges( std::move(rASet.m_aWhichRanges) )
- , m_aCallback(rASet.m_aCallback)
+sal_uInt16 SfxItemSet::ClearSingleItem_ForWhichID( sal_uInt16 nWhich )
{
-#ifdef DBG_UTIL
- nAllocatedSfxItemSetCount++;
- nUsedSfxItemSetCount++;
-#endif
- if (rASet.m_bItemsFixed)
- {
- // have to make a copy
- m_ppItems = new const SfxPoolItem* [TotalCount()];
+ PoolItemMap::iterator aHit(m_aPoolItemMap.find(nWhich));
- // 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).
- std::copy(rASet.m_ppItems, rASet.m_ppItems + TotalCount(), m_ppItems);
- }
-
- // 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_ppItems = nullptr;
- rASet.m_aWhichRanges.reset();
- rASet.m_aCallback = nullptr;
-
- assert(m_aWhichRanges.validRanges2());
-}
+ if (aHit == m_aPoolItemMap.end())
+ return 0;
-SfxItemSet::~SfxItemSet()
-{
#ifdef DBG_UTIL
- nAllocatedSfxItemSetCount--;
- addArrayUsage(Count(), TotalCount());
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet ClearItem with active SfxItemIters (!)");
#endif
- // cleanup items. No std::fill needed, we are done with this ItemSet.
- // the callback is not set in destructor, so no worries about that
- ClearAllItemsImpl();
-
- if (!m_bItemsFixed)
- {
- // free SfxPoolItem array
- delete[] m_ppItems;
- }
-
- // for invariant-testing
- m_aWhichRanges.reset();
-}
-// Delete single Items or all Items (nWhich == 0)
-sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
-{
- if( !Count() )
- return 0;
-
- if( nWhich )
- return ClearSingleItem_ForWhichID(nWhich);
+ ClearSingleItem_PrepareRemove(aHit->second);
+ m_aPoolItemMap.erase(aHit);
- // clear all & reset to nullptr
- const sal_uInt16 nRetval(ClearAllItemsImpl());
- std::fill(begin(), begin() + TotalCount(), nullptr);
- return nRetval;
+ return 1;
}
-sal_uInt16 SfxItemSet::ClearSingleItem_ForWhichID( sal_uInt16 nWhich )
+void SfxItemSet::ClearSingleItem_PrepareRemove(const SfxPoolItem* pItem)
{
- const sal_uInt16 nOffset(GetRanges().getOffsetFromWhich(nWhich));
+ if (nullptr == pItem)
+ return;
- if (INVALID_WHICHPAIR_OFFSET != nOffset)
+ // Notification-Callback
+ if(m_aCallback)
{
- // found, continue with offset
- return ClearSingleItem_ForOffset(nOffset);
+ m_aCallback(pItem, nullptr);
}
- // not found, return sal_uInt16 nDel = 0;
- return 0;
+ // check register for remove
+ checkRemovePoolRegistration(pItem);
+
+ // cleanup item & reset ptr
+ implCleanupItemEntry(pItem);
}
void SfxItemSet::checkRemovePoolRegistration(const SfxPoolItem* pItem)
@@ -971,10 +827,6 @@ void SfxItemSet::checkAddPoolRegistration(const SfxPoolItem* pItem)
// 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 NeedsSurrogateSupport exist
if (0 == m_nRegister)
GetPool()->registerItemSet(*this);
@@ -983,55 +835,23 @@ void SfxItemSet::checkAddPoolRegistration(const SfxPoolItem* pItem)
m_nRegister++;
}
-sal_uInt16 SfxItemSet::ClearSingleItem_ForOffset( sal_uInt16 nOffset )
-{
- assert(nOffset < TotalCount());
- const_iterator aEntry(begin() + nOffset);
- assert(nullptr == *aEntry || IsInvalidItem(*aEntry) || IsDisabledItem(*aEntry) || 0 != (*aEntry)->Which());
-
- if (nullptr == *aEntry)
- // no entry, done
- return 0;
-
- // we reset an entry to nullptr -> decrement count
- --m_nCount;
-
- // Notification-Callback
- if(m_aCallback)
- {
- m_aCallback(*aEntry, nullptr);
- }
-
- // check register for remove
- checkRemovePoolRegistration(*aEntry);
-
- // cleanup item & reset ptr
- implCleanupItemEntry(*aEntry);
- *aEntry = nullptr;
-
- return 1;
-}
-
sal_uInt16 SfxItemSet::ClearAllItemsImpl()
{
if (0 == Count())
// no items set, done
return 0;
- // loop & cleanup items
- for (auto& rCandidate : *this)
- {
- if (nullptr != rCandidate && m_aCallback)
- {
- m_aCallback(rCandidate, nullptr);
- }
+#ifdef DBG_UTIL
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet ClearAllItems with active SfxItemIters (!)");
+#endif
- implCleanupItemEntry(rCandidate);
- }
+ // loop & cleanup items
+ for (const auto& rCandidate : m_aPoolItemMap)
+ ClearSingleItem_PrepareRemove(rCandidate.second);
// remember count before resetting it, that is the retval
const sal_uInt16 nRetval(Count());
- m_nCount = 0;
+ m_aPoolItemMap.clear();
if (0 != m_nRegister)
{
@@ -1049,24 +869,46 @@ void SfxItemSet::ClearInvalidItems()
return;
// loop, here using const_iterator due to need to set ptr in m_ppItems array
- for (const_iterator candidate(begin()); candidate != end(); candidate++)
+ for (PoolItemMap::iterator aCandidate(m_aPoolItemMap.begin()); aCandidate != m_aPoolItemMap.end();)
{
- if (IsInvalidItem(*candidate))
+ if (IsInvalidItem(aCandidate->second))
{
- *candidate = nullptr;
- --m_nCount;
+#ifdef DBG_UTIL
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet ClearInvalidItems with active SfxItemIters (!)");
+#endif
+ aCandidate = m_aPoolItemMap.erase(aCandidate);
}
+ else
+ aCandidate++;
}
}
SfxItemState SfxItemSet::GetItemState_ForWhichID( SfxItemState eState, sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem) const
{
- const sal_uInt16 nOffset(GetRanges().getOffsetFromWhich(nWhich));
+ PoolItemMap::const_iterator aHit(m_aPoolItemMap.find(nWhich));
+
+ if (aHit != m_aPoolItemMap.end())
+ {
+ if (IsInvalidItem(aHit->second))
+ // Different ones are present
+ return SfxItemState::INVALID;
+
+ if (IsDisabledItem(aHit->second))
+ // Item is Disabled
+ return SfxItemState::DISABLED;
+
+ // if we have the Item, add it to output an hand back
+ if (nullptr != ppItem)
+ *ppItem = aHit->second;
+
+ // Item is set
+ return SfxItemState::SET;
+ }
- if (INVALID_WHICHPAIR_OFFSET != nOffset)
+ if (GetRanges().doesContainWhich(nWhich))
{
- // found, continue with offset
- eState = GetItemState_ForOffset(nOffset, ppItem);
+ // set to Default
+ eState = SfxItemState::DEFAULT;
}
// search in parent?
@@ -1080,33 +922,6 @@ SfxItemState SfxItemSet::GetItemState_ForWhichID( SfxItemState eState, sal_uInt1
return eState;
}
-SfxItemState SfxItemSet::GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPoolItem **ppItem) const
-{
- // check and assert from invalid offset. The caller is responsible for
- // ensuring a valid offset (see callers, all checked & safe)
- assert(nOffset < TotalCount());
- SfxPoolItem const* pCandidate(*(begin() + nOffset));
-
- if (nullptr == pCandidate)
- // set to Default
- return SfxItemState::DEFAULT;
-
- if (IsInvalidItem(pCandidate))
- // Different ones are present
- return SfxItemState::INVALID;
-
- if (IsDisabledItem(pCandidate))
- // Item is Disabled
- return SfxItemState::DISABLED;
-
- if (nullptr != ppItem)
- // if we have the Item, add it to output an hand back
- *ppItem = pCandidate;
-
- // Item is set
- return SfxItemState::SET;
-}
-
bool SfxItemSet::HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem) const
{
const bool bRet(SfxItemState::SET == GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWhich, true, ppItem));
@@ -1154,59 +969,59 @@ const SfxPoolItem* SfxItemSet::PutImpl(const SfxPoolItem& rItem, bool bPassingOw
return nullptr;
}
-#ifdef _WIN32
- // Win build *insists* for initialization, triggers warning C4701:
- // "potentially uninitialized local variable 'aEntry' used" for
- // lines below. This is not the case here, but I know of no way
- // to silence the warning in another way
- const_iterator aEntry(begin());
-#else
- const_iterator aEntry;
-#endif
+ const sal_uInt16 nWhich(rItem.Which());
- sal_uInt16 nOffset(GetRanges().getOffsetFromWhich(rItem.Which()));
- bool bActionNeeded(INVALID_WHICHPAIR_OFFSET != nOffset);
+ if (!GetRanges().doesContainWhich(nWhich))
+ {
+ // no action needed: not in WhichRange
+ if (bPassingOwnership)
+ delete &rItem;
+ return nullptr;
+ }
+
+ const SfxPoolItem* pEntry(nullptr);
+ PoolItemMap::iterator aHit(m_aPoolItemMap.find(nWhich));
- if (bActionNeeded)
+ if (aHit != m_aPoolItemMap.end())
{
- aEntry = begin() + nOffset;
+ // compare items, evtl. containing content compare
+ pEntry = aHit->second;
- if (nullptr == *aEntry)
- {
- // increase count if there was no entry before
- ++m_nCount;
- }
- else
+ if (SfxPoolItem::areSame(*pEntry, rItem))
{
- // compare items, evtl. containing content compare
- bActionNeeded = !SfxPoolItem::areSame(**aEntry, rItem);
+ // no action needed: identical item already in place
+ if (bPassingOwnership)
+ delete &rItem;
+ return nullptr;
}
}
- if (!bActionNeeded)
- {
- if (bPassingOwnership)
- delete &rItem;
- return nullptr;
- }
-
// prepare new entry
const SfxPoolItem* pNew(implCreateItemEntry(*GetPool(), &rItem, bPassingOwnership));
// Notification-Callback
if(m_aCallback)
{
- m_aCallback(*aEntry, pNew);
+ m_aCallback(pEntry, 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);
+ checkRemovePoolRegistration(pEntry);
// cleanup old entry & set entry at m_ppItems array
- implCleanupItemEntry(*aEntry);
- *aEntry = pNew;
+ implCleanupItemEntry(pEntry);
+
+ if (pEntry)
+ aHit->second = pNew;
+ else
+ {
+#ifdef DBG_UTIL
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet PutImpl with active SfxItemIters (!)");
+#endif
+ m_aPoolItemMap[nWhich] = pNew;
+ }
return pNew;
}
@@ -1217,42 +1032,25 @@ bool SfxItemSet::Put(const SfxItemSet& rSource, bool bInvalidAsDefault)
// no items in source, done
return false;
- const_iterator aSource(rSource.begin());
- sal_uInt16 nNumberToGo(rSource.Count());
bool bRetval(false);
- // iterate based on WhichIDs to have it available for evtl. PutImpl calls
- for (const WhichPair& rPair : rSource.GetRanges())
+ for (PoolItemMap::const_iterator aCandidate(rSource.m_aPoolItemMap.begin()); aCandidate != rSource.m_aPoolItemMap.end(); aCandidate++)
{
- for (sal_uInt16 nWhich(rPair.first); nWhich <= rPair.second; nWhich++, aSource++)
+ if (IsInvalidItem(aCandidate->second))
{
- if (nullptr != *aSource)
+ if (bInvalidAsDefault)
{
- nNumberToGo--;
-
- if (IsInvalidItem(*aSource))
- {
- if (bInvalidAsDefault)
- {
- bRetval |= 0 != ClearSingleItem_ForWhichID(nWhich);
- }
- else
- {
- DisableOrInvalidateItem_ForWhichID(false, nWhich);
- }
- }
- else
- {
- bRetval |= nullptr != PutImpl(**aSource, false);
- }
+ bRetval |= 0 != ClearSingleItem_ForWhichID(aCandidate->first);
}
-
- if (0 == nNumberToGo)
+ else
{
- // we can return early if all set Items are handled
- return bRetval;
+ DisableOrInvalidateItem_ForWhichID(false, aCandidate->first);
}
}
+ else
+ {
+ bRetval |= nullptr != PutImpl(*aCandidate->second, false);
+ }
}
return bRetval;
@@ -1281,15 +1079,15 @@ void SfxItemSet::PutExtended
)
{
// don't "optimize" with "if( rSource.Count()" because of dontcare + defaults
- const_iterator aSource(rSource.begin());
-
for (const WhichPair& rPair : rSource.GetRanges())
{
- for (sal_uInt16 nWhich = rPair.first; nWhich <= rPair.second; nWhich++, aSource++)
+ for (sal_uInt16 nWhich = rPair.first; nWhich <= rPair.second; nWhich++)
{
- if (nullptr != *aSource)
+ PoolItemMap::const_iterator aHit(rSource.m_aPoolItemMap.find(nWhich));
+
+ if (aHit != rSource.m_aPoolItemMap.end())
{
- if (IsInvalidItem(*aSource))
+ if (IsInvalidItem(aHit->second))
{
// Item is DontCare:
switch (eDontCareAs)
@@ -1313,7 +1111,7 @@ void SfxItemSet::PutExtended
else
{
// Item is set:
- PutImpl(**aSource, false);
+ PutImpl(*aHit->second, false);
}
}
else
@@ -1355,7 +1153,7 @@ void SfxItemSet::MergeRange( sal_uInt16 nFrom, sal_uInt16 nTo )
bool bAllIncluded(!GetRanges().empty());
for (sal_uInt16 a(nFrom); bAllIncluded && a <= nTo; a++)
- if (INVALID_WHICHPAIR_OFFSET == GetRanges().getOffsetFromWhich(a))
+ if (!GetRanges().doesContainWhich(a))
bAllIncluded = false;
// if yes, we are done
@@ -1396,72 +1194,25 @@ void SfxItemSet::SetRanges( WhichRangesContainer&& aNewRanges )
void SfxItemSet::RecreateRanges_Impl(const WhichRangesContainer& rNewRanges)
{
- // create new item-array (by iterating through all new ranges)
- const sal_uInt16 nNewTotalCount(rNewRanges.TotalCount());
- SfxPoolItem const** aNewItemArray(new const SfxPoolItem* [nNewTotalCount]);
- sal_uInt16 nNewCount(0);
-
if (0 == Count())
- {
- // no Items set, just reset to nullptr (default)
- std::fill(aNewItemArray, aNewItemArray + nNewTotalCount, nullptr);
- }
- else
- {
- // iterate over target - all entries there need to be set/initialized. Use
- // WhichIDs, we need to access two different WhichRanges
- const_iterator aNewTarget(aNewItemArray);
-
- for (auto const & rNewRange : rNewRanges)
- {
- for (sal_uInt16 nWhich(rNewRange.first); nWhich <= rNewRange.second; nWhich++, aNewTarget++)
- {
- // check if we have that WhichID in source ranges
- const sal_uInt16 nSourceOffset(GetRanges().getOffsetFromWhich(nWhich));
-
- if (INVALID_WHICHPAIR_OFFSET == nSourceOffset)
- {
- // no entry in source, init to nullptr
- *aNewTarget = nullptr;
- }
- else
- {
- // we have entry in source, transfer entry - whatever it may be,
- // also for nullptr (for initialization)
- const_iterator aSourceEntry(begin() + nSourceOffset);
- *aNewTarget = *aSourceEntry;
-
- // take care of new Count
- if (nullptr != *aNewTarget)
- {
- nNewCount++;
- }
-
- // reset entry, since it got transferred it should not be cleaned-up
- *aSourceEntry = nullptr;
- }
- }
- }
+ // no existing items, done
+ return;
- // free old items: only necessary when not all Items were transferred
- if (nNewCount != Count())
+ // check if existing items are in the new ItemRanges.
+ // if they are not, remove the item
+ for (PoolItemMap::iterator aCandidate(m_aPoolItemMap.begin()); aCandidate != m_aPoolItemMap.end();)
+ {
+ if (!rNewRanges.doesContainWhich(aCandidate->first))
{
- ClearAllItemsImpl();
+#ifdef DBG_UTIL
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet RecreateRanges with active SfxItemIters (!)");
+#endif
+ ClearSingleItem_PrepareRemove(aCandidate->second);
+ aCandidate = m_aPoolItemMap.erase(aCandidate);
}
+ else
+ aCandidate++;
}
-
- // replace old items-array and ranges
- if (m_bItemsFixed)
- {
- m_bItemsFixed = false;
- }
- else
- {
- delete[] m_ppItems;
- }
-
- m_ppItems = aNewItemArray;
- m_nCount = nNewCount;
}
/**
@@ -1499,38 +1250,37 @@ bool SfxItemSet::Set
rSet are not taken into account */
)
{
- bool bRet = false;
if (Count())
ClearItem();
- if ( bDeep )
+
+ if (!bDeep)
+ return Put(rSet, false);
+
+ bool bRet = false;
+ SfxWhichIter aIter1(*this);
+ SfxWhichIter aIter2(rSet);
+ sal_uInt16 nWhich1 = aIter1.FirstWhich();
+ sal_uInt16 nWhich2 = aIter2.FirstWhich();
+ for (;;)
{
- SfxWhichIter aIter1(*this);
- SfxWhichIter aIter2(rSet);
- sal_uInt16 nWhich1 = aIter1.FirstWhich();
- sal_uInt16 nWhich2 = aIter2.FirstWhich();
- for (;;)
+ if (!nWhich1 || !nWhich2)
+ break;
+ if (nWhich1 > nWhich2)
{
- if (!nWhich1 || !nWhich2)
- break;
- if (nWhich1 > nWhich2)
- {
- nWhich2 = aIter2.NextWhich();
- continue;
- }
- if (nWhich1 < nWhich2)
- {
- nWhich1 = aIter1.NextWhich();
- continue;
- }
- const SfxPoolItem* pItem;
- if( SfxItemState::SET == aIter2.GetItemState( true, &pItem ) )
- bRet |= nullptr != Put( *pItem );
- nWhich1 = aIter1.NextWhich();
nWhich2 = aIter2.NextWhich();
+ continue;
}
+ if (nWhich1 < nWhich2)
+ {
+ nWhich1 = aIter1.NextWhich();
+ continue;
+ }
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == aIter2.GetItemState( true, &pItem ) )
+ bRet |= nullptr != Put( *pItem );
+ nWhich1 = aIter1.NextWhich();
+ nWhich2 = aIter2.NextWhich();
}
- else
- bRet = Put(rSet, false);
return bRet;
}
@@ -1554,25 +1304,19 @@ const SfxPoolItem* SfxItemSet::GetItem(sal_uInt16 nId, bool bSearchInParent) con
const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const
{
- // Search the Range in which the Which is located in:
- const sal_uInt16 nOffset(GetRanges().getOffsetFromWhich(nWhich));
+ PoolItemMap::const_iterator aHit(m_aPoolItemMap.find(nWhich));
- if (INVALID_WHICHPAIR_OFFSET != nOffset)
+ if (aHit != m_aPoolItemMap.end())
{
- const_iterator aFoundOne(begin() + nOffset);
-
- if (nullptr != *aFoundOne)
+ if (IsInvalidItem(aHit->second))
{
- if (IsInvalidItem(*aFoundOne))
- {
- return GetPool()->GetUserOrPoolDefaultItem(nWhich);
- }
+ return GetPool()->GetUserOrPoolDefaultItem(nWhich);
+ }
#ifdef DBG_UTIL
- if (IsDisabledItem(*aFoundOne))
- SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
+ if (IsDisabledItem(aHit->second))
+ SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
#endif
- return **aFoundOne;
- }
+ return *aHit->second;
}
if (bSrchInParent && nullptr != GetParent())
@@ -1617,33 +1361,18 @@ void SfxItemSet::Intersect( const SfxItemSet& rSet )
// locally delete all Items that are *not* set in rSet
// -> != SfxItemState::SET
- // same ranges?
- if (GetRanges() == rSet.GetRanges())
- {
- for (sal_uInt16 nOffset(0); nOffset < TotalCount(); nOffset++)
- {
- if (SfxItemState::SET != rSet.GetItemState_ForOffset(nOffset, nullptr))
- {
- // can use same offset
- ClearSingleItem_ForOffset(nOffset);
- }
- }
- }
- else
+ for (PoolItemMap::iterator aCandidate(m_aPoolItemMap.begin()); aCandidate != m_aPoolItemMap.end();)
{
- sal_uInt16 nOffset(0);
-
- for (auto const & rRange : GetRanges())
+ if (SfxItemState::SET != rSet.GetItemState_ForWhichID(SfxItemState::UNKNOWN, aCandidate->first, false, nullptr))
{
- for (sal_uInt16 nWhich(rRange.first); nWhich <= rRange.second; nWhich++, nOffset++)
- {
- if (SfxItemState::SET != rSet.GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWhich, false, nullptr))
- {
- // can use offset
- ClearSingleItem_ForOffset(nOffset);
- }
- }
+#ifdef DBG_UTIL
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet Intersect with active SfxItemIters (!)");
+#endif
+ ClearSingleItem_PrepareRemove(aCandidate->second);
+ aCandidate = m_aPoolItemMap.erase(aCandidate);
}
+ else
+ aCandidate++;
}
}
@@ -1673,33 +1402,18 @@ void SfxItemSet::Differentiate(const SfxItemSet& rSet)
// locally delete all Items that *are *not* set in rSet
// -> ==SfxItemState::SET
- // same ranges?
- if (GetRanges() == rSet.GetRanges())
+ for (PoolItemMap::iterator aCandidate(m_aPoolItemMap.begin()); aCandidate != m_aPoolItemMap.end();)
{
- for (sal_uInt16 nOffset(0); nOffset < TotalCount(); nOffset++)
+ if (SfxItemState::SET == rSet.GetItemState_ForWhichID(SfxItemState::UNKNOWN, aCandidate->first, false, nullptr))
{
- if (SfxItemState::SET == rSet.GetItemState_ForOffset(nOffset, nullptr))
- {
- // can use same offset
- ClearSingleItem_ForOffset(nOffset);
- }
- }
- }
- else
- {
- sal_uInt16 nOffset(0);
-
- for (auto const & rRange : GetRanges())
- {
- for (sal_uInt16 nWhich(rRange.first); nWhich <= rRange.second; nWhich++, nOffset++)
- {
- if (SfxItemState::SET == rSet.GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWhich, false, nullptr))
- {
- // can use offset
- ClearSingleItem_ForOffset(nOffset);
- }
- }
+#ifdef DBG_UTIL
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet Differentiate with active SfxItemIters (!)");
+#endif
+ ClearSingleItem_PrepareRemove(aCandidate->second);
+ aCandidate = m_aPoolItemMap.erase(aCandidate);
}
+ else
+ aCandidate++;
}
}
@@ -1781,77 +1495,83 @@ void SfxItemSet::Differentiate(const SfxItemSet& rSet)
* dontcare unknown != sal_True - - -
* unknown unknown != sal_True - - -
*/
-void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, bool bIgnoreDefaults)
+
+void SfxItemSet::MergeItem_Impl(sal_uInt16 nWhich, const SfxPoolItem *pFnd2, bool bIgnoreDefaults)
{
- assert(ppFnd1 != nullptr && "Merging to 0-Item");
+ // callers need to ensure that nWhich is in local range
+ assert(GetRanges().doesContainWhich(nWhich) && "ITEM: call to MergeItem_Impl with WhichID outside local range (!)");
+ const PoolItemMap::iterator aHit(m_aPoolItemMap.find(nWhich));
- // 1st Item is Default?
- if ( !*ppFnd1 )
+ if (aHit == m_aPoolItemMap.end())
{
- if ( IsInvalidItem(pFnd2) )
+ // 1st Item nWhich is not set (Default)
+ const SfxPoolItem* pNew(nullptr);
+
+ if (IsInvalidItem(pFnd2))
// Decision table: default, dontcare, doesn't matter, doesn't matter
- *ppFnd1 = INVALID_POOL_ITEM;
+ pNew = INVALID_POOL_ITEM;
- else if ( pFnd2 && !bIgnoreDefaults &&
- GetPool()->GetUserOrPoolDefaultItem(pFnd2->Which()) != *pFnd2 )
+ else if (pFnd2 && !bIgnoreDefaults && GetPool()->GetUserOrPoolDefaultItem(nWhich) != *pFnd2)
// Decision table: default, set, !=, sal_False
- *ppFnd1 = INVALID_POOL_ITEM;
+ pNew = INVALID_POOL_ITEM;
- else if ( pFnd2 && bIgnoreDefaults )
+ else if (pFnd2 && bIgnoreDefaults)
// Decision table: default, set, doesn't matter, sal_True
- *ppFnd1 = implCreateItemEntry(*GetPool(), pFnd2, false);
- // *ppFnd1 = &GetPool()->Put( *pFnd2 );
+ pNew = implCreateItemEntry(*GetPool(), pFnd2, false);
- if ( *ppFnd1 )
+ if (pNew)
{
- ++m_nCount;
- checkAddPoolRegistration(*ppFnd1);
+#ifdef DBG_UTIL
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet MergeItem with active SfxItemIters (!)");
+#endif
+ m_aPoolItemMap[nWhich] = pNew;
+ checkAddPoolRegistration(pNew);
}
+
+ return;
}
- // 1st Item set?
- else if ( !IsInvalidItem(*ppFnd1) )
+ const SfxPoolItem* pFnd1(aHit->second);
+
+ if (IsInvalidItem(pFnd1))
{
- if ( !pFnd2 )
- {
- // 2nd Item is Default
- if ( !bIgnoreDefaults &&
- **ppFnd1 != GetPool()->GetUserOrPoolDefaultItem((*ppFnd1)->Which()) )
- {
- // Decision table: set, default, !=, sal_False
- checkRemovePoolRegistration(*ppFnd1);
- implCleanupItemEntry(*ppFnd1);
- // GetPool()->Remove( **ppFnd1 );
- *ppFnd1 = INVALID_POOL_ITEM;
- }
- }
- else if ( IsInvalidItem(pFnd2) )
+ return;
+ }
+
+ // 1st Item is set, check for change
+ bool bDoChange(false);
+
+ if (nullptr == pFnd2)
+ {
+ // 2nd Item is not set (Default)
+ if (!bIgnoreDefaults && *pFnd1 != GetPool()->GetUserOrPoolDefaultItem(nWhich))
{
- // 2nd Item is dontcare
- if ( !bIgnoreDefaults ||
- **ppFnd1 != GetPool()->GetUserOrPoolDefaultItem( (*ppFnd1)->Which()) )
- {
- // Decision table: set, dontcare, doesn't matter, sal_False
- // or: set, dontcare, !=, sal_True
- checkRemovePoolRegistration(*ppFnd1);
- implCleanupItemEntry(*ppFnd1);
- // GetPool()->Remove( **ppFnd1 );
- *ppFnd1 = INVALID_POOL_ITEM;
- }
+ // Decision table: set, default, !=, sal_False
+ bDoChange = true;
}
- else
+ }
+ else if (IsInvalidItem(pFnd2))
+ {
+ // 2nd Item is invaid (dontcare)
+ if (!bIgnoreDefaults || *pFnd1 != GetPool()->GetUserOrPoolDefaultItem(nWhich))
{
- // 2nd Item is set
- if ( **ppFnd1 != *pFnd2 )
- {
- // Decision table: set, set, !=, doesn't matter
- checkRemovePoolRegistration(*ppFnd1);
- implCleanupItemEntry(*ppFnd1);
- // GetPool()->Remove( **ppFnd1 );
- *ppFnd1 = INVALID_POOL_ITEM;
- }
+ // Decision table: set, dontcare, doesn't matter, sal_False
+ // or: set, dontcare, !=, sal_True
+ bDoChange = true;
}
}
+ else if (*pFnd1 != *pFnd2)
+ {
+ // 2nd Item is set
+ // Decision table: set, set, !=, doesn't matter
+ bDoChange = true;
+ }
+
+ if (bDoChange)
+ {
+ ClearSingleItem_PrepareRemove(pFnd1);
+ aHit->second = INVALID_POOL_ITEM;
+ }
}
void SfxItemSet::MergeValues( const SfxItemSet& rSet )
@@ -1869,33 +1589,13 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet )
// evtl. could not find that WhichID in local WhichRanges
// Better to loop over local WhichRanges (these get changed) and look
// for Item with same WhichID in rSet, this is done now.
- if (GetRanges() == rSet.GetRanges())
- {
-
- // loop over both & merge, WhichIDs are identical
- for (const_iterator dst(begin()), src(rSet.begin()); dst != end(); dst++, src++)
- {
- MergeItem_Impl(dst, *src, false/*bIgnoreDefaults*/);
- }
- }
- else
+ for (auto const & rRange : GetRanges())
{
- // loop over local which-ranges - the local Items need to be changed
- const_iterator dst(begin());
-
- for (auto const & rRange : GetRanges())
+ for (sal_uInt16 nWhich(rRange.first); nWhich <= rRange.second; nWhich++)
{
- for (sal_uInt16 nWhich(rRange.first); nWhich <= rRange.second; nWhich++, dst++)
- {
- // try to get offset in rSet for same WhichID
- const sal_uInt16 nOffset(rSet.GetRanges().getOffsetFromWhich(nWhich));
-
- if (INVALID_WHICHPAIR_OFFSET != nOffset)
- {
- // if entry with same WhichID exists in rSet, merge with local entry
- MergeItem_Impl(dst, *(rSet.begin() + nOffset), false/*bIgnoreDefaults*/);
- }
- }
+ PoolItemMap::const_iterator aHit(rSet.m_aPoolItemMap.find(nWhich));
+ const SfxPoolItem* src(aHit == rSet.m_aPoolItemMap.end() ? nullptr : aHit->second);
+ MergeItem_Impl(nWhich, src, false/*bIgnoreDefaults*/);
}
}
}
@@ -1903,106 +1603,42 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet )
void SfxItemSet::MergeValue(const SfxPoolItem& rAttr)
{
if (IsDisabledItem(&rAttr))
- // is IsDisabledItem, nothing to do
+ // DisabledItem, nothing to do
return;
- const sal_uInt16 nOffset(GetRanges().getOffsetFromWhich(rAttr.Which()));
-
- if (INVALID_WHICHPAIR_OFFSET != nOffset)
+ if (GetRanges().doesContainWhich(rAttr.Which()))
{
- MergeItem_Impl(begin() + nOffset, &rAttr, /*bIgnoreDefaults*/true);
+ MergeItem_Impl(rAttr.Which(), &rAttr, /*bIgnoreDefaults*/true);
}
}
void SfxItemSet::DisableOrInvalidateItem_ForWhichID(bool bDisable, sal_uInt16 nWhich)
{
- const sal_uInt16 nOffset(GetRanges().getOffsetFromWhich(nWhich));
+ PoolItemMap::iterator aHit(m_aPoolItemMap.find(nWhich));
- if (INVALID_WHICHPAIR_OFFSET != nOffset)
+ if (aHit != m_aPoolItemMap.end())
{
- DisableOrInvalidateItem_ForOffset(bDisable, nOffset);
- }
-}
-
-void SfxItemSet::DisableOrInvalidateItem_ForOffset(bool bDisable, sal_uInt16 nOffset)
-{
- // check and assert from invalid offset. The caller is responsible for
- // ensuring a valid offset (see callers, all checked & safe)
- assert(nOffset < TotalCount());
- const_iterator aFoundOne(begin() + nOffset);
-
- if (nullptr == *aFoundOne)
- {
- // entry goes from nullptr -> invalid
- ++m_nCount;
- }
- else
- {
- if (bDisable && IsDisabledItem(*aFoundOne))
+ if (bDisable && IsDisabledItem(aHit->second))
// already disabled item, done
return;
- if (!bDisable && IsInvalidItem(*aFoundOne))
+ if (!bDisable && IsInvalidItem(aHit->second))
// already invalid item, done
return;
-
// cleanup entry
- checkRemovePoolRegistration(*aFoundOne);
- implCleanupItemEntry(*aFoundOne);
+ ClearSingleItem_PrepareRemove(aHit->second);
+ aHit->second = bDisable ? DISABLED_POOL_ITEM : INVALID_POOL_ITEM;
}
-
- // set new entry
- *aFoundOne = bDisable ? DISABLED_POOL_ITEM : INVALID_POOL_ITEM;
-}
-
-sal_uInt16 SfxItemSet::GetWhichByOffset( sal_uInt16 nOffset ) const
-{
- assert(nOffset < TotalCount());
-
- // 1st try to get a set SfxPoolItem and fetch the WhichID from there.
- const SfxPoolItem* pItem(nullptr);
- (void)GetItemState_ForOffset(nOffset, &pItem);
-
- if (nullptr != pItem && 0 != pItem->Which())
- return pItem->Which();
-
- // 2nd have to get from WhichRangesContainer. That might use
- // the buffering, too. We might assert a return value of zero
- // (which means invalid WhichID), but we already assert for
- // a valid offset at the start of this method
- return GetRanges().getWhichFromOffset(nOffset);
-}
-
-const SfxPoolItem& SfxItemSet::GetByOffset( sal_uInt16 nWhich, sal_uInt16 nOffset ) const
-{
- assert(nOffset < TotalCount());
-
- const_iterator aFoundOne(begin() + nOffset);
-
- if (nullptr != *aFoundOne)
+ else if (GetRanges().doesContainWhich(nWhich))
{
- if (IsInvalidItem(*aFoundOne))
- {
- return GetPool()->GetUserOrPoolDefaultItem(nWhich);
- }
#ifdef DBG_UTIL
- if (IsDisabledItem(*aFoundOne))
- SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
+ assert(0 == m_nRegisteredSfxItemIter && "ITEM: SfxItemSet DisableOrInvalidateItem with active SfxItemIters (!)");
#endif
- return **aFoundOne;
- }
-
- if (nullptr != GetParent())
- {
- return GetParent()->Get(nWhich, /*bSrchInParent*/true);
+ // new entry
+ m_aPoolItemMap[nWhich] = bDisable ? DISABLED_POOL_ITEM : INVALID_POOL_ITEM;
}
-
- // Get the Default from the Pool and return
- assert(m_pPool);
- return GetPool()->GetUserOrPoolDefaultItem(nWhich);
}
-
bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
{
return Equals( rCmp, true);
@@ -2030,66 +1666,20 @@ bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool bComparePool) const
if (0 == Count())
return true;
- // check if ranges are equal
- if (GetRanges() == rCmp.GetRanges())
+ for (PoolItemMap::const_iterator aCandidate(m_aPoolItemMap.begin()); aCandidate != m_aPoolItemMap.end(); aCandidate++)
{
- // if yes, we can simplify: are all pointers the same?
- if (0 == memcmp( m_ppItems, rCmp.m_ppItems, TotalCount() * sizeof(m_ppItems[0]) ))
- return true;
-
- // compare each one separately
- const SfxPoolItem **ppItem1(m_ppItems);
- const SfxPoolItem **ppItem2(rCmp.m_ppItems);
-
- for (sal_uInt16 nPos(0); nPos < TotalCount(); nPos++)
- {
- // do full SfxPoolItem compare
- if (!SfxPoolItem::areSame(*ppItem1, *ppItem2))
- return false;
- ++ppItem1;
- ++ppItem2;
- }
-
- return true;
- }
+ const SfxPoolItem *pItem1(nullptr);
+ const SfxPoolItem *pItem2(nullptr);
+ const sal_uInt16 nWhich(aCandidate->first);
+ const SfxItemState aStateA(GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWhich, false, &pItem1));
+ const SfxItemState aStateB(rCmp.GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWhich, false, &pItem2));
- // Not same ranges, need to compare content. Only need to check if
- // the content of one is inside the other due to already having
- // compared Count() above.
- // Iterate over local SfxItemSet by using locval ranges and offset,
- // so we can access needed data at least for one SfxItemSet more
- // direct. For the 2nd one we need the WhichID which we have by
- // iterating over the ranges.
- sal_uInt16 nOffset(0);
- sal_uInt16 nNumberToGo(Count());
+ if (aStateA != aStateB)
+ return false;
- for (auto const & rRange : GetRanges())
- {
- for (sal_uInt16 nWhich(rRange.first); nWhich <= rRange.second; nWhich++, nOffset++)
- {
- const SfxPoolItem *pItem1(nullptr);
- const SfxPoolItem *pItem2(nullptr);
- const SfxItemState aStateA(GetItemState_ForOffset(nOffset, &pItem1));
- const SfxItemState aStateB(rCmp.GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWhich, false, &pItem2));
-
- if (aStateA != aStateB)
- return false;
-
- // only compare items if SfxItemState::SET, else the item ptrs are not set
- if (SfxItemState::SET == aStateA && !SfxPoolItem::areSame(pItem1, pItem2))
- return false;
-
- if (SfxItemState::DEFAULT != aStateA)
- // if local item is not-nullptr we have compared one more, reduce NumberToGo
- // NOTE: we could also use 'nullptr != *(begin() + nOffset)' here, but the
- // entry was already checked by GetItemState_ForOffset above
- nNumberToGo--;
-
- if (0 == nNumberToGo)
- // if we have compared Count() number of items and are still here
- // (all were equal), we can exit early
- return true;
- }
+ // only compare items if SfxItemState::SET, else the item ptrs are not set
+ if (SfxItemState::SET == aStateA && !SfxPoolItem::areSame(pItem1, pItem2))
+ return false;
}
return true;
@@ -2172,7 +1762,7 @@ void SfxItemSet::dumpAsXml(xmlTextWriterPtr pWriter) const
// ----------------------------------------------- class SfxAllItemSet
SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool )
-: SfxItemSet(rPool, SfxAllItemSetFlag::Flag)
+: SfxItemSet(rPool)
{
}
@@ -2344,20 +1934,20 @@ static void isMiss()
}
#endif
-sal_uInt16 WhichRangesContainer::getOffsetFromWhich(sal_uInt16 nWhich) const
+bool WhichRangesContainer::doesContainWhich(sal_uInt16 nWhich) const
{
// special case for single entry - happens often e.g. UI stuff
if (m_size == 1)
{
if( m_pairs->first <= nWhich && nWhich <= m_pairs->second )
- return nWhich - m_pairs->first;
+ return true;
// we have only one WhichPair entry and it's not contained -> failed
- return INVALID_WHICHPAIR_OFFSET;
+ return false;
}
if (m_size == 0)
- return INVALID_WHICHPAIR_OFFSET;
+ return false;
// check if nWhich is inside last successfully used WhichPair
if (INVALID_WHICHPAIR_OFFSET != m_aLastWhichPairOffset
@@ -2368,7 +1958,7 @@ sal_uInt16 WhichRangesContainer::getOffsetFromWhich(sal_uInt16 nWhich) const
isHit();
#endif
// we can re-use the last found WhichPair
- return m_aLastWhichPairOffset + (nWhich - m_aLastWhichPairFirst);
+ return true;
}
#ifdef DBG_UTIL
@@ -2389,7 +1979,7 @@ sal_uInt16 WhichRangesContainer::getOffsetFromWhich(sal_uInt16 nWhich) const
m_aLastWhichPairSecond = rPair.second;
// ...and return
- return m_aLastWhichPairOffset + (nWhich - m_aLastWhichPairFirst);
+ return true;
}
m_aLastWhichPairOffset += rPair.second - rPair.first + 1;
@@ -2399,62 +1989,7 @@ sal_uInt16 WhichRangesContainer::getOffsetFromWhich(sal_uInt16 nWhich) const
// what could wrongly trigger re-use above for next search
m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
- return m_aLastWhichPairOffset;
-}
-
-sal_uInt16 WhichRangesContainer::getWhichFromOffset(sal_uInt16 nOffset) const
-{
- // special case for single entry - happens often e.g. UI stuff
- if (m_size == 1)
- {
- if (nOffset <= m_pairs->second - m_pairs->first)
- return m_pairs->first + nOffset;
-
- // we have only one WhichPair entry and it's not contained -> failed
- return 0;
- }
-
- // check for empty, if yes, return null which is an invalid WhichID
- if (m_size == 0)
- return 0;
-
- // check if nWhich is inside last successfully used WhichPair
- if (INVALID_WHICHPAIR_OFFSET != m_aLastWhichPairOffset)
- {
- // only try if we are beyond or at m_aLastWhichPairOffset to
- // not get numerically negative
- if (nOffset >= m_aLastWhichPairOffset)
- {
- const sal_uInt16 nAdaptedOffset(nOffset - m_aLastWhichPairOffset);
-
- if (nAdaptedOffset <= m_aLastWhichPairSecond - m_aLastWhichPairFirst)
- {
-#ifdef DBG_UTIL
- isHit();
-#endif
- return m_aLastWhichPairFirst + nAdaptedOffset;
- }
- }
- }
-
-#ifdef DBG_UTIL
- isMiss();
-#endif
-
- // Iterate over WhichPairs in WhichRangesContainer
- // Do not update buffered last hit (m_aLastWhichPair*), these calls
- // are potentially more rare than getOffsetFromWhich calls. Still,
- // it could also be done here
- for( auto const & pPtr : *this )
- {
- const sal_uInt16 nWhichPairRange(pPtr.second - pPtr.first);
- if( nOffset <= nWhichPairRange )
- return pPtr.first + nOffset;
- nOffset -= nWhichPairRange + 1;
- }
-
- // no WhichID found, return invalid one
- return 0;
+ return false;
}
// Adds a range to which ranges, keeping the ranges in valid state (sorted, non-overlapping)