38 std::vector<std::unique_ptr<Node>> mChildren;
41 std::vector< std::shared_ptr<SfxItemSet> >
maItemSet;
42 std::unique_ptr<const SfxPoolItem> mpItem;
45 const bool mbIsItemIgnorable;
50 mbIsItemIgnorable( false )
53 : mpItem( rItem.
Clone() ),
55 mbIsItemIgnorable( bIgnorable )
58 bool hasItemSet(
const bool bCheckUsage )
const;
60 std::shared_ptr<SfxItemSet>
const & getItemSet()
const
64 std::shared_ptr<SfxItemSet>
const & getUsedOrLastAddedItemSet()
const;
68 const bool bIsItemIgnorable );
69 Node* nextItemSet(
Node const * pLast,
70 const bool bSkipUnusedItemSet,
71 const bool bSkipIgnorable );
73 bool hasIgnorableChildren(
const bool bCheckUsage )
const;
74 std::shared_ptr<SfxItemSet> getItemSetOfIgnorableChild(
75 const bool bSkipUnusedItemSets )
const;
79 std::shared_ptr<SfxItemSet>
const & Node::getUsedOrLastAddedItemSet()
const
82 [](
const std::shared_ptr<SfxItemSet>& rxItemSet) { return rxItemSet.use_count() > 1; });
91 bool Node::hasItemSet(
const bool bCheckUsage )
const
93 bool bHasItemSet =
false;
100 [](
const std::shared_ptr<SfxItemSet>& rxItemSet) { return rxItemSet.use_count() > 1; });
112 const bool bIsItemIgnorable )
114 for(
auto const & rChild : mChildren )
116 if( rItem.
Which() == rChild->mpItem->Which() &&
117 rItem == *rChild->mpItem )
121 auto pNextNode =
new Node( rItem,
this, bIsItemIgnorable );
122 mChildren.emplace_back( pNextNode );
143 Node* Node::nextItemSet(
Node const * pLast,
144 const bool bSkipUnusedItemSets,
145 const bool bSkipIgnorable )
148 auto aIter = mChildren.begin();
151 if( pLast && pLast !=
this )
153 aIter = std::find_if( mChildren.begin(), mChildren.end(),
154 [&] (std::unique_ptr<Node>
const &p) { return p.get() == pLast; });
155 if( aIter != mChildren.end() )
158 Node *pNext =
nullptr;
159 while( aIter != mChildren.end() )
162 if ( bSkipIgnorable && (*aIter)->mbIsItemIgnorable )
167 pNext = aIter->get();
169 if ( pNext->hasItemSet( bSkipUnusedItemSets ) )
173 if ( bSkipIgnorable &&
174 pNext->hasIgnorableChildren( bSkipUnusedItemSets ) )
178 pNext = pNext->nextItemSet(
nullptr, bSkipUnusedItemSets, bSkipIgnorable );
184 if( pLast && mpUpper )
187 pNext = mpUpper->nextItemSet(
this, bSkipUnusedItemSets, bSkipIgnorable );
193 bool Node::hasIgnorableChildren(
const bool bCheckUsage )
const
195 return std::any_of(mChildren.begin(), mChildren.end(),
196 [&bCheckUsage](
const std::unique_ptr<Node>& rxChild) {
197 Node* pChild = rxChild.get();
198 return pChild->mbIsItemIgnorable &&
200 ( pChild->hasItemSet( bCheckUsage ) ||
201 pChild->hasIgnorableChildren( bCheckUsage ) ));
205 std::shared_ptr<SfxItemSet> Node::getItemSetOfIgnorableChild(
206 const bool bSkipUnusedItemSets )
const
208 DBG_ASSERT( hasIgnorableChildren( bSkipUnusedItemSets ),
209 "<Node::getItemSetOfIgnorableChild> - node has no ignorable children" );
211 for(
const auto& rxChild : mChildren )
213 Node* pChild = rxChild.get();
214 if ( pChild->mbIsItemIgnorable )
216 if ( pChild->hasItemSet( bSkipUnusedItemSets ) )
218 return pChild->getUsedOrLastAddedItemSet();
222 pChild = pChild->nextItemSet(
nullptr, bSkipUnusedItemSets,
false );
225 return pChild->getUsedOrLastAddedItemSet();
231 std::shared_ptr<SfxItemSet> pReturn;
237 std::map< const SfxItemSet*, Node >& mrRoot;
238 std::map< const SfxItemSet*, Node >::iterator mpCurrNode;
240 const bool mbSkipUnusedItemSets;
241 const bool mbSkipIgnorable;
243 std::vector<const SfxItemSet*> maParents;
245 std::vector<const SfxItemSet*>::iterator mpCurrParent;
248 Iterator( std::map< const SfxItemSet*, Node >& rR,
249 const bool bSkipUnusedItemSets,
250 const bool bSkipIgnorable,
251 const std::map< const SfxItemSet*, OUString>& rParentNames )
254 mbSkipUnusedItemSets( bSkipUnusedItemSets ),
255 mbSkipIgnorable( bSkipIgnorable )
258 for (
const auto& rParent : mrRoot)
259 maParents.push_back(rParent.first);
262 if (!rParentNames.empty())
264 std::stable_sort(maParents.begin(), maParents.end(),
268 auto it = rParentNames.find(pA);
269 if (it != rParentNames.end())
271 it = rParentNames.find(pB);
272 if (it != rParentNames.end())
279 mpCurrParent = maParents.begin();
280 if (mpCurrParent != maParents.end())
281 mpCurrNode = mrRoot.find(*mpCurrParent);
283 virtual std::shared_ptr<SfxItemSet>
getNext()
override;
286 std::shared_ptr<SfxItemSet> Iterator::getNext()
288 std::shared_ptr<SfxItemSet> pReturn;
289 while( mpNode || mpCurrParent != maParents.end() )
293 mpNode = &mpCurrNode->second;
296 if (mpCurrParent != maParents.end())
297 mpCurrNode = mrRoot.find(*mpCurrParent);
299 if (
mpNode->hasItemSet( mbSkipUnusedItemSets ) )
302 return mpNode->getUsedOrLastAddedItemSet();
306 mpNode =
mpNode->nextItemSet( mpNode, mbSkipUnusedItemSets, mbSkipIgnorable );
307 if ( mpNode &&
mpNode->hasItemSet( mbSkipUnusedItemSets ) )
310 return mpNode->getUsedOrLastAddedItemSet();
312 if ( mbSkipIgnorable &&
313 mpNode &&
mpNode->hasIgnorableChildren( mbSkipUnusedItemSets ) )
315 return mpNode->getItemSetOfIgnorableChild( mbSkipUnusedItemSets );
329 return OUString::number(
reinterpret_cast<sal_IntPtr
>( pSet.get() ), 16 );
341 std::map< const SfxItemSet*, Node >
maRoot;
357 ? pIgnorableItems->
Clone( false )
361 "<StylePoolImpl::StylePoolImpl(..)> - misusage: item set for ignorable item should be empty. Please correct usage." );
363 "<StylePoolImpl::StylePoolImpl(..)> - <SfxItemSet::Clone( sal_False )> does not work as expected - <mpIgnorableItems> is not empty." );
369 std::unique_ptr<IStylePoolIteratorAccess>
createIterator(
bool bSkipUnusedItemSets,
370 bool bSkipIgnorableItems );
376 bool bNonPoolable =
false;
385 std::optional<SfxItemSet> xFoundIgnorableItems;
394 if (!xFoundIgnorableItems || (xFoundIgnorableItems->Put(*pItem) ==
nullptr))
396 pCurNode = pCurNode->findChildNode( *pItem,
false );
400 if ( xFoundIgnorableItems && xFoundIgnorableItems->Count() > 0 )
402 SfxItemIter aIgnorableItemsIter( *xFoundIgnorableItems );
408 pCurNode = pCurNode->findChildNode( *pItem,
true );
409 pItem = aIgnorableItemsIter.
NextItem();
415 if( !pCurNode->hasItemSet(
false ) )
417 pCurNode->setItemSet(
rSet );
418 bNonPoolable =
false;
425 pCurNode->setItemSet(
rSet );
428 sal_Int32 nCheck = -1;
429 std::unique_ptr<IStylePoolIteratorAccess> pIter =
createIterator(
false,
false);
430 std::shared_ptr<SfxItemSet> pTemp;
434 pTemp = pIter->getNext();
435 }
while( pTemp.get() );
439 return pCurNode->getItemSet();
444 bool bSkipIgnorableItems )
446 return std::make_unique<Iterator>(
maRoot, bSkipUnusedItemSets, bSkipIgnorableItems,
maParentNames );
456{
return pImpl->insertItemSet(
rSet, pParentName ); }
460 const bool bSkipIgnorableItems )
462 return pImpl->createIterator( bSkipUnusedItemSets, bSkipIgnorableItems );
virtual std::shared_ptr< SfxItemSet > getNext()=0
Delivers a shared pointer to the next SfxItemSet of the pool If there is no more SfxItemSet,...
const SfxPoolItem * GetCurItem() const
get item, or null if no items
const SfxPoolItem * NextItem()
bool IsItemPoolable(sal_uInt16 nWhich) const
SfxItemPool * GetPool() const
virtual std::unique_ptr< SfxItemSet > Clone(bool bItems=true, SfxItemPool *pToPool=nullptr) const
const SfxItemSet * GetParent() const
class StylePoolImpl organized a tree-structure where every node represents a SfxItemSet.
std::unique_ptr< SfxItemSet > mpIgnorableItems
StylePoolImpl(SfxItemSet const *pIgnorableItems)
std::unique_ptr< IStylePoolIteratorAccess > createIterator(bool bSkipUnusedItemSets, bool bSkipIgnorableItems)
std::map< const SfxItemSet *, Node > maRoot
std::map< const SfxItemSet *, OUString > maParentNames
Names of maRoot keys.
std::shared_ptr< SfxItemSet > insertItemSet(const SfxItemSet &rSet, const OUString *pParentName=nullptr)
std::unique_ptr< StylePoolImpl > pImpl
StylePool(SfxItemSet const *pIgnorableItems=nullptr)
static OUString nameOf(const std::shared_ptr< SfxItemSet > &pSet)
This static method creates a unique name from a shared pointer to a SfxItemSet The name is the memory...
std::unique_ptr< IStylePoolIteratorAccess > createIterator(const bool bSkipUnusedItemSets=false, const bool bSkipIgnorableItems=false)
Create an iterator.
std::shared_ptr< SfxItemSet > insertItemSet(const SfxItemSet &rSet, const OUString *pParentName=nullptr)
Insert a SfxItemSet into the style pool.
#define DBG_ASSERT(sCon, aError)
css::uno::Reference< css::animations::XAnimationNode > Clone(const css::uno::Reference< css::animations::XAnimationNode > &xSourceNode, const SdPage *pSource=nullptr, const SdPage *pTarget=nullptr)