24#include <libxml/xmlwriter.h>
26#include <osl/diagnose.h>
38#if OSL_DEBUG_LEVEL > 0
47 if (rPool.
GetName() ==
"EditEngineItemPool")
53 sal_uInt16
const nSlotId(pInfo[
n]._nSID);
61 std::map<sal_uInt16, sal_uInt16>::const_iterator
const iter(
62 rSlotMap.find(nSlotId));
63 sal_uInt16
const nWhich(nFirst +
n);
64 if (iter != rSlotMap.end())
66 SAL_WARN(
"svl",
"SfxItemPool: duplicate SlotId " << nSlotId
67 <<
" mapped to " << iter->second <<
" and " << nWhich);
70 rSlotMap.insert(std::make_pair(nSlotId, nWhich));
75#define CHECK_SLOTS() \
77 std::map<sal_uInt16, sal_uInt16> slotmap; \
78 for (SfxItemPool * p = pImpl->mpMaster; p; p = p->pImpl->mpSecondary.get()) \
80 lcl_CheckSlots2(slotmap, *p, p->pItemInfos); \
85#define CHECK_SLOTS() do {} while (false)
99 return pImpl->mnStart;
109 return nWhich >=
pImpl->mnStart && nWhich <=
pImpl->mnEnd;
116 assert(
false &&
"missing bounds check before use");
119 return nWhich -
pImpl->mnStart;
130 DBG_ASSERT( pItem,
"no 0-Pointer Surrogate" );
136 if (
pImpl->mpSecondary )
137 return pImpl->mpSecondary->CheckItemInPool( pItem );
138 SAL_WARN(
"svl.items",
"unknown Which-Id - don't ask me for surrogates, with ID/pos " << pItem->
Which());
147 for (
auto p : rItemArr )
152 SAL_WARN(
"svl.items",
"Item not in the pool, with ID/pos " << pItem->
Which());
161 else if(
pImpl->mpSecondary )
162 pRet =
pImpl->mpSecondary->GetPoolDefaultItem( nWhich );
165 assert(
false &&
"unknown WhichId - cannot get pool default");
180 for (
const SfxItemPool *pPool =
this; pPool; pPool = pPool->
pImpl->mpSecondary.get() )
182 if ( pPool->IsInRange(nWhich) )
183 return pPool->IsItemPoolable_Impl( pPool->GetIndex_Impl(nWhich));
220 const OUString& rName,
221 sal_uInt16 nStartWhich,
222 sal_uInt16 nEndWhich,
224 std::vector<SfxPoolItem*>*
232 pImpl->eDefMetric = MapUnit::MapTwip;
241 auto nWhich = nStartWhich;
242 while (nWhich <= nEndWhich)
244 if (
p->_nSID == nWhich)
246 SAL_WARN(
"svl.items",
"No point mapping a SID to itself, just put a 0 here in the SfxItemInfo array, at index " << (
p -
pItemInfos));
265 bool bCloneStaticDefaults
272 pItemInfos(rPool.pItemInfos),
278 if ( bCloneStaticDefaults )
280 std::vector<SfxPoolItem *>* ppDefaults =
new std::vector<SfxPoolItem*>(
pImpl->mnEnd-
pImpl->mnStart+1);
281 for ( sal_uInt16
n = 0;
n <=
pImpl->mnEnd -
pImpl->mnStart; ++
n )
283 (*ppDefaults)[
n] = (*rPool.
pImpl->mpStaticDefaults)[
n]->
Clone(
this);
293 for (
size_t n = 0;
n <
pImpl->maPoolDefaults.size(); ++
n )
294 if (rPool.
pImpl->maPoolDefaults[
n])
296 pImpl->maPoolDefaults[
n] = rPool.
pImpl->maPoolDefaults[
n]->Clone(
this);
301 if ( rPool.
pImpl->mpSecondary )
307 DBG_ASSERT( pDefaults,
"first we ask for it, and then we don't give back..." );
310 pImpl->mpStaticDefaults = pDefaults;
316 "these are not static" );
317 for ( sal_uInt16
n = 0;
n <=
pImpl->mnEnd -
pImpl->mnStart; ++
n )
319 assert( ((*
pImpl->mpStaticDefaults)[
n]->Which() ==
n +
pImpl->mnStart)
320 &&
"items ids in pool-ranges and in static-defaults do not match" );
322 DBG_ASSERT(
pImpl->maPoolItemArrays[
n].empty(),
"defaults with setitems with items?!" );
329 pImpl->mpStaticDefaults =
nullptr;
355 pImpl->mpStaticDefaults =
nullptr;
368 std::vector<SfxPoolItem*>*
380 DBG_ASSERT( pDefaults,
"we first ask for it and the return nothing ..." );
382 for (
auto & rpItem : *pDefaults )
385 rpItem->SetRefCount(0);
403 if ( !
pImpl->maPoolItemArrays.empty() && !
pImpl->maPoolDefaults.empty() )
406 if (
pImpl->mpMaster !=
nullptr &&
pImpl->mpMaster !=
this)
412 DBG_ASSERT(
pImpl->mpMaster ==
this,
"destroying active Secondary-Pool" );
413 if (
pImpl->mpMaster->pImpl->mpSecondary ==
this)
414 pImpl->mpMaster->pImpl->mpSecondary =
nullptr;
421 if (
pImpl->mpSecondary )
424 if (
pImpl->mpStaticDefaults !=
nullptr && !
pImpl->maPoolItemArrays.empty()
425 && !
pImpl->mpSecondary->pImpl->maPoolItemArrays.empty())
429 bool bHasSetItems =
false;
430 for ( sal_uInt16
i = 0; !bHasSetItems &&
i <
pImpl->mnEnd -
pImpl->mnStart; ++
i )
431 bHasSetItems =
dynamic_cast<const SfxSetItem *
>((*
pImpl->mpStaticDefaults)[
i]) !=
nullptr;
434 bool bOK = bHasSetItems;
435 for (
auto const& rSecArray :
pImpl->mpSecondary->pImpl->maPoolItemArrays)
439 if (rSecArray.size()>0)
441 SAL_WARN(
"svl.items",
"old secondary pool: " <<
pImpl->mpSecondary->pImpl->aName
442 <<
" of pool: " <<
pImpl->aName <<
" must be empty.");
449 pImpl->mpSecondary->pImpl->mpMaster =
pImpl->mpSecondary.get();
450 for (
SfxItemPool *
p =
pImpl->mpSecondary->pImpl->mpSecondary.get();
p;
p =
p->pImpl->mpSecondary.get() )
451 p->pImpl->mpMaster =
pImpl->mpSecondary.get();
455 DBG_ASSERT( !pPool || pPool->
pImpl->mpMaster == pPool,
"Secondary is present in two Pools" );
458 p->pImpl->mpMaster = pNewMaster;
461 pImpl->mpSecondary = pPool;
475 return pImpl->eDefMetric;
482 pImpl->eDefMetric = eNewMetric;
487 return pImpl->eDefMetric;
518 if (
pImpl->maPoolItemArrays.empty() ||
pImpl->maPoolDefaults.empty())
525 if (
pImpl->mpStaticDefaults !=
nullptr) {
532 if (
dynamic_cast<const SfxSetItem*
>(pStaticDefaultItem))
535 auto& rArray =
pImpl->maPoolItemArrays[
n];
536 for (
auto& rItemPtr : rArray)
538 ReleaseRef(*rItemPtr, rItemPtr->GetRefCount());
543 auto& rItemPtr =
pImpl->maPoolDefaults[
n];
557 for (
auto& rArray :
pImpl->maPoolItemArrays)
559 for (
auto& rItemPtr : rArray)
561 ReleaseRef(*rItemPtr, rItemPtr->GetRefCount());
567 pImpl->maPoolItemArrays.clear();
569 for (
auto rItemPtr :
pImpl->maPoolDefaults)
581 pImpl->DeleteItems();
595 rOldDefault->SetRefCount(0);
597 rOldDefault =
nullptr;
599 rOldDefault = pNewDefault;
601 else if (
pImpl->mpSecondary )
602 pImpl->mpSecondary->SetPoolDefaultItem(rItem);
605 assert(
false &&
"unknown WhichId - cannot set pool default");
621 rOldDefault->SetRefCount(0);
623 rOldDefault =
nullptr;
626 else if (
pImpl->mpSecondary )
627 pImpl->mpSecondary->ResetPoolDefaultItem(nWhichId);
630 assert(
false &&
"unknown WhichId - cannot reset pool default");
638 nWhich = rItem.
Which();
641 bool bSID =
IsSlot(nWhich);
644 if (
pImpl->mpSecondary )
645 return pImpl->mpSecondary->PutImpl( rItem, nWhich, bPassingOwnership );
646 OSL_FAIL(
"unknown WhichId - cannot put item" );
652 assert((rItem.
Which() != nWhich ||
654 &&
"a non Pool Item is Default?!");
658 if (bPassingOwnership)
663 assert(!
pImpl->mpStaticDefaults ||
678 if (it != rItemArr.
end())
681 assert(!bPassingOwnership &&
"can't be passing ownership and have the item already in the pool");
692 assert(*pFoundItem == rItem);
697 if( it != rItemArr.
end())
702 for (
auto it = rItemArr.
begin(); it != rItemArr.
end(); ++it)
713 assert((!bPassingOwnership || (&rItem != pFoundItem)) &&
"can't be passing ownership and have the item already in the pool");
715 if (bPassingOwnership)
723 if (bPassingOwnership)
726 if (
auto pSetItem =
dynamic_cast<const SfxSetItem*
>(&rItem))
727 assert(pSetItem->GetItemSet().GetPool() ==
pImpl->mpMaster &&
"can't pass ownership of SfxSetItem, unless they have been cloned to the master pool");
734 assert(
typeid(rItem) ==
typeid(*pNewItem) &&
"SfxItemPool::Put(): unequal types, no Clone() override?");
736 if (
dynamic_cast<const SfxSetItem*
>(&rItem) ==
nullptr)
739 &&
"SfxItemPool::Put(): unequal items: no operator== override?");
741 &&
"SfxItemPool::Put(): unequal items: no operator== override?");
747 rItemArr.
insert( pNewItem );
756 const sal_uInt16 nWhich = rItem.
Which();
757 bool bSID =
IsSlot(nWhich);
760 if (
pImpl->mpSecondary )
762 pImpl->mpSecondary->Remove( rItem );
765 OSL_FAIL(
"unknown WhichId - cannot remove item" );
771 assert(!
IsDefaultItem(&rItem) &&
"a non Pool Item is Default?!");
779 assert(rItem.
GetRefCount() &&
"RefCount == 0, Remove impossible");
791 if (it != rItemArr.
end())
797 assert(
false &&
"removing Item without ref");
812 assert(
false &&
"removing Item not in Pool");
820 if (
pImpl->mpSecondary )
821 return pImpl->mpSecondary->GetDefaultItem( nWhich );
822 assert(!
"unknown which - don't ask me for defaults");
825 DBG_ASSERT(
pImpl->mpStaticDefaults,
"no defaults known - don't ask me for defaults" );
830 return *(*
pImpl->mpStaticDefaults)[
nPos];
835 return pImpl->mpSecondary.get();
849 return pImpl->mpMaster;
861 assert(
pImpl->mpPoolRanges.empty() &&
"pool already frozen, cannot freeze twice");
868 DBG_ASSERT(
pImpl->mpPoolRanges.empty(),
"GetFrozenRanges() would be faster!" );
870 pWhichRanges.
reset();
873 for (
const SfxItemPool* pPool =
this; pPool; pPool = pPool->
pImpl->mpSecondary.get())
874 pWhichRanges = pWhichRanges.
MergeRange(pPool->pImpl->mnStart, pPool->pImpl->mnEnd);
879 return pImpl->mpPoolRanges;
886 if (
pImpl->mpSecondary )
887 return pImpl->mpSecondary->GetItem2Default( nWhich );
888 assert(
false &&
"unknown WhichId - cannot resolve surrogate");
900 if (
pImpl->mpSecondary )
901 return pImpl->mpSecondary->GetItemSurrogates( nWhich );
902 assert(
false &&
"unknown WhichId - cannot resolve surrogate");
907 return { rItemArr.
begin(), rItemArr.
end() };
915 if (
pImpl->mpSecondary )
916 return pImpl->mpSecondary->FindItemSurrogate( nWhich, rSample );
917 assert(
false &&
"unknown WhichId - cannot resolve surrogate");
918 return std::vector<const SfxPoolItem*>();
929 if (
pImpl->mpSecondary )
930 return pImpl->mpSecondary->GetItemCount2( nWhich );
931 assert(
false &&
"unknown WhichId - cannot resolve surrogate");
936 return rItemArr.
size();
946 for ( sal_uInt16 nOfs = 0; nOfs <
nCount; ++nOfs )
948 return nOfs +
pImpl->mnStart;
949 if (
pImpl->mpSecondary && bDeep )
950 return pImpl->mpSecondary->GetWhich(nSlotId);
962 if (
pImpl->mpSecondary )
963 return pImpl->mpSecondary->GetSlotId(nWhich);
964 assert(
false &&
"unknown WhichId - cannot get slot-id");
969 return nSID ? nSID : nWhich;
979 for ( sal_uInt16 nOfs = 0; nOfs <
nCount; ++nOfs )
981 return nOfs +
pImpl->mnStart;
982 if (
pImpl->mpSecondary && bDeep )
983 return pImpl->mpSecondary->GetTrueWhich(nSlotId);
995 if (
pImpl->mpSecondary )
996 return pImpl->mpSecondary->GetTrueSlotId(nWhich);
997 assert(
false &&
"unknown WhichId - cannot get slot-id");
1005 (void)xmlTextWriterStartElement(pWriter, BAD_CAST(
"SfxItemPool"));
1006 for (
auto const & rArray :
pImpl->maPoolItemArrays)
1007 for (
auto const & rItem : rArray)
1008 rItem->dumpAsXml(pWriter);
1009 (void)xmlTextWriterEndElement(pWriter);
Base class for providers of defaults of SfxPoolItems.
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
const WhichRangesContainer & GetFrozenIdRanges() const
SfxItemPool * GetSecondaryPool() const
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
const SfxItemInfo * pItemInfos
void ResetPoolDefaultItem(sal_uInt16 nWhich)
Resets the default of the given WhichId back to the static Default.
bool IsItemPoolable(sal_uInt16 nWhich) const
void dumpAsXml(xmlTextWriterPtr pWriter) const
void FreezeIdRanges()
This method should be called at the master pool, when all secondary pools are appended to it.
const OUString & GetName() const
static void ClearRefCount(SfxPoolItem &rItem)
bool CheckItemInPool(const SfxPoolItem *) const
const SfxPoolItem * GetPoolDefaultItem(sal_uInt16 nWhich) const
sal_uInt16 GetSlotId(sal_uInt16 nWhich) const
sal_uInt16 GetTrueSlotId(sal_uInt16 nWhich) const
void SetDefaults(std::vector< SfxPoolItem * > *pDefaults)
SfxItemPool(const SfxItemPool &rPool, bool bCloneStaticDefaults=false)
Copy ctor.
static void AddRef(const SfxPoolItem &rItem)
sal_uInt16 GetTrueWhich(sal_uInt16 nSlot, bool bDeep=true) const
static bool IsWhich(sal_uInt16 nId)
std::unique_ptr< SfxItemPool_Impl > pImpl
void SetPoolDefaultItem(const SfxPoolItem &)
SfxItemPool * GetLastPoolInChain()
SVL_DLLPRIVATE bool IsItemPoolable_Impl(sal_uInt16 nWhich) const
void SetItemInfos(const SfxItemInfo *pInfos)
bool IsInRange(sal_uInt16 nWhich) const
void Remove(const SfxPoolItem &)
sal_uInt16 GetLastWhich() const
static bool IsSlot(sal_uInt16 nId)
sal_uInt16 GetSize_Impl() const
virtual const SfxPoolItem & PutImpl(const SfxPoolItem &, sal_uInt16 nWhich=0, bool bPassingOwnership=false)
virtual bool GetPresentation(const SfxPoolItem &rItem, MapUnit ePresentationMetric, OUString &rText, const IntlWrapper &rIntlWrapper) const
Request string representation of pool items.
std::vector< const SfxPoolItem * > FindItemSurrogate(sal_uInt16 nWhich, SfxPoolItem const &rNeedle) const
void ReleaseDefaults(bool bDelete=false)
Frees the static Defaults of the corresponding SfxItemPool instance and deletes them if specified.
sal_uInt16 GetFirstWhich() const
const SfxPoolItem * GetItem2Default(sal_uInt16 nWhich) const
void SetDefaultMetric(MapUnit eNewMetric)
void SetSecondaryPool(SfxItemPool *pPool)
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
MapUnit GetDefaultMetric() const
virtual rtl::Reference< SfxItemPool > Clone() const
sal_uInt16 GetIndex_Impl(sal_uInt16 nWhich) const
static sal_uInt32 ReleaseRef(const SfxPoolItem &rItem, sal_uInt32 n=1)
void FillItemIdRanges_Impl(WhichRangesContainer &pWhichRanges) const
SfxItemPool * GetMasterPool() const
sal_uInt32 GetItemCount2(sal_uInt16 nWhich) const
void SetKind(SfxItemKind n)
virtual bool GetPresentation(SfxItemPresentation ePresentation, MapUnit eCoreMetric, MapUnit ePresentationMetric, OUString &rText, const IntlWrapper &rIntlWrapper) const
This virtual method allows to get a textual representation of the value for the SfxPoolItem subclasse...
sal_uInt32 GetRefCount() const
virtual bool HasLookup() const
virtual lookup_iterator Lookup(lookup_iterator, lookup_iterator end) const
virtual bool IsSortable() const
void SetWhich(sal_uInt16 nId)
SfxItemKind GetKind() const
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
#define DBG_ASSERT(sCon, aError)
struct _xmlTextWriter * xmlTextWriterPtr
static void lcl_CheckSlots2(std::map< sal_uInt16, sal_uInt16 > &rSlotMap, SfxItemPool const &rPool, SfxItemInfo const *pInfo)
#define SAL_WARN(area, stream)
constexpr OUStringLiteral EMPTY
bool IsPoolDefaultItem(const SfxPoolItem *pItem)
bool IsDefaultItem(const SfxPoolItem *pItem)
bool IsInvalidItem(const SfxPoolItem *pItem)
bool IsPooledItem(const SfxPoolItem *pItem)
bool IsStaticDefaultItem(const SfxPoolItem *pItem)
This array contains a set of SfxPoolItems, if those items are poolable then each item has a unique se...
std::vector< SfxPoolItem * > maSortablePoolItems
o3tl::sorted_vector< SfxPoolItem * > maPoolItemSet
o3tl::sorted_vector< SfxPoolItem * >::const_iterator find(SfxPoolItem *pItem) const
void insert(SfxPoolItem *pItem)
o3tl::sorted_vector< SfxPoolItem * >::const_iterator begin() const
const SfxPoolItem * findByLessThan(const SfxPoolItem *pNeedle) const
o3tl::sorted_vector< SfxPoolItem * >::const_iterator end() const
std::vector< const SfxPoolItem * > findSurrogateRange(const SfxPoolItem *pNeedle) const
void clear()
clear array of PoolItem variants after all PoolItems are deleted or all ref counts are decreased
void erase(o3tl::sorted_vector< SfxPoolItem * >::const_iterator it)
Most of the time, the which ranges we point at are a compile-time literal.
SAL_WARN_UNUSED_RESULT WhichRangesContainer MergeRange(sal_uInt16 nFrom, sal_uInt16 nTo) const