attempt to fix macos jenkins hangs - part 3
[LibreOffice.git] / svl / source / items / style.cxx
blob41551e5064984b0654185646c594445176fcdd2c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <svl/style.hxx>
23 #include <com/sun/star/lang/XComponent.hpp>
25 #include <sal/log.hxx>
26 #include <osl/diagnose.h>
27 #include <unotools/intlwrapper.hxx>
28 #include <svl/hint.hxx>
29 #include <svl/poolitem.hxx>
30 #include <svl/itemset.hxx>
31 #include <svl/itempool.hxx>
32 #include <svl/IndexedStyleSheets.hxx>
33 #include <svl/itemiter.hxx>
34 #include <unotools/syslocale.hxx>
35 #include <comphelper/servicehelper.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <utility>
39 #ifdef DBG_UTIL
40 namespace {
42 class DbgStyleSheetReferences
44 public:
45 DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {}
46 ~DbgStyleSheetReferences()
48 SAL_WARN_IF(
49 mnStyles != 0 || mnPools != 0, "svl.items",
50 "SfxStyleSheetBase left " << mnStyles
51 << "; SfxStyleSheetBasePool left " << mnPools);
54 sal_uInt32 mnStyles;
55 sal_uInt32 mnPools;
60 static DbgStyleSheetReferences aDbgStyleSheetReferences;
61 #endif
64 SfxStyleSheetModifiedHint::SfxStyleSheetModifiedHint
66 OUString aOldName,
67 SfxStyleSheetBase& rStyleSheet // Remains with the caller
69 : SfxStyleSheetHint( SfxHintId::StyleSheetModified, rStyleSheet ),
70 aName(std::move( aOldName ))
74 SfxStyleSheetHint::SfxStyleSheetHint
76 SfxHintId nAction,
77 SfxStyleSheetBase& rStyleSheet // Remains with the caller
79 : SfxHint(nAction), pStyleSh( &rStyleSheet )
83 class SfxStyleSheetBasePool_Impl
85 private:
86 SfxStyleSheetBasePool_Impl(const SfxStyleSheetBasePool_Impl&) = delete;
87 SfxStyleSheetBasePool_Impl& operator=(const SfxStyleSheetBasePool_Impl&) = delete;
88 public:
89 std::shared_ptr<SfxStyleSheetIterator> pIter;
91 /** This member holds the indexed style sheets.
93 * @internal
94 * This member is private and not protected in order to have more control which style sheets are added
95 * where. Ideally, all calls which add/remove/change style sheets are done in the base class.
97 std::shared_ptr<svl::IndexedStyleSheets> mxIndexedStyleSheets;
99 SfxStyleSheetBasePool_Impl() :
100 mxIndexedStyleSheets(std::make_shared<svl::IndexedStyleSheets>()) {}
104 SfxStyleSheetBase::SfxStyleSheetBase( const OUString& rName, SfxStyleSheetBasePool* p, SfxStyleFamily eFam, SfxStyleSearchBits mask )
105 : m_pPool( p )
106 , nFamily( eFam )
107 , aName( rName )
108 , aFollow( rName )
109 , pSet( nullptr )
110 , nMask(mask)
111 , nHelpId( 0 )
112 , bMySet( false )
113 , bHidden( false )
115 #ifdef DBG_UTIL
116 aDbgStyleSheetReferences.mnStyles++;
117 #endif
120 SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r )
121 : WeakImplHelper()
122 , m_pPool( r.m_pPool )
123 , nFamily( r.nFamily )
124 , aName( r.aName )
125 , aParent( r.aParent )
126 , aFollow( r.aFollow )
127 , aHelpFile( r.aHelpFile )
128 , nMask( r.nMask )
129 , nHelpId( r.nHelpId )
130 , bMySet( r.bMySet )
131 , bHidden( r.bHidden )
133 #ifdef DBG_UTIL
134 aDbgStyleSheetReferences.mnStyles++;
135 #endif
136 if( r.pSet )
137 pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet;
138 else
139 pSet = nullptr;
142 SfxStyleSheetBase::~SfxStyleSheetBase()
144 #ifdef DBG_UTIL
145 --aDbgStyleSheetReferences.mnStyles;
146 #endif
148 if( bMySet )
150 delete pSet;
151 pSet = nullptr;
155 // Change name
156 const OUString& SfxStyleSheetBase::GetName() const
158 return aName;
161 bool SfxStyleSheetBase::SetName(const OUString& rName, bool bReIndexNow)
163 if(rName.isEmpty())
164 return false;
166 if( aName != rName )
168 OUString aOldName = aName;
169 SfxStyleSheetBase *pOther = m_pPool->Find( rName, nFamily ) ;
170 if ( pOther && pOther != this )
171 return false;
173 if ( !aName.isEmpty() )
174 m_pPool->ChangeParent(aName, rName, nFamily, false);
176 if ( aFollow == aName )
177 aFollow = rName;
178 aName = rName;
179 if (bReIndexNow)
180 m_pPool->Reindex();
182 m_pPool->Broadcast( SfxStyleSheetModifiedHint( aOldName, *this ) );
184 return true;
187 // Change Parent
188 const OUString& SfxStyleSheetBase::GetParent() const
190 return aParent;
193 bool SfxStyleSheetBase::SetParent( const OUString& rName )
195 if ( rName == aName )
196 return false;
198 if( aParent != rName )
200 SfxStyleSheetBase* pIter = m_pPool->Find(rName, nFamily);
201 if( !rName.isEmpty() && !pIter )
203 OSL_FAIL( "StyleSheet-Parent not found" );
204 return false;
206 // prevent recursive linkages
207 if( !aName.isEmpty() )
209 while(pIter)
211 if(pIter->GetName() == aName)
212 return false;
213 pIter = m_pPool->Find(pIter->GetParent(), nFamily);
216 aParent = rName;
218 m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
219 return true;
222 void SfxStyleSheetBase::SetHidden( bool hidden )
224 bHidden = hidden;
225 m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
229 * Change follow
231 const OUString& SfxStyleSheetBase::GetFollow() const
233 return aFollow;
236 bool SfxStyleSheetBase::SetFollow( const OUString& rName )
238 if( aFollow != rName )
240 if( !m_pPool->Find( rName, nFamily ) )
242 SAL_WARN( "svl.items", "StyleSheet-Follow not found" );
243 return false;
245 aFollow = rName;
247 m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
248 return true;
252 * Set Itemset
253 * The default implementation creates a new set
255 SfxItemSet& SfxStyleSheetBase::GetItemSet()
257 if( !pSet )
259 pSet = new SfxItemSet( m_pPool->GetPool() );
260 bMySet = true;
262 return *pSet;
265 std::optional<SfxItemSet> SfxStyleSheetBase::GetItemSetForPreview()
267 return GetItemSet();
271 * Set help file and ID and return it
273 sal_uLong SfxStyleSheetBase::GetHelpId( OUString& rFile )
275 rFile = aHelpFile;
276 return nHelpId;
279 void SfxStyleSheetBase::SetHelpId( const OUString& rFile, sal_uLong nId )
281 aHelpFile = rFile;
282 nHelpId = nId;
286 * Next style possible?
287 * Default: Yes
289 bool SfxStyleSheetBase::HasFollowSupport() const
291 return true;
295 * Base template possible?
296 * Default: Yes
298 bool SfxStyleSheetBase::HasParentSupport() const
300 return true;
304 * Setting base template to NULL possible?
305 * Default: No
307 bool SfxStyleSheetBase::HasClearParentSupport() const
309 return false;
313 * By default all stylesheets are set to used
315 bool SfxStyleSheetBase::IsUsed() const
317 return true;
321 * Return set attributes
323 OUString SfxStyleSheetBase::GetDescription( MapUnit eMetric )
325 SfxItemIter aIter( GetItemSet() );
326 OUStringBuffer aDesc;
328 IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
329 for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
331 OUString aItemPresentation;
333 if ( !IsInvalidItem( pItem ) &&
334 m_pPool->GetPool().GetPresentation(
335 *pItem, eMetric, aItemPresentation, aIntlWrapper ) )
337 if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
338 aDesc.append(" + ");
339 if ( !aItemPresentation.isEmpty() )
340 aDesc.append(aItemPresentation);
343 return aDesc.makeStringAndClear();
346 SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
348 return nSearchFamily;
351 inline bool SfxStyleSheetIterator::IsTrivialSearch() const
353 return (( nMask & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible) &&
354 (GetSearchFamily() == SfxStyleFamily::All);
357 namespace {
359 struct DoesStyleMatchStyleSheetPredicate final : public svl::StyleSheetPredicate
361 explicit DoesStyleMatchStyleSheetPredicate(SfxStyleSheetIterator *it)
362 : mIterator(it) {}
364 bool
365 Check(const SfxStyleSheetBase& styleSheet) override
367 bool bMatchFamily = ((mIterator->GetSearchFamily() == SfxStyleFamily::All) ||
368 ( styleSheet.GetFamily() == mIterator->GetSearchFamily() ));
370 bool bUsed = mIterator->SearchUsed() && styleSheet.IsUsed( );
372 bool bSearchHidden( mIterator->GetSearchMask() & SfxStyleSearchBits::Hidden );
373 bool bMatchVisibility = bSearchHidden || !styleSheet.IsHidden() || bUsed;
374 bool bOnlyHidden = mIterator->GetSearchMask( ) == SfxStyleSearchBits::Hidden && styleSheet.IsHidden( );
376 bool bMatches = bMatchFamily && bMatchVisibility
377 && (( styleSheet.GetMask() & ( mIterator->GetSearchMask() & ~SfxStyleSearchBits::Used )) ||
378 bUsed || bOnlyHidden ||
379 ( mIterator->GetSearchMask() & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible );
380 return bMatches;
383 SfxStyleSheetIterator *mIterator;
388 SfxStyleSheetIterator::SfxStyleSheetIterator(const SfxStyleSheetBasePool *pBase,
389 SfxStyleFamily eFam, SfxStyleSearchBits n)
390 : pBasePool(pBase)
391 , pCurrentStyle(nullptr)
392 , mnCurrentPosition(0)
394 nSearchFamily=eFam;
395 bSearchUsed=false;
396 if( (( n & SfxStyleSearchBits::AllVisible ) != SfxStyleSearchBits::AllVisible )
397 && ((n & SfxStyleSearchBits::Used) == SfxStyleSearchBits::Used))
399 bSearchUsed = true;
400 n &= ~SfxStyleSearchBits::Used;
402 nMask=n;
405 SfxStyleSheetIterator::~SfxStyleSheetIterator()
409 sal_Int32 SfxStyleSheetIterator::Count()
411 sal_Int32 n = 0;
412 if( IsTrivialSearch())
414 n = static_cast<sal_uInt16>(pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheets());
416 else if(nMask == SfxStyleSearchBits::All)
418 n = static_cast<sal_uInt16>(pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).size());
420 else
422 DoesStyleMatchStyleSheetPredicate predicate(this);
423 n = pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheetsWithPredicate(predicate);
425 return n;
428 SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_Int32 nIdx)
430 SfxStyleSheetBase* retval = nullptr;
431 if( IsTrivialSearch())
433 retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(nIdx);
434 mnCurrentPosition = nIdx;
436 else if(nMask == SfxStyleSearchBits::All)
438 rtl::Reference< SfxStyleSheetBase > ref =
439 pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(
440 pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).at(nIdx))
442 retval = ref.get();
443 mnCurrentPosition = nIdx;
445 else
447 DoesStyleMatchStyleSheetPredicate predicate(this);
448 rtl::Reference< SfxStyleSheetBase > ref =
449 pBasePool->pImpl->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(nIdx, predicate);
450 if (ref)
452 mnCurrentPosition = pBasePool->pImpl->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
453 retval = ref.get();
457 if (retval == nullptr)
459 OSL_FAIL("Incorrect index");
462 return retval;
465 SfxStyleSheetBase* SfxStyleSheetIterator::First()
467 if (Count() != 0) {
468 return operator[](0);
470 else {
471 return nullptr;
475 SfxStyleSheetBase* SfxStyleSheetIterator::Next()
477 SfxStyleSheetBase* retval = nullptr;
479 if ( IsTrivialSearch() )
481 sal_Int32 nStyleSheets = pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheets();
482 sal_Int32 newPosition = mnCurrentPosition + 1;
483 if (nStyleSheets > newPosition)
485 mnCurrentPosition = newPosition;
486 retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(mnCurrentPosition);
489 else if(nMask == SfxStyleSearchBits::All)
491 sal_Int32 newPosition = mnCurrentPosition + 1;
492 const std::vector<sal_Int32>& familyVector
494 pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily);
495 if (static_cast<sal_Int32>(familyVector.size()) > newPosition)
497 mnCurrentPosition = newPosition;
498 sal_Int32 stylePosition = familyVector[newPosition];
499 retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(stylePosition);
502 else
504 DoesStyleMatchStyleSheetPredicate predicate(this);
505 rtl::Reference< SfxStyleSheetBase > ref =
506 pBasePool->pImpl->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(
507 0, predicate, mnCurrentPosition+1);
508 retval = ref.get();
509 if (retval != nullptr) {
510 mnCurrentPosition = pBasePool->pImpl->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
513 pCurrentStyle = retval;
514 return retval;
517 SfxStyleSheetBase* SfxStyleSheetIterator::Find(const OUString& rStr)
519 DoesStyleMatchStyleSheetPredicate predicate(this);
521 std::vector<sal_Int32> positions =
522 pBasePool->pImpl->mxIndexedStyleSheets->FindPositionsByNameAndPredicate(rStr, predicate,
523 svl::IndexedStyleSheets::SearchBehavior::ReturnFirst);
524 if (positions.empty()) {
525 return nullptr;
528 sal_Int32 pos = positions.front();
529 SfxStyleSheetBase* pStyle = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
530 mnCurrentPosition = pos;
531 pCurrentStyle = pStyle;
532 return pCurrentStyle;
535 SfxStyleSearchBits SfxStyleSheetIterator::GetSearchMask() const
537 SfxStyleSearchBits mask = nMask;
539 if ( bSearchUsed )
540 mask |= SfxStyleSearchBits::Used;
541 return mask;
544 SfxStyleSheetIterator* SfxStyleSheetBasePool::GetCachedIterator()
546 return pImpl->pIter.get();
549 SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl(SfxStyleFamily eFamily, SfxStyleSearchBits eMask)
551 if (!pImpl->pIter || (pImpl->pIter->GetSearchMask() != eMask) || (pImpl->pIter->GetSearchFamily() != eFamily))
552 pImpl->pIter = CreateIterator(eFamily, eMask);
553 return *pImpl->pIter;
556 SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r ) :
557 pImpl(new SfxStyleSheetBasePool_Impl),
558 rPool(r)
560 #ifdef DBG_UTIL
561 aDbgStyleSheetReferences.mnPools++;
562 #endif
565 SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r ) :
566 SfxBroadcaster( r ),
567 WeakImplHelper(),
568 pImpl(new SfxStyleSheetBasePool_Impl),
569 rPool(r.rPool)
571 #ifdef DBG_UTIL
572 aDbgStyleSheetReferences.mnPools++;
573 #endif
575 *this += r;
578 SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
580 #ifdef DBG_UTIL
581 aDbgStyleSheetReferences.mnPools--;
582 #endif
584 Broadcast( SfxHint(SfxHintId::Dying) );
585 Clear();
588 std::unique_ptr<SfxStyleSheetIterator> SfxStyleSheetBasePool::CreateIterator
590 SfxStyleFamily eFam,
591 SfxStyleSearchBits mask
594 return std::make_unique<SfxStyleSheetIterator>(this,eFam,mask);
597 rtl::Reference<SfxStyleSheetBase> SfxStyleSheetBasePool::Create
599 const OUString& rName,
600 SfxStyleFamily eFam,
601 SfxStyleSearchBits mask
604 return new SfxStyleSheetBase( rName, this, eFam, mask );
607 rtl::Reference<SfxStyleSheetBase> SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
609 return new SfxStyleSheetBase( r );
612 SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const OUString& rName, SfxStyleFamily eFam, SfxStyleSearchBits mask)
614 OSL_ENSURE( eFam != SfxStyleFamily::All, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not an allowed Family" );
616 SfxStyleSheetIterator aIter(this, eFam, mask);
617 rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) );
618 OSL_ENSURE( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" );
620 if( !xStyle.is() )
622 xStyle = Create( rName, eFam, mask );
623 StoreStyleSheet(xStyle);
624 Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetCreated, *xStyle));
626 return *xStyle;
630 * Helper function: If a template with this name exists it is created
631 * anew. All templates that have this template as a parent are reconnected.
633 void SfxStyleSheetBasePool::Add( const SfxStyleSheetBase& rSheet )
635 SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), SfxStyleSearchBits::All);
636 SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
637 if (pOld) {
638 Remove( pOld );
640 rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
641 pImpl->mxIndexedStyleSheets->AddStyleSheet(xNew);
642 Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetChanged, *xNew));
645 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
647 if( &r != this )
649 Clear();
650 *this += r;
652 return *this;
655 namespace {
656 struct AddStyleSheetCallback : svl::StyleSheetCallback
658 explicit AddStyleSheetCallback(SfxStyleSheetBasePool *pool)
659 : mPool(pool) {}
661 void DoIt(const SfxStyleSheetBase& ssheet) override
663 mPool->Add(ssheet);
666 SfxStyleSheetBasePool *mPool;
670 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
672 if( &r != this )
674 AddStyleSheetCallback callback(this);
675 pImpl->mxIndexedStyleSheets->ApplyToAllStyleSheets(callback);
677 return *this;
680 SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const OUString& rName,
681 SfxStyleFamily eFamily,
682 SfxStyleSearchBits eMask)
684 SfxStyleSheetIterator aIter(this, eFamily, eMask);
685 return aIter.Find(rName);
688 SfxStyleSheetBase* SfxStyleSheetBasePool::First(SfxStyleFamily eFamily, SfxStyleSearchBits eMask)
690 return GetIterator_Impl(eFamily, eMask).First();
693 SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
695 assert(pImpl->pIter && "Next called without a previous First");
696 return pImpl->pIter->Next();
699 void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
701 if( !p )
702 return;
704 // Reference to keep p alive until after Broadcast call!
705 rtl::Reference<SfxStyleSheetBase> xP(p);
706 bool bWasRemoved = pImpl->mxIndexedStyleSheets->RemoveStyleSheet(xP);
707 if( !bWasRemoved )
708 return;
710 // Adapt all styles which have this style as parent
711 ChangeParent(p->GetName(), p->GetParent(), p->GetFamily());
713 // #120015# Do not dispose, the removed StyleSheet may still be used in
714 // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal,
715 // this works well under normal conditions (checked breaking and counting
716 // on SfxStyleSheetBase constructors and destructors)
718 // css::uno::Reference< css::lang::XComponent > xComp( getXWeak((*aIter).get()), css::uno::UNO_QUERY );
719 // if( xComp.is() ) try
720 // {
721 // xComp->dispose();
722 // }
723 // catch( css::uno::Exception& )
724 // {
725 // }
726 Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetErased, *p ) );
729 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
731 #if OSL_DEBUG_LEVEL > 0
732 OSL_ENSURE( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
734 SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
735 SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
736 OSL_ENSURE( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
737 if( !p->GetParent().isEmpty() )
739 pOld = aIter.Find( p->GetParent() );
740 OSL_ENSURE( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
742 #endif
743 StoreStyleSheet(rtl::Reference< SfxStyleSheetBase >( p ) );
744 Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetCreated, *p ) );
747 namespace
750 struct StyleSheetDisposerFunctor final : public svl::StyleSheetDisposer
752 explicit StyleSheetDisposerFunctor(SfxStyleSheetBasePool* pool)
753 : mPool(pool) {}
755 void
756 Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet) override
758 cppu::OWeakObject* weakObject = styleSheet.get();
759 css::uno::Reference< css::lang::XComponent > xComp( weakObject, css::uno::UNO_QUERY );
760 if( xComp.is() ) try
762 xComp->dispose();
764 catch( css::uno::Exception& )
767 mPool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetErased, *styleSheet));
770 SfxStyleSheetBasePool* mPool;
775 void SfxStyleSheetBasePool::Clear()
777 StyleSheetDisposerFunctor cleanup(this);
778 pImpl->mxIndexedStyleSheets->Clear(cleanup);
781 void SfxStyleSheetBasePool::ChangeParent(std::u16string_view rOld,
782 const OUString& rNew,
783 SfxStyleFamily eFamily,
784 bool bVirtual)
786 for( SfxStyleSheetBase* p = First(eFamily); p; p = Next() )
788 if( p->GetParent() == rOld )
790 if(bVirtual)
791 p->SetParent( rNew );
792 else
793 p->aParent = rNew;
798 SfxStyleSheet::SfxStyleSheet(const OUString &rName,
799 const SfxStyleSheetBasePool& r_Pool,
800 SfxStyleFamily eFam,
801 SfxStyleSearchBits mask )
802 : SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool* >( &r_Pool ), eFam, mask)
806 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle)
807 : SfxStyleSheetBase(rStyle)
808 , SfxListener( rStyle )
809 , SfxBroadcaster( rStyle )
810 , svl::StyleSheetUser()
814 SfxStyleSheet::~SfxStyleSheet()
816 Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetInDestruction, *this ) );
820 bool SfxStyleSheet::SetParent( const OUString& rName )
822 if(aParent == rName)
823 return true;
824 const OUString aOldParent(aParent);
825 if(SfxStyleSheetBase::SetParent(rName))
827 // Remove from notification chain of the old parent if applicable
828 if(!aOldParent.isEmpty())
830 SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(m_pPool->Find(aOldParent, nFamily));
831 if(pParent)
832 EndListening(*pParent);
834 // Add to the notification chain of the new parent
835 if(!aParent.isEmpty())
837 SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(m_pPool->Find(aParent, nFamily));
838 if(pParent)
839 StartListening(*pParent);
841 return true;
843 return false;
847 * Notify all listeners
849 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
851 Forward(rBC, rHint);
854 bool SfxStyleSheet::isUsedByModel() const
856 return IsUsed();
860 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
861 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
865 rtl::Reference<SfxStyleSheetBase> SfxStyleSheetPool::Create( const OUString& rName,
866 SfxStyleFamily eFam, SfxStyleSearchBits mask )
868 return new SfxStyleSheet( rName, *this, eFam, mask );
871 SfxUnoStyleSheet::SfxUnoStyleSheet( const OUString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, SfxStyleSearchBits _nMask )
872 : cppu::ImplInheritanceHelper<SfxStyleSheet, css::style::XStyle>(_rName, _rPool, _eFamily, _nMask)
876 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const css::uno::Reference< css::style::XStyle >& xStyle )
878 return dynamic_cast<SfxUnoStyleSheet*>(xStyle.get());
881 void
882 SfxStyleSheetBasePool::StoreStyleSheet(const rtl::Reference< SfxStyleSheetBase >& xStyle)
884 pImpl->mxIndexedStyleSheets->AddStyleSheet(xStyle);
887 void
888 SfxStyleSheetBasePool::Reindex()
890 pImpl->mxIndexedStyleSheets->Reindex();
893 const svl::IndexedStyleSheets&
894 SfxStyleSheetBasePool::GetIndexedStyleSheets() const
896 return *pImpl->mxIndexedStyleSheets;
899 SfxStyleSheetBase*
900 SfxStyleSheetBasePool::GetStyleSheetByPositionInIndex(unsigned pos)
902 return pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
905 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */