summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svl/itemset.hxx24
-rw-r--r--include/svl/whichranges.hxx21
-rw-r--r--svl/source/items/itemiter.cxx21
-rw-r--r--svl/source/items/itemset.cxx673
-rw-r--r--svl/source/items/whiter.cxx25
-rw-r--r--svx/source/dialog/srchdlg.cxx2
-rw-r--r--sw/source/core/crsr/findattr.cxx8
-rw-r--r--sw/source/core/doc/DocumentRedlineManager.cxx2
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx2
-rw-r--r--sw/source/core/undo/undobj1.cxx2
-rw-r--r--sw/source/filter/ww8/writerhelper.cxx2
-rw-r--r--sw/source/uibase/app/docstyle.cxx2
-rw-r--r--sw/source/uibase/uiview/srcview.cxx2
13 files changed, 472 insertions, 314 deletions
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index 52966ecc96d6..468893557b5e 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -40,9 +40,10 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
SfxItemPool* m_pPool; ///< pool that stores the items
const SfxItemSet* m_pParent; ///< derivation
+ sal_uInt16 m_nCount; ///< number of items
+ sal_uInt16 m_nTotalCount; ///< number of WhichIDs, also size of m_ppItems array
SfxPoolItem const** m_ppItems; ///< pointer to array of items, we allocate and free this unless m_bItemsFixed==true
WhichRangesContainer m_pWhichRanges; ///< array of Which Ranges
- sal_uInt16 m_nCount; ///< number of items
bool m_bItemsFixed; ///< true if this is a SfxItemSetFixed object
friend class SfxItemPoolCache;
@@ -69,7 +70,7 @@ protected:
enum class SfxAllItemSetFlag { Flag };
SfxItemSet( SfxItemPool&, SfxAllItemSetFlag );
/** special constructor for SfxItemSetFixed */
- SfxItemSet( SfxItemPool&, WhichRangesContainer&& ranges, SfxPoolItem const ** ppItems );
+ SfxItemSet( SfxItemPool&, WhichRangesContainer&& ranges, SfxPoolItem const ** ppItems, sal_uInt16 nTotalCount );
public:
SfxItemSet( const SfxItemSet& );
@@ -93,7 +94,7 @@ public:
// Get number of items
sal_uInt16 Count() const { return m_nCount; }
- sal_uInt16 TotalCount() const;
+ sal_uInt16 TotalCount() const { return m_nTotalCount; }
const SfxPoolItem& Get( sal_uInt16 nWhich, bool bSrchInParent = true ) const;
template<class T>
@@ -140,7 +141,7 @@ public:
return GetItem<T>(pItemSet, static_cast<sal_uInt16>(nWhich), bSearchInParent);
}
- sal_uInt16 GetWhichByPos(sal_uInt16 nPos) const;
+ sal_uInt16 GetWhichByOffset(sal_uInt16 nOffset) const;
SfxItemState GetItemState( sal_uInt16 nWhich,
bool bSrchInParent = true,
@@ -224,12 +225,15 @@ public:
void dumpAsXml(xmlTextWriterPtr pWriter) const;
private:
- sal_uInt16 ClearSingleItemImpl( sal_uInt16 nWhich, std::optional<sal_uInt16> oItemOffsetHint );
+ // split version(s) of ClearSingleItemImpl for input types WhichID and Offset
+ sal_uInt16 ClearSingleItem_ForWhichID( sal_uInt16 nWhich );
+ sal_uInt16 ClearSingleItem_ForOffset( sal_uInt16 nOffset );
+
sal_uInt16 ClearAllItemsImpl();
- SfxItemState GetItemStateImpl( sal_uInt16 nWhich,
- bool bSrchInParent,
- const SfxPoolItem **ppItem,
- std::optional<sal_uInt16> oItemsOffsetHint) const;
+
+ // split version(s) of GetItemStateImpl for input types WhichID and Offset
+ SfxItemState GetItemState_ForWhichID( SfxItemState eState, sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem) const;
+ SfxItemState GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPoolItem **ppItem) const;
};
inline void SfxItemSet::SetParent( const SfxItemSet* pNew )
@@ -275,7 +279,7 @@ class SfxItemSetFixed : public SfxItemSet
{
public:
SfxItemSetFixed( SfxItemPool& rPool)
- : SfxItemSet(rPool, WhichRangesContainer(svl::Items_t<WIDs...>{}), m_aItems) {}
+ : SfxItemSet(rPool, WhichRangesContainer(svl::Items_t<WIDs...>{}), m_aItems, NITEMS) {}
private:
static constexpr sal_uInt16 NITEMS = svl::detail::CountRanges1<WIDs...>();
const SfxPoolItem* m_aItems[NITEMS] = {};
diff --git a/include/svl/whichranges.hxx b/include/svl/whichranges.hxx
index 744a0f2edaf5..37a3d34e5613 100644
--- a/include/svl/whichranges.hxx
+++ b/include/svl/whichranges.hxx
@@ -71,6 +71,8 @@ template <sal_uInt16... WIDs> struct Items_t
template <sal_uInt16... WIDs> inline static constexpr auto Items = Items_t<WIDs...>{};
}
+#define INVALID_WHICHPAIR_OFFSET (sal_uInt16(0xffff))
+
/**
* Most of the time, the which ranges we point at are a compile-time literal.
* So we take advantage of that, and avoid the cost of allocating our own array and copying into it.
@@ -85,12 +87,21 @@ struct SVL_DLLPUBLIC WhichRangesContainer
* at a global const literal */
bool m_bOwnRanges = false;
+ // variables for buffering the last used WhichPair to allow fast answers
+ // in getOffsetFromWhich
+ mutable sal_uInt16 m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+ mutable sal_uInt16 m_aLastWhichPairFirst = 0;
+ mutable sal_uInt16 m_aLastWhichPairSecond = 0;
+
WhichRangesContainer() = default;
WhichRangesContainer(std::unique_ptr<WhichPair[]> wids, sal_Int32 nSize)
: m_pairs(wids.release())
, m_size(nSize)
, m_bOwnRanges(true)
+ , m_aLastWhichPairOffset(INVALID_WHICHPAIR_OFFSET)
+ , m_aLastWhichPairFirst(0)
+ , m_aLastWhichPairSecond(0)
{
}
template <sal_uInt16... WIDs>
@@ -98,6 +109,9 @@ struct SVL_DLLPUBLIC WhichRangesContainer
: m_pairs(svl::Items_t<WIDs...>::value.data())
, m_size(svl::Items_t<WIDs...>::value.size())
, m_bOwnRanges(false)
+ , m_aLastWhichPairOffset(INVALID_WHICHPAIR_OFFSET)
+ , m_aLastWhichPairFirst(0)
+ , m_aLastWhichPairSecond(0)
{
}
WhichRangesContainer(const WhichPair* wids, sal_Int32 nSize);
@@ -121,6 +135,13 @@ struct SVL_DLLPUBLIC WhichRangesContainer
}
void reset();
+ // calculate and return the offset inside the fixed SfxPoolItem
+ // array of SfxItemPool
+ sal_uInt16 getOffsetFromWhich(sal_uInt16 nWhich) const;
+
+ // extract the WhichID for given offset
+ sal_uInt16 getWhichFromOffset(sal_uInt16 nOffset) const;
+
// Adds a range to which ranges, keeping the ranges in valid state (sorted, non-overlapping)
SAL_WARN_UNUSED_RESULT WhichRangesContainer MergeRange(sal_uInt16 nFrom, sal_uInt16 nTo) const;
};
diff --git a/svl/source/items/itemiter.cxx b/svl/source/items/itemiter.cxx
index fd0f6240e0c6..d8864c387edd 100644
--- a/svl/source/items/itemiter.cxx
+++ b/svl/source/items/itemiter.cxx
@@ -58,14 +58,27 @@ const SfxPoolItem* SfxItemIter::ImplNextItem()
SfxItemState SfxItemIter::GetItemState(bool bSrchInParent, const SfxPoolItem** ppItem) const
{
- sal_uInt16 nWhich = (*(m_rSet.m_ppItems + m_nCurrent))->Which();
- return m_rSet.GetItemStateImpl(nWhich, bSrchInParent, ppItem, m_nCurrent);
+ // we have the offset, so use it to profit. It is always valid, so no need
+ // to check if smaller than TotalCount()
+ SfxItemState eState(m_rSet.GetItemState_ForOffset(m_nCurrent, ppItem));
+
+ // search in parent?
+ if (bSrchInParent && nullptr != m_rSet.GetParent()
+ && (SfxItemState::UNKNOWN == eState || SfxItemState::DEFAULT == eState))
+ {
+ // nOffset was only valid for *local* SfxItemSet, need to continue with WhichID
+ const sal_uInt16 nWhich(m_rSet.GetWhichByOffset(m_nCurrent));
+ eState = m_rSet.GetParent()->GetItemState_ForWhichID(eState, nWhich, true, ppItem);
+ }
+
+ return eState;
}
void SfxItemIter::ClearItem()
{
- sal_uInt16 nWhich = (*(m_rSet.m_ppItems + m_nCurrent))->Which();
- const_cast<SfxItemSet&>(m_rSet).ClearSingleItemImpl(nWhich, m_nCurrent);
+ // we have the offset, so use it to profit. It is always valid, so no need
+ // to check if smaller than TotalCount()
+ const_cast<SfxItemSet&>(m_rSet).ClearSingleItem_ForOffset(m_nCurrent);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 655956f2d1cc..bfc8f74b2010 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -45,11 +45,13 @@
* Don't create ItemSets with full range before FreezeIdRanges()!
*/
SfxItemSet::SfxItemSet(SfxItemPool& rPool)
- : m_pPool(&rPool), m_pParent(nullptr),
- m_ppItems(new SfxPoolItem const *[svl::detail::CountRanges(rPool.GetFrozenIdRanges())]{}),
- m_pWhichRanges(rPool.GetFrozenIdRanges()),
- m_nCount(0),
- m_bItemsFixed(false)
+ : m_pPool(&rPool)
+ , m_pParent(nullptr)
+ , m_nCount(0)
+ , m_nTotalCount(svl::detail::CountRanges(rPool.GetFrozenIdRanges()))
+ , m_ppItems(new SfxPoolItem const *[m_nTotalCount]{})
+ , m_pWhichRanges(rPool.GetFrozenIdRanges())
+ , m_bItemsFixed(false)
{
assert(svl::detail::validRanges2(m_pWhichRanges));
}
@@ -57,19 +59,21 @@ SfxItemSet::SfxItemSet(SfxItemPool& rPool)
SfxItemSet::SfxItemSet( SfxItemPool& rPool, SfxAllItemSetFlag )
: m_pPool(&rPool)
, m_pParent(nullptr)
- , m_ppItems(nullptr)
, m_nCount(0)
+ , m_nTotalCount(0)
+ , m_ppItems(nullptr)
, m_bItemsFixed(false)
{
}
/** special constructor for SfxItemSetFixed */
-SfxItemSet::SfxItemSet( SfxItemPool& rPool, WhichRangesContainer&& ranges, SfxPoolItem const ** ppItems )
+SfxItemSet::SfxItemSet( SfxItemPool& rPool, WhichRangesContainer&& ranges, SfxPoolItem const ** ppItems, sal_uInt16 nTotalCount )
: m_pPool(&rPool)
, m_pParent(nullptr)
+ , m_nCount(0)
+ , m_nTotalCount(nTotalCount)
, m_ppItems(ppItems)
, m_pWhichRanges(std::move(ranges))
- , m_nCount(0)
, m_bItemsFixed(true)
{
assert(ppItems);
@@ -78,12 +82,13 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, WhichRangesContainer&& ranges, SfxPo
}
SfxItemSet::SfxItemSet(SfxItemPool& pool, WhichRangesContainer wids)
- : m_pPool(&pool),
- m_pParent(nullptr),
- m_ppItems(new SfxPoolItem const *[svl::detail::CountRanges(wids)]{}),
- m_pWhichRanges(std::move(wids)),
- m_nCount(0),
- m_bItemsFixed(false)
+ : m_pPool(&pool)
+ , m_pParent(nullptr)
+ , m_nCount(0)
+ , m_nTotalCount(svl::detail::CountRanges(wids))
+ , m_ppItems(new SfxPoolItem const *[m_nTotalCount]{})
+ , m_pWhichRanges(std::move(wids))
+ , m_bItemsFixed(false)
{
assert(svl::detail::CountRanges(m_pWhichRanges) != 0);
assert(svl::detail::validRanges2(m_pWhichRanges));
@@ -92,23 +97,23 @@ SfxItemSet::SfxItemSet(SfxItemPool& pool, WhichRangesContainer wids)
SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
: m_pPool( rASet.m_pPool )
, m_pParent( rASet.m_pParent )
- , m_pWhichRanges( rASet.m_pWhichRanges )
, m_nCount( rASet.m_nCount )
+ , m_nTotalCount( rASet.m_nTotalCount )
+ , m_ppItems(nullptr)
+ , m_pWhichRanges( rASet.m_pWhichRanges )
, m_bItemsFixed(false)
{
if (rASet.m_pWhichRanges.empty())
{
- m_ppItems = nullptr;
return;
}
- auto nCnt = svl::detail::CountRanges(m_pWhichRanges);
- m_ppItems = new const SfxPoolItem* [nCnt] {};
+ m_ppItems = new const SfxPoolItem* [TotalCount()] {};
// Copy attributes
SfxPoolItem const** ppDst = m_ppItems;
SfxPoolItem const** ppSrc = rASet.m_ppItems;
- for( sal_uInt16 n = nCnt; n; --n, ++ppDst, ++ppSrc )
+ for( sal_uInt16 n = TotalCount(); n; --n, ++ppDst, ++ppSrc )
if ( nullptr == *ppSrc || // Current Default?
IsInvalidItem(*ppSrc) || // DontCare?
IsStaticDefaultItem(*ppSrc) ) // Defaults that are not to be pooled?
@@ -132,21 +137,24 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept
: m_pPool( rASet.m_pPool )
, m_pParent( rASet.m_pParent )
+ , m_nCount( rASet.m_nCount )
+ , m_nTotalCount( rASet.TotalCount() )
, m_ppItems( rASet.m_ppItems )
, m_pWhichRanges( std::move(rASet.m_pWhichRanges) )
- , m_nCount( rASet.m_nCount )
, m_bItemsFixed(false)
{
if (rASet.m_bItemsFixed)
{
// have to make a copy
- int noItems = svl::detail::CountRanges(m_pWhichRanges);
- m_ppItems = new const SfxPoolItem* [noItems];
- std::copy(rASet.m_ppItems, rASet.m_ppItems + noItems, m_ppItems);
+ m_ppItems = new const SfxPoolItem* [TotalCount()];
+ std::copy(rASet.m_ppItems, rASet.m_ppItems + TotalCount(), m_ppItems);
}
else
+ {
// taking over ownership
+ rASet.m_nTotalCount = 0;
rASet.m_ppItems = nullptr;
+ }
rASet.m_pPool = nullptr;
rASet.m_pParent = nullptr;
rASet.m_nCount = 0;
@@ -159,9 +167,8 @@ SfxItemSet::~SfxItemSet()
{
if( Count() )
{
- sal_uInt16 nCount = TotalCount();
SfxPoolItem const** ppFnd = m_ppItems;
- for( sal_uInt16 nCnt = nCount; nCnt; --nCnt, ++ppFnd )
+ for( sal_uInt16 nCnt = TotalCount(); nCnt; --nCnt, ++ppFnd )
if( *ppFnd && !IsInvalidItem(*ppFnd) )
{
if( !(*ppFnd)->Which() )
@@ -192,40 +199,33 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
if( !Count() )
return 0;
if( nWhich )
- return ClearSingleItemImpl(nWhich, std::nullopt);
+ return ClearSingleItem_ForWhichID(nWhich);
else
return ClearAllItemsImpl();
}
-sal_uInt16 SfxItemSet::ClearSingleItemImpl( sal_uInt16 nWhich, std::optional<sal_uInt16> oItemOffsetHint )
+sal_uInt16 SfxItemSet::ClearSingleItem_ForWhichID( sal_uInt16 nWhich )
{
- sal_uInt16 nDel = 0;
- SfxPoolItem const** pFoundOne = nullptr;
+ const sal_uInt16 nOffset(m_pWhichRanges.getOffsetFromWhich(nWhich));
- if (oItemOffsetHint)
+ if (INVALID_WHICHPAIR_OFFSET != nOffset)
{
- pFoundOne = m_ppItems + *oItemOffsetHint;
- assert(!*pFoundOne || IsInvalidItem(*pFoundOne) || (*pFoundOne)->IsVoidItem() || (*pFoundOne)->Which() == nWhich);
+ // found, continue with offset
+ return ClearSingleItem_ForOffset(nOffset);
}
- else
- {
- SfxPoolItem const** ppFnd = m_ppItems;
- for (const WhichPair& rPair : m_pWhichRanges)
- {
- // Within this range?
- if( rPair.first <= nWhich && nWhich <= rPair.second )
- {
- // Actually set?
- ppFnd += nWhich - rPair.first;
- pFoundOne = ppFnd;
- // found => break
- break;
- }
- ppFnd += rPair.second - rPair.first + 1;
- }
- }
- if (pFoundOne && *pFoundOne)
+ // not found, return sal_uInt16 nDel = 0;
+ return 0;
+}
+
+sal_uInt16 SfxItemSet::ClearSingleItem_ForOffset( sal_uInt16 nOffset )
+{
+ sal_uInt16 nDel = 0;
+ SfxPoolItem const** pFoundOne = m_ppItems + nOffset;
+ assert(!*pFoundOne || IsInvalidItem(*pFoundOne) || (*pFoundOne)->IsVoidItem() || (*pFoundOne)->Which() != 0);
+ assert(nOffset < TotalCount());
+
+ if (*pFoundOne)
{
// Due to the assertions in the sub calls, we need to do the following
--m_nCount;
@@ -234,6 +234,8 @@ sal_uInt16 SfxItemSet::ClearSingleItemImpl( sal_uInt16 nWhich, std::optional<sal
if ( !IsInvalidItem(pItemToClear) )
{
+ const sal_uInt16 nWhich(pItemToClear->Which());
+
if (SfxItemPool::IsWhich(nWhich))
{
const SfxPoolItem& rNew = m_pParent
@@ -314,79 +316,64 @@ void SfxItemSet::ClearInvalidItems()
void SfxItemSet::InvalidateAllItems()
{
assert( !m_nCount && "There are still Items set" );
- m_nCount = TotalCount();
- memset(static_cast<void*>(m_ppItems), -1, m_nCount * sizeof(SfxPoolItem*));
+ memset(static_cast<void*>(m_ppItems), -1, TotalCount() * sizeof(SfxPoolItem*));
}
SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
bool bSrchInParent,
const SfxPoolItem **ppItem ) const
{
- return GetItemStateImpl(nWhich, bSrchInParent, ppItem, std::nullopt);
+ // use local helper, start value for looped-through SfxItemState value
+ // is SfxItemState::UNKNOWN
+ return GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWhich, bSrchInParent, ppItem);
}
-SfxItemState SfxItemSet::GetItemStateImpl( sal_uInt16 nWhich,
- bool bSrchInParent,
- const SfxPoolItem **ppItem,
- std::optional<sal_uInt16> oItemsOffsetHint) const
+SfxItemState SfxItemSet::GetItemState_ForWhichID( SfxItemState eState, sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem) const
{
- // Find the range in which the Which is located
- const SfxItemSet* pCurrentSet = this;
- SfxItemState eRet = SfxItemState::UNKNOWN;
- do
+ const sal_uInt16 nOffset(m_pWhichRanges.getOffsetFromWhich(nWhich));
+
+ if (INVALID_WHICHPAIR_OFFSET != nOffset)
{
- SfxPoolItem const** pFoundOne = nullptr;
- if (oItemsOffsetHint)
- {
- pFoundOne = pCurrentSet->m_ppItems + *oItemsOffsetHint;
- assert(!*pFoundOne || IsInvalidItem(*pFoundOne) || (*pFoundOne)->IsVoidItem() || (*pFoundOne)->Which() == nWhich);
- oItemsOffsetHint.reset(); // in case we need to search parent
- }
- else
- {
- SfxPoolItem const** ppFnd = pCurrentSet->m_ppItems;
- for (const WhichPair& rPair : pCurrentSet->m_pWhichRanges)
- {
- if ( rPair.first <= nWhich && nWhich <= rPair.second )
- {
- // Within this range
- pFoundOne = ppFnd + nWhich - rPair.first;
- break;
- }
- ppFnd += rPair.second - rPair.first + 1;
- }
- }
+ // found, continue with offset
+ eState = GetItemState_ForOffset(nOffset, ppItem);
+ }
- if (pFoundOne)
- {
- if ( !*pFoundOne )
- {
- eRet = SfxItemState::DEFAULT;
- if( !bSrchInParent )
- return eRet; // Not present
- // Keep searching in the parents!
- }
- else
- {
- if ( IsInvalidItem(*pFoundOne) )
- // Different ones are present
- return SfxItemState::DONTCARE;
+ // search in parent?
+ if (bSrchInParent && nullptr != GetParent() && (SfxItemState::UNKNOWN == eState || SfxItemState::DEFAULT == eState))
+ {
+ // nOffset was only valid for *local* SfxItemSet, need to continue with WhichID
+ // Use the *highest* SfxItemState as result
+ return GetParent()->GetItemState_ForWhichID( eState, nWhich, true, ppItem);
+ }
- if ( (*pFoundOne)->IsVoidItem() )
- return SfxItemState::DISABLED;
+ return eState;
+}
- if (ppItem)
- {
- *ppItem = *pFoundOne;
- }
- return SfxItemState::SET;
- }
- }
- if (!bSrchInParent)
- break;
- pCurrentSet = pCurrentSet->m_pParent;
- } while (nullptr != pCurrentSet);
- return eRet;
+SfxItemState SfxItemSet::GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPoolItem **ppItem) const
+{
+ // check and assert fr iinvaliid offset. The caller is responsible for
+ // ensuring a valid offset (see callers, all checked & safe)
+ assert(nOffset < TotalCount());
+ SfxPoolItem const** pFoundOne = m_ppItems + nOffset;
+
+ if ( nullptr == *pFoundOne )
+ // set to Default
+ return SfxItemState::DEFAULT;
+
+ if ( IsInvalidItem(*pFoundOne) )
+ // Different ones are present
+ return SfxItemState::DONTCARE;
+
+ if ( (*pFoundOne)->IsVoidItem() )
+ // Item is Disabled
+ return SfxItemState::DISABLED;
+
+ if (ppItem)
+ // if we have the Item, add it to output an hand back
+ *ppItem = *pFoundOne;
+
+ // Item is set
+ return SfxItemState::SET;
}
bool SfxItemSet::HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem) const
@@ -405,93 +392,91 @@ const SfxPoolItem* SfxItemSet::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWh
return nullptr; //FIXME: Only because of Outliner bug
}
- SfxPoolItem const** ppFnd = m_ppItems;
- for (const WhichPair& rPair : m_pWhichRanges)
+ const sal_uInt16 nOffset(m_pWhichRanges.getOffsetFromWhich(nWhich));
+
+ if (INVALID_WHICHPAIR_OFFSET != nOffset)
{
- if( rPair.first <= nWhich && nWhich <= rPair.second )
+ SfxPoolItem const** ppFnd(m_ppItems + nOffset);
+
+ if( *ppFnd ) // Already one present
{
- // Within this range
- ppFnd += nWhich - rPair.first;
- if( *ppFnd ) // Already one present
+ // Same Item already present?
+ if ( *ppFnd == &rItem )
{
- // Same Item already present?
- if ( *ppFnd == &rItem )
- {
- assert(!bPassingOwnership);
- return nullptr;
- }
+ assert(!bPassingOwnership);
+ return nullptr;
+ }
- // Will 'dontcare' or 'disabled' be overwritten with some real value?
- if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
- {
- auto const old = *ppFnd;
- *ppFnd = &m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
- if (!IsInvalidItem(old)) {
- assert(old->Which() == 0);
- delete old;
- }
- return *ppFnd;
+ // Will 'dontcare' or 'disabled' be overwritten with some real value?
+ if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
+ {
+ auto const old = *ppFnd;
+ *ppFnd = &m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
+ if (!IsInvalidItem(old)) {
+ assert(old->Which() == 0);
+ delete old;
}
+ return *ppFnd;
+ }
- // Turns into disabled?
- if( !rItem.Which() )
+ // Turns into disabled?
+ if( !rItem.Which() )
+ {
+ if (IsInvalidItem(*ppFnd) || (*ppFnd)->Which() != 0) {
+ *ppFnd = rItem.Clone(m_pPool);
+ }
+ if (bPassingOwnership)
+ delete &rItem;
+ return nullptr;
+ }
+ else
+ {
+ // Same value already present?
+ if ( rItem == **ppFnd )
{
- if (IsInvalidItem(*ppFnd) || (*ppFnd)->Which() != 0) {
- *ppFnd = rItem.Clone(m_pPool);
- }
if (bPassingOwnership)
delete &rItem;
return nullptr;
}
- else
- {
- // Same value already present?
- if ( rItem == **ppFnd )
- {
- if (bPassingOwnership)
- delete &rItem;
- return nullptr;
- }
- // Add the new one, remove the old one
- const SfxPoolItem& rNew = m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
- const SfxPoolItem* pOld = *ppFnd;
- *ppFnd = &rNew;
- if (SfxItemPool::IsWhich(nWhich))
- Changed( *pOld, rNew );
- m_pPool->Remove( *pOld );
- }
+ // Add the new one, remove the old one
+ const SfxPoolItem& rNew = m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
+ const SfxPoolItem* pOld = *ppFnd;
+ *ppFnd = &rNew;
+ if (SfxItemPool::IsWhich(nWhich))
+ Changed( *pOld, rNew );
+ m_pPool->Remove( *pOld );
+ }
+ }
+ else
+ {
+ ++m_nCount;
+ if( !rItem.Which() )
+ {
+ *ppFnd = rItem.Clone(m_pPool);
+ if (bPassingOwnership)
+ delete &rItem;
}
else
{
- ++m_nCount;
- if( !rItem.Which() )
- {
- *ppFnd = rItem.Clone(m_pPool);
- if (bPassingOwnership)
- delete &rItem;
- }
- else
+ const SfxPoolItem& rNew = m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
+ *ppFnd = &rNew;
+ if (SfxItemPool::IsWhich(nWhich))
{
- const SfxPoolItem& rNew = m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
- *ppFnd = &rNew;
- if (SfxItemPool::IsWhich(nWhich))
- {
- const SfxPoolItem& rOld = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
- Changed( rOld, rNew );
- }
+ const SfxPoolItem& rOld = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+ Changed( rOld, rNew );
}
}
- SAL_WARN_IF(!bPassingOwnership && m_pPool->IsItemPoolable(nWhich) &&
- dynamic_cast<const SfxSetItem*>( &rItem ) == nullptr &&
- **ppFnd != rItem,
- "svl.items", "putted Item unequal, with ID/pos " << nWhich );
- return *ppFnd;
}
- ppFnd += rPair.second - rPair.first + 1;
+ SAL_WARN_IF(!bPassingOwnership && m_pPool->IsItemPoolable(nWhich) &&
+ dynamic_cast<const SfxSetItem*>( &rItem ) == nullptr &&
+ **ppFnd != rItem,
+ "svl.items", "putted Item unequal, with ID/pos " << nWhich );
+ return *ppFnd;
}
+
if (bPassingOwnership)
delete &rItem;
return nullptr;
@@ -647,11 +632,11 @@ void SfxItemSet::SetRanges( WhichRangesContainer&& pNewRanges )
void SfxItemSet::RecreateRanges_Impl(const WhichRangesContainer& pNewRanges)
{
// create new item-array (by iterating through all new ranges)
- const auto nSize = svl::detail::CountRanges(pNewRanges);
- SfxPoolItem const** aNewItems = new const SfxPoolItem* [ nSize ];
+ const sal_uInt16 nTotalCount(svl::detail::CountRanges(pNewRanges));
+ SfxPoolItem const** aNewItems = new const SfxPoolItem* [ nTotalCount ];
sal_uInt16 nNewCount = 0;
if (m_nCount == 0)
- memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) );
+ memset( aNewItems, 0, nTotalCount * sizeof( SfxPoolItem* ) );
else
{
sal_uInt16 n = 0;
@@ -687,8 +672,7 @@ void SfxItemSet::RecreateRanges_Impl(const WhichRangesContainer& pNewRanges)
}
}
// free old items
- sal_uInt16 nOldTotalCount = TotalCount();
- for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem )
+ for ( sal_uInt16 nItem = 0; nItem < TotalCount(); ++nItem )
{
const SfxPoolItem *pItem = m_ppItems[nItem];
if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
@@ -701,6 +685,7 @@ void SfxItemSet::RecreateRanges_Impl(const WhichRangesContainer& pNewRanges)
m_bItemsFixed = false;
else
delete[] m_ppItems;
+ m_nTotalCount = nTotalCount;
m_ppItems = aNewItems;
m_nCount = nNewCount;
}
@@ -795,46 +780,34 @@ 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 SfxItemSet* pCurrentSet = this;
- do
+ const sal_uInt16 nOffset(m_pWhichRanges.getOffsetFromWhich(nWhich));
+
+ if (INVALID_WHICHPAIR_OFFSET != nOffset)
{
- if( pCurrentSet->Count() )
+ SfxPoolItem const** ppFnd(m_ppItems + nOffset);
+
+ if( *ppFnd )
{
- SfxPoolItem const** ppFnd = pCurrentSet->m_ppItems;
- for (auto const & pPtr : pCurrentSet->m_pWhichRanges)
- {
- if( pPtr.first <= nWhich && nWhich <= pPtr.second )
- {
- // In this Range
- ppFnd += nWhich - pPtr.first;
- if( *ppFnd )
- {
- if( IsInvalidItem(*ppFnd) ) {
- //FIXME: The following code is duplicated further down
- assert(m_pPool);
- //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
- //!return aDefault;
- return m_pPool->GetDefaultItem( nWhich );
- }
+ if( IsInvalidItem(*ppFnd) ) {
+ //FIXME: The following code is duplicated further down
+ assert(m_pPool);
+ //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
+ //!return aDefault;
+ return m_pPool->GetDefaultItem( nWhich );
+ }
#ifdef DBG_UTIL
- const SfxPoolItem *pItem = *ppFnd;
- if ( pItem->IsVoidItem() || !pItem->Which() )
- SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
+ const SfxPoolItem *pItem = *ppFnd;
+ if ( pItem->IsVoidItem() || !pItem->Which() )
+ SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
#endif
- return **ppFnd;
- }
- break; // Continue with Parent
- }
- ppFnd += pPtr.second - pPtr.first + 1;
- }
+ return **ppFnd;
}
-//TODO: Search until end of Range: What are we supposed to do now? To the Parent or Default??
-// if( !*pPtr ) // Until the end of the search Range?
-// break;
- if (!bSrchInParent)
- break;
- pCurrentSet = pCurrentSet->m_pParent;
- } while (nullptr != pCurrentSet);
+ }
+
+ if (bSrchInParent && nullptr != m_pParent)
+ {
+ return m_pParent->Get( nWhich, bSrchInParent);
+ }
// Get the Default from the Pool and return
assert(m_pPool);
@@ -848,11 +821,6 @@ void SfxItemSet::Changed( const SfxPoolItem&, const SfxPoolItem& )
{
}
-sal_uInt16 SfxItemSet::TotalCount() const
-{
- return svl::detail::CountRanges(m_pWhichRanges);
-}
-
/**
* Only retain the Items that are also present in rSet
* (nevermind their value).
@@ -873,7 +841,7 @@ void SfxItemSet::Intersect( const SfxItemSet& rSet )
// If the Ranges are identical, we can easily process it
if( m_pWhichRanges == rSet.m_pWhichRanges )
{
- sal_uInt16 nSize = TotalCount();
+ sal_uInt16 nSize(TotalCount());
SfxPoolItem const** ppFnd1 = m_ppItems;
SfxPoolItem const** ppFnd2 = rSet.m_ppItems;
@@ -919,7 +887,7 @@ void SfxItemSet::Differentiate( const SfxItemSet& rSet )
// If the Ranges are identical, we can easily process it
if( m_pWhichRanges == rSet.m_pWhichRanges )
{
- sal_uInt16 nSize = TotalCount();
+ sal_uInt16 nSize(TotalCount());
SfxPoolItem const** ppFnd1 = m_ppItems;
SfxPoolItem const** ppFnd2 = rSet.m_ppItems;
@@ -1108,7 +1076,7 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet )
// If the Ranges match, they are easier to process!
if( m_pWhichRanges == rSet.m_pWhichRanges )
{
- sal_uInt16 nSize = TotalCount();
+ sal_uInt16 nSize(TotalCount());
SfxPoolItem const** ppFnd1 = m_ppItems;
SfxPoolItem const** ppFnd2 = rSet.m_ppItems;
@@ -1156,45 +1124,44 @@ void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults )
void SfxItemSet::InvalidateItem( sal_uInt16 nWhich )
{
- SfxPoolItem const** ppFnd = m_ppItems;
- for( auto const & pPtr : m_pWhichRanges )
+ const sal_uInt16 nOffset(m_pWhichRanges.getOffsetFromWhich(nWhich));
+
+ if (INVALID_WHICHPAIR_OFFSET != nOffset)
{
- if( pPtr.first <= nWhich && nWhich <= pPtr.second )
- {
- // In this Range?
- ppFnd += nWhich - pPtr.first;
+ SfxPoolItem const** ppFnd(m_ppItems + nOffset);
- if( *ppFnd ) // Set for me
- {
- if( !IsInvalidItem(*ppFnd) )
- {
- m_pPool->Remove( **ppFnd );
- *ppFnd = INVALID_POOL_ITEM;
- }
- }
- else
+ if( *ppFnd ) // Set for me
+ {
+ if( !IsInvalidItem(*ppFnd) )
{
+ m_pPool->Remove( **ppFnd );
*ppFnd = INVALID_POOL_ITEM;
- ++m_nCount;
}
- break;
}
- ppFnd += pPtr.second - pPtr.first + 1;
+ else
+ {
+ *ppFnd = INVALID_POOL_ITEM;
+ ++m_nCount;
+ }
}
}
-sal_uInt16 SfxItemSet::GetWhichByPos( sal_uInt16 nPos ) const
+sal_uInt16 SfxItemSet::GetWhichByOffset( sal_uInt16 nOffset ) const
{
- sal_uInt16 n = 0;
- for( auto const & pPtr : m_pWhichRanges )
- {
- n = ( pPtr.second - pPtr.first ) + 1;
- if( nPos < n )
- return pPtr.first + nPos;
- nPos = nPos - n;
- }
- assert(false);
- return 0;
+ assert(nOffset < TotalCount());
+
+ // 1st try to get a set SfxPoolItem and fetch the WhichID from there.
+ const SfxPoolItem* pItem(nullptr);
+ GetItemState_ForOffset(nOffset, &pItem);
+
+ if (nullptr != pItem)
+ 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 m_pWhichRanges.getWhichFromOffset(nOffset);
}
bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
@@ -1214,8 +1181,8 @@ bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool bComparePool) const
// If we reach here and bDifferentPools==true that means bComparePool==false.
// Counting Ranges takes longer; they also need to be the same, however
- sal_uInt16 nCount1 = TotalCount();
- sal_uInt16 nCount2 = rCmp.TotalCount();
+ const sal_uInt16 nCount1(TotalCount());
+ const sal_uInt16 nCount2(rCmp.TotalCount());
if ( nCount1 != nCount2 )
return false;
@@ -1326,41 +1293,34 @@ SfxItemSet SfxItemSet::CloneAsValue(bool bItems, SfxItemPool *pToPool ) const
void SfxItemSet::PutDirect(const SfxPoolItem &rItem)
{
- SfxPoolItem const** ppFnd = m_ppItems;
- const sal_uInt16 nWhich = rItem.Which();
#ifdef DBG_UTIL
IsPoolDefaultItem(&rItem) || m_pPool->CheckItemInPool(&rItem);
// Only cause assertion in the callees
#endif
- for( auto const & pPtr : m_pWhichRanges)
+ const sal_uInt16 nOffset(m_pWhichRanges.getOffsetFromWhich(rItem.Which()));
+
+ if (INVALID_WHICHPAIR_OFFSET != nOffset)
{
- if( pPtr.first <= nWhich && nWhich <= pPtr.second )
+ SfxPoolItem const** ppFnd(m_ppItems + nOffset);
+ const SfxPoolItem* pOld = *ppFnd;
+ if( pOld ) // One already present
{
- // In this Range?
- ppFnd += nWhich - pPtr.first;
- const SfxPoolItem* pOld = *ppFnd;
- if( pOld ) // One already present
- {
- if( rItem == **ppFnd )
- return; // Already present!
- m_pPool->Remove( *pOld );
- }
- else
- ++m_nCount;
-
- // Add the new one
- if( IsPoolDefaultItem(&rItem) )
- *ppFnd = &m_pPool->Put( rItem );
- else
- {
- *ppFnd = &rItem;
- if( !IsStaticDefaultItem( &rItem ) )
- rItem.AddRef();
- }
+ if( rItem == **ppFnd )
+ return; // Already present!
+ m_pPool->Remove( *pOld );
+ }
+ else
+ ++m_nCount;
- return;
+ // Add the new one
+ if( IsPoolDefaultItem(&rItem) )
+ *ppFnd = &m_pPool->Put( rItem );
+ else
+ {
+ *ppFnd = &rItem;
+ if( !IsStaticDefaultItem( &rItem ) )
+ rItem.AddRef();
}
- ppFnd += pPtr.second - pPtr.first + 1;
}
}
@@ -1445,6 +1405,9 @@ WhichRangesContainer::WhichRangesContainer( const WhichPair* wids, sal_Int32 nSi
m_pairs = p;
m_size = nSize;
m_bOwnRanges = true;
+ m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+ m_aLastWhichPairFirst = 0;
+ m_aLastWhichPairSecond = 0;
}
WhichRangesContainer::WhichRangesContainer(sal_uInt16 nWhichStart, sal_uInt16 nWhichEnd)
@@ -1453,6 +1416,9 @@ WhichRangesContainer::WhichRangesContainer(sal_uInt16 nWhichStart, sal_uInt16 nW
auto p = new WhichPair[1];
p[0] = { nWhichStart, nWhichEnd };
m_pairs = p;
+ m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+ m_aLastWhichPairFirst = 0;
+ m_aLastWhichPairSecond = 0;
}
WhichRangesContainer::WhichRangesContainer(WhichRangesContainer && other)
@@ -1460,6 +1426,9 @@ WhichRangesContainer::WhichRangesContainer(WhichRangesContainer && other)
std::swap(m_pairs, other.m_pairs);
std::swap(m_size, other.m_size);
std::swap(m_bOwnRanges, other.m_bOwnRanges);
+ m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+ m_aLastWhichPairFirst = 0;
+ m_aLastWhichPairSecond = 0;
}
WhichRangesContainer& WhichRangesContainer::operator=(WhichRangesContainer && other)
@@ -1467,6 +1436,9 @@ WhichRangesContainer& WhichRangesContainer::operator=(WhichRangesContainer && ot
std::swap(m_pairs, other.m_pairs);
std::swap(m_size, other.m_size);
std::swap(m_bOwnRanges, other.m_bOwnRanges);
+ m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+ m_aLastWhichPairFirst = 0;
+ m_aLastWhichPairSecond = 0;
return *this;
}
@@ -1475,6 +1447,9 @@ WhichRangesContainer& WhichRangesContainer::operator=(WhichRangesContainer const
reset();
m_size = other.m_size;
m_bOwnRanges = other.m_bOwnRanges;
+ m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+ m_aLastWhichPairFirst = 0;
+ m_aLastWhichPairSecond = 0;
if (m_bOwnRanges)
{
auto p = new WhichPair[m_size];
@@ -1511,6 +1486,136 @@ void WhichRangesContainer::reset()
}
m_pairs = nullptr;
m_size = 0;
+ m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+ m_aLastWhichPairFirst = 0;
+ m_aLastWhichPairSecond = 0;
+}
+
+#ifdef DBG_UTIL
+static size_t g_nHit(0);
+static size_t g_nMiss(1);
+static bool g_bShowWhichRangesHitRate(getenv("SVL_SHOW_WHICHRANGES_HITRATE"));
+static void isHit() { g_nHit++; }
+static void isMiss()
+{
+ g_nMiss++;
+ const double fHitRate(double(g_nHit) /double(g_nMiss));
+ if (0 == g_nMiss % 1000 && g_bShowWhichRangesHitRate)
+ SAL_WARN("svl", "ITEM: hits: " << g_nHit << " misses: " << g_nMiss << " hits/misses(rate): " << fHitRate);
+}
+#endif
+
+sal_uInt16 WhichRangesContainer::getOffsetFromWhich(sal_uInt16 nWhich) const
+{
+ if (empty())
+ return INVALID_WHICHPAIR_OFFSET;
+
+ // special case for single entry - happens often e.g. UI stuff
+ if (1 == m_size)
+ {
+ if( m_pairs->first <= nWhich && nWhich <= m_pairs->second )
+ return nWhich - m_pairs->first;
+
+ // we have only one WhichPair entry and it's not contained -> failed
+ return INVALID_WHICHPAIR_OFFSET;
+ }
+
+ // check if nWhich is inside last sucessfully used WhichPair
+ if (INVALID_WHICHPAIR_OFFSET != m_aLastWhichPairOffset
+ && m_aLastWhichPairFirst <= nWhich
+ && nWhich <= m_aLastWhichPairSecond)
+ {
+#ifdef DBG_UTIL
+ isHit();
+#endif
+ // we can re-use the last found WhichPair
+ return m_aLastWhichPairOffset + (nWhich - m_aLastWhichPairFirst);
+ }
+
+#ifdef DBG_UTIL
+ isMiss();
+#endif
+
+ // we have to find the correct WhichPair, iterate linear. This
+ // also directly updates the buffered m_aLastWhichPair* values
+ m_aLastWhichPairOffset = 0;
+
+ for (const WhichPair& rPair : *this)
+ {
+ // Within this range?
+ if( rPair.first <= nWhich && nWhich <= rPair.second )
+ {
+ // found, remember parameters for buffered hits
+ m_aLastWhichPairFirst = rPair.first;
+ m_aLastWhichPairSecond = rPair.second;
+
+ // ...and return
+ return m_aLastWhichPairOffset + (nWhich - m_aLastWhichPairFirst);
+ }
+
+ m_aLastWhichPairOffset += rPair.second - rPair.first + 1;
+ }
+
+ // *need* to reset: if 1st WhichPair only one entry it could be 1
+ // 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
+{
+ // check for empty, if yes, return null which is an invalid WhichID
+ if (empty())
+ return 0;
+
+ // special case for single entry - happens often e.g. UI stuff
+ if (1 == m_size)
+ {
+ 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 if nWhich is inside last sucessfully 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 potetially 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;
}
// Adds a range to which ranges, keeping the ranges in valid state (sorted, non-overlapping)
@@ -1522,6 +1627,8 @@ WhichRangesContainer WhichRangesContainer::MergeRange(sal_uInt16 nFrom,
if (empty())
return WhichRangesContainer(nFrom, nTo);
+ m_aLastWhichPairOffset = INVALID_WHICHPAIR_OFFSET;
+
// create vector of ranges (sal_uInt16 pairs of lower and upper bound)
const size_t nOldCount = size();
// Allocate one item more than we already have.
diff --git a/svl/source/items/whiter.cxx b/svl/source/items/whiter.cxx
index c89c6ed2794b..13915415df08 100644
--- a/svl/source/items/whiter.cxx
+++ b/svl/source/items/whiter.cxx
@@ -65,16 +65,29 @@ sal_uInt16 SfxWhichIter::FirstWhich()
SfxItemState SfxWhichIter::GetItemState(bool bSrchInParent, const SfxPoolItem** ppItem) const
{
- sal_uInt16 nWhich = m_pCurrentWhichPair->first + m_nOffsetFromStartOfCurrentWhichPair;
- sal_uInt16 nItemsOffsetHint = m_nItemsOffset + m_nOffsetFromStartOfCurrentWhichPair;
- return m_rItemSet.GetItemStateImpl(nWhich, bSrchInParent, ppItem, nItemsOffsetHint);
+ const sal_uInt16 nOffset(m_nItemsOffset + m_nOffsetFromStartOfCurrentWhichPair);
+
+ // we have the offset, so use it to profit. It is always valid, so no need
+ // to check if smaller than TotalCount()
+ SfxItemState eState(m_rItemSet.GetItemState_ForOffset(nOffset, ppItem));
+
+ // search in parent?
+ if (bSrchInParent && nullptr != m_rItemSet.GetParent() && (SfxItemState::UNKNOWN == eState || SfxItemState::DEFAULT == eState))
+ {
+ // nOffset was only valid for *local* SfxItemSet, need to continue with WhichID
+ // Use the *highest* SfxItemState as result
+ const sal_uInt16 nWhich(m_pCurrentWhichPair->first + m_nOffsetFromStartOfCurrentWhichPair);
+ return m_rItemSet.GetParent()->GetItemState_ForWhichID( eState, nWhich, true, ppItem);
+ }
+
+ return eState;
}
void SfxWhichIter::ClearItem()
{
- sal_uInt16 nWhich = m_pCurrentWhichPair->first + m_nOffsetFromStartOfCurrentWhichPair;
- sal_uInt16 nItemOffsetHint = m_nItemsOffset + m_nOffsetFromStartOfCurrentWhichPair;
- const_cast<SfxItemSet&>(m_rItemSet).ClearSingleItemImpl(nWhich, nItemOffsetHint);
+ // we have the offset, so use it to profit. It is always valid, so no need
+ // to check if smaller than TotalCount()
+ const_cast<SfxItemSet&>(m_rItemSet).ClearSingleItem_ForOffset(m_nItemsOffset + m_nOffsetFromStartOfCurrentWhichPair);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/dialog/srchdlg.cxx b/svx/source/dialog/srchdlg.cxx
index 1e0bcd36a944..7f496535e2b7 100644
--- a/svx/source/dialog/srchdlg.cxx
+++ b/svx/source/dialog/srchdlg.cxx
@@ -211,7 +211,7 @@ void SearchAttrItemList::Put( const SfxItemSet& rSet )
// only test that it is available?
if( IsInvalidItem( pItem ) )
{
- nWhich = rSet.GetWhichByPos( aIter.GetCurPos() );
+ nWhich = rSet.GetWhichByOffset( aIter.GetCurPos() );
aItem.pItem = const_cast<SfxPoolItem*>(pItem);
}
else
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index 29c5c8f7ef71..9492cfdd6c70 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -221,8 +221,8 @@ SwAttrCheckArr::SwAttrCheckArr( const SfxItemSet& rSet, bool bFwd,
// determine area of Fnd/Stack array (Min/Max)
SfxItemIter aIter( m_aComapeSet );
- m_nArrStart = m_aComapeSet.GetWhichByPos( aIter.GetFirstPos() );
- m_nArrLen = m_aComapeSet.GetWhichByPos( aIter.GetLastPos() ) - m_nArrStart+1;
+ m_nArrStart = m_aComapeSet.GetWhichByOffset( aIter.GetFirstPos() );
+ m_nArrLen = m_aComapeSet.GetWhichByOffset( aIter.GetLastPos() ) - m_nArrStart+1;
char* pFndChar = new char[ m_nArrLen * sizeof(SwSrchChrAttr) ];
char* pStackChar = new char[ m_nArrLen * sizeof(SwSrchChrAttr) ];
@@ -273,7 +273,7 @@ void SwAttrCheckArr::SetNewSet( const SwTextNode& rTextNd, const SwPaM& rPam )
{
if( IsInvalidItem( pItem ) )
{
- nWhich = m_aComapeSet.GetWhichByPos( aIter.GetCurPos() );
+ nWhich = m_aComapeSet.GetWhichByOffset( aIter.GetCurPos() );
if( RES_TXTATR_END <= nWhich )
break; // end of text attributes
@@ -887,7 +887,7 @@ static bool lcl_Search( const SwContentNode& rCNd, const SfxItemSet& rCmpSet, bo
{
if( IsInvalidItem( pItem ))
{
- nWhich = rCmpSet.GetWhichByPos( aIter.GetCurPos() );
+ nWhich = rCmpSet.GetWhichByOffset( aIter.GetCurPos() );
if( SfxItemState::SET != rNdSet.GetItemState( nWhich, !bNoColls, &pNdItem )
|| CmpAttr( *pNdItem, rNdSet.GetPool()->GetDefaultItem( nWhich ) ))
return false;
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 898590d6201b..75c5ba1ccc10 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -436,7 +436,7 @@ namespace
{
for( sal_uInt16 nItem = 0; nItem < aTmp.TotalCount(); ++nItem)
{
- sal_uInt16 nWhich = aTmp.GetWhichByPos(nItem);
+ sal_uInt16 nWhich = aTmp.GetWhichByOffset(nItem);
if( SfxItemState::SET == aTmp.GetItemState( nWhich, false ) &&
SfxItemState::SET != aTmp2.GetItemState( nWhich, false ) )
aTmp2.Put( aTmp.GetPool()->GetDefaultItem(nWhich), nWhich );
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 8eea1b74f11e..19a2bffbf562 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -2568,7 +2568,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwContentIndex & rDest
{
// check current item
const sal_uInt16 nWhich = IsInvalidItem( pItem )
- ? pDest->GetpSwAttrSet()->GetWhichByPos( aIter.GetCurPos() )
+ ? pDest->GetpSwAttrSet()->GetWhichByOffset( aIter.GetCurPos() )
: pItem->Which();
if( RES_FRMATR_STYLE_NAME != nWhich &&
RES_FRMATR_CONDITIONAL_STYLE_NAME != nWhich &&
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx
index 6db3d9315114..781c5555a6f6 100644
--- a/sw/source/core/undo/undobj1.cxx
+++ b/sw/source/core/undo/undobj1.cxx
@@ -572,7 +572,7 @@ void SwUndoSetFlyFormat::UndoImpl(::sw::UndoRedoContext & rContext)
for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
{
if( IsInvalidItem( pItem ))
- m_pFrameFormat->ResetFormatAttr( m_oItemSet->GetWhichByPos(
+ m_pFrameFormat->ResetFormatAttr( m_oItemSet->GetWhichByOffset(
aIter.GetCurPos() ));
else
m_pFrameFormat->SetFormatAttr( *pItem );
diff --git a/sw/source/filter/ww8/writerhelper.cxx b/sw/source/filter/ww8/writerhelper.cxx
index 528859565667..86cf8d622200 100644
--- a/sw/source/filter/ww8/writerhelper.cxx
+++ b/sw/source/filter/ww8/writerhelper.cxx
@@ -385,7 +385,7 @@ namespace sw
for( sal_uInt16 nItem =0; nItem < nTotal; ++nItem )
{
const SfxPoolItem* pItem = nullptr;
- if( SfxItemState::SET == rSet.GetItemState( rSet.GetWhichByPos( nItem ), true, &pItem ) )
+ if( SfxItemState::SET == rSet.GetItemState( rSet.GetWhichByOffset( nItem ), true, &pItem ) )
{
rItems[pItem->Which()] = pItem;
}
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index 456aae85c5e9..52f9253252b0 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -1848,7 +1848,7 @@ void SwDocStyleSheet::SetItemSet( const SfxItemSet& rSet, const bool bBroadcast,
{
// use method <SwDoc::ResetAttrAtFormat(..)> in order to
// create an Undo object for the attribute reset.
- aWhichIdsToReset.emplace_back(rSet.GetWhichByPos(aIter.GetCurPos()));
+ aWhichIdsToReset.emplace_back(rSet.GetWhichByOffset(aIter.GetCurPos()));
}
pItem = aIter.NextItem();
diff --git a/sw/source/uibase/uiview/srcview.cxx b/sw/source/uibase/uiview/srcview.cxx
index 0a936b67f311..8ebae23d3d4b 100644
--- a/sw/source/uibase/uiview/srcview.cxx
+++ b/sw/source/uibase/uiview/srcview.cxx
@@ -334,7 +334,7 @@ void SwSrcView::Execute(SfxRequest& rReq)
{
const SfxItemSet* pTmpArgs = rReq.GetArgs();
- const sal_uInt16 nWhich = pTmpArgs->GetWhichByPos( 0 );
+ const sal_uInt16 nWhich = pTmpArgs->GetWhichByOffset( 0 );
OSL_ENSURE( nWhich, "Which for SearchItem ?" );
const SfxPoolItem& rItem = pTmpArgs->Get( nWhich );
SetSearchItem( static_cast<const SvxSearchItem&>(rItem));