bump product version to 6.3.0.0.beta1
[LibreOffice.git] / svl / source / items / style.cxx
bloba563e5a00cbf3a785b0e9e48e246aaddce216e70
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 <tools/tenccvt.hxx>
27 #include <osl/diagnose.h>
28 #include <unotools/intlwrapper.hxx>
29 #include <svl/hint.hxx>
30 #include <svl/poolitem.hxx>
31 #include <svl/itemset.hxx>
32 #include <svl/itempool.hxx>
33 #include <svl/IndexedStyleSheets.hxx>
34 #include <svl/itemiter.hxx>
35 #include <unotools/syslocale.hxx>
36 #include <algorithm>
37 #include <comphelper/servicehelper.hxx>
38 #include <rtl/ustrbuf.hxx>
40 #include <string.h>
42 #ifdef DBG_UTIL
43 class DbgStyleSheetReferences
45 public:
46 DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {}
47 ~DbgStyleSheetReferences()
49 SAL_WARN_IF(
50 mnStyles != 0 || mnPools != 0, "svl.items",
51 "SfxStyleSheetBase left " << mnStyles
52 << "; SfxStyleSheetBasePool left " << mnPools);
55 sal_uInt32 mnStyles;
56 sal_uInt32 mnPools;
59 static DbgStyleSheetReferences aDbgStyleSheetReferences;
60 #endif
63 SfxStyleSheetModifiedHint::SfxStyleSheetModifiedHint
65 const OUString& rOldName,
66 SfxStyleSheetBase& rStyleSheet // Remains with the caller
68 : SfxStyleSheetHint( SfxHintId::StyleSheetModified, rStyleSheet ),
69 aName( rOldName )
73 SfxStyleSheetHint::SfxStyleSheetHint
75 SfxHintId nAction,
76 SfxStyleSheetBase& rStyleSheet // Remains with the caller
78 : SfxHint(nAction), pStyleSh( &rStyleSheet )
82 class SfxStyleSheetBasePool_Impl
84 private:
85 SfxStyleSheetBasePool_Impl(const SfxStyleSheetBasePool_Impl&) = delete;
86 SfxStyleSheetBasePool_Impl& operator=(const SfxStyleSheetBasePool_Impl&) = delete;
87 public:
88 std::shared_ptr<SfxStyleSheetIterator> pIter;
90 /** This member holds the indexed style sheets.
92 * @internal
93 * This member is private and not protected in order to have more control which style sheets are added
94 * where. Ideally, all calls which add/remove/change style sheets are done in the base class.
96 std::shared_ptr<svl::IndexedStyleSheets> mxIndexedStyleSheets;
98 SfxStyleSheetBasePool_Impl() :
99 mxIndexedStyleSheets(new svl::IndexedStyleSheets) {}
103 SfxStyleSheetBase::SfxStyleSheetBase( const OUString& rName, SfxStyleSheetBasePool* p, SfxStyleFamily eFam, SfxStyleSearchBits mask )
104 : m_pPool( p )
105 , nFamily( eFam )
106 , aName( rName )
107 , aParent()
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 : comphelper::OWeakTypeObject(r)
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 SfxStyleFamily eTmpFam = m_pPool->GetSearchFamily();
174 SfxStyleSearchBits nTmpMask = m_pPool->GetSearchMask();
176 m_pPool->SetSearchMask(nFamily);
178 if ( !aName.isEmpty() )
179 m_pPool->ChangeParent( aName, rName, false );
181 if ( aFollow == aName )
182 aFollow = rName;
183 aName = rName;
184 if (bReIndexNow)
185 m_pPool->Reindex();
186 m_pPool->SetSearchMask(eTmpFam, nTmpMask);
187 m_pPool->Broadcast( SfxStyleSheetModifiedHint( aOldName, *this ) );
189 return true;
192 // Change Parent
193 const OUString& SfxStyleSheetBase::GetParent() const
195 return aParent;
198 bool SfxStyleSheetBase::SetParent( const OUString& rName )
200 if ( rName == aName )
201 return false;
203 if( aParent != rName )
205 SfxStyleSheetBase* pIter = m_pPool->Find(rName, nFamily);
206 if( !rName.isEmpty() && !pIter )
208 OSL_FAIL( "StyleSheet-Parent not found" );
209 return false;
211 // prevent recursive linkages
212 if( !aName.isEmpty() )
214 while(pIter)
216 if(pIter->GetName() == aName)
217 return false;
218 pIter = m_pPool->Find(pIter->GetParent(), nFamily);
221 aParent = rName;
223 m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
224 return true;
227 void SfxStyleSheetBase::SetHidden( bool hidden )
229 bHidden = hidden;
230 m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
234 * Change follow
236 const OUString& SfxStyleSheetBase::GetFollow() const
238 return aFollow;
241 bool SfxStyleSheetBase::SetFollow( const OUString& rName )
243 if( aFollow != rName )
245 if( !m_pPool->Find( rName, nFamily ) )
247 SAL_WARN( "svl.items", "StyleSheet-Follow not found" );
248 return false;
250 aFollow = rName;
252 m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
253 return true;
257 * Set Itemset
258 * The default implementation creates a new set
260 SfxItemSet& SfxStyleSheetBase::GetItemSet()
262 if( !pSet )
264 pSet = new SfxItemSet( m_pPool->GetPool() );
265 bMySet = true;
267 return *pSet;
270 std::unique_ptr<SfxItemSet> SfxStyleSheetBase::GetItemSetForPreview()
272 return std::make_unique<SfxItemSet>(GetItemSet());
276 * Set help file and ID and return it
278 sal_uLong SfxStyleSheetBase::GetHelpId( OUString& rFile )
280 rFile = aHelpFile;
281 return nHelpId;
284 void SfxStyleSheetBase::SetHelpId( const OUString& rFile, sal_uLong nId )
286 aHelpFile = rFile;
287 nHelpId = nId;
291 * Next style possible?
292 * Default: Yes
294 bool SfxStyleSheetBase::HasFollowSupport() const
296 return true;
300 * Base template possible?
301 * Default: Yes
303 bool SfxStyleSheetBase::HasParentSupport() const
305 return true;
309 * Setting base template to NULL possible?
310 * Default: No
312 bool SfxStyleSheetBase::HasClearParentSupport() const
314 return false;
318 * By default all stylesheets are set to used
320 bool SfxStyleSheetBase::IsUsed() const
322 return true;
326 * Return set attributes
328 OUString SfxStyleSheetBase::GetDescription( MapUnit eMetric )
330 SfxItemIter aIter( GetItemSet() );
331 OUStringBuffer aDesc;
332 const SfxPoolItem* pItem = aIter.FirstItem();
334 IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
335 while ( pItem )
337 OUString aItemPresentation;
339 if ( !IsInvalidItem( pItem ) &&
340 m_pPool->GetPool().GetPresentation(
341 *pItem, eMetric, aItemPresentation, aIntlWrapper ) )
343 if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
344 aDesc.append(" + ");
345 if ( !aItemPresentation.isEmpty() )
346 aDesc.append(aItemPresentation);
348 pItem = aIter.NextItem();
350 return aDesc.makeStringAndClear();
353 SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
355 return nSearchFamily;
358 inline bool SfxStyleSheetIterator::IsTrivialSearch() const
360 return (( nMask & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible) &&
361 (GetSearchFamily() == SfxStyleFamily::All);
364 namespace {
366 struct DoesStyleMatchStyleSheetPredicate final : public svl::StyleSheetPredicate
368 explicit DoesStyleMatchStyleSheetPredicate(SfxStyleSheetIterator *it)
369 : mIterator(it) {}
371 bool
372 Check(const SfxStyleSheetBase& styleSheet) override
374 bool bMatchFamily = ((mIterator->GetSearchFamily() == SfxStyleFamily::All) ||
375 ( styleSheet.GetFamily() == mIterator->GetSearchFamily() ));
377 bool bUsed = mIterator->SearchUsed() && styleSheet.IsUsed( );
379 bool bSearchHidden( mIterator->GetSearchMask() & SfxStyleSearchBits::Hidden );
380 bool bMatchVisibility = !( !bSearchHidden && styleSheet.IsHidden() && !bUsed );
381 bool bOnlyHidden = mIterator->GetSearchMask( ) == SfxStyleSearchBits::Hidden && styleSheet.IsHidden( );
383 bool bMatches = bMatchFamily && bMatchVisibility
384 && (( styleSheet.GetMask() & ( mIterator->GetSearchMask() & ~SfxStyleSearchBits::Used )) ||
385 bUsed || bOnlyHidden ||
386 ( mIterator->GetSearchMask() & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible );
387 return bMatches;
390 SfxStyleSheetIterator * const mIterator;
395 SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
396 SfxStyleFamily eFam, SfxStyleSearchBits n)
397 : pCurrentStyle(nullptr)
398 , nCurrentPosition(0)
400 pBasePool=pBase;
401 nSearchFamily=eFam;
402 bSearchUsed=false;
403 if( (( n & SfxStyleSearchBits::AllVisible ) != SfxStyleSearchBits::AllVisible )
404 && ((n & SfxStyleSearchBits::Used) == SfxStyleSearchBits::Used))
406 bSearchUsed = true;
407 n &= ~SfxStyleSearchBits::Used;
409 nMask=n;
412 SfxStyleSheetIterator::~SfxStyleSheetIterator()
416 sal_uInt16 SfxStyleSheetIterator::Count()
418 sal_uInt16 n = 0;
419 if( IsTrivialSearch())
421 n = static_cast<sal_uInt16>(pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheets());
423 else if(nMask == SfxStyleSearchBits::All)
425 n = static_cast<sal_uInt16>(pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).size());
427 else
429 DoesStyleMatchStyleSheetPredicate predicate(this);
430 n = pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheetsWithPredicate(predicate);
432 return n;
435 SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_uInt16 nIdx)
437 SfxStyleSheetBase* retval = nullptr;
438 if( IsTrivialSearch())
440 retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(nIdx);
441 nCurrentPosition = nIdx;
443 else if(nMask == SfxStyleSearchBits::All)
445 rtl::Reference< SfxStyleSheetBase > ref =
446 pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(
447 pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).at(nIdx))
449 retval = ref.get();
450 nCurrentPosition = nIdx;
452 else
454 DoesStyleMatchStyleSheetPredicate predicate(this);
455 rtl::Reference< SfxStyleSheetBase > ref =
456 pBasePool->pImpl->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(nIdx, predicate);
457 if (ref.get() != nullptr)
459 nCurrentPosition = pBasePool->pImpl->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
460 retval = ref.get();
464 if (retval == nullptr)
466 OSL_FAIL("Incorrect index");
469 return retval;
472 SfxStyleSheetBase* SfxStyleSheetIterator::First()
474 if (Count() != 0) {
475 return operator[](0);
477 else {
478 return nullptr;
483 SfxStyleSheetBase* SfxStyleSheetIterator::Next()
485 SfxStyleSheetBase* retval = nullptr;
487 if ( IsTrivialSearch() )
489 unsigned nStyleSheets = pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheets();
490 unsigned newPosition = nCurrentPosition +1;
491 if (nStyleSheets > newPosition)
493 nCurrentPosition = newPosition;
494 retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(nCurrentPosition);
497 else if(nMask == SfxStyleSearchBits::All)
499 unsigned newPosition = nCurrentPosition +1;
500 const std::vector<unsigned>& familyVector =
501 pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily);
502 if (familyVector.size() > newPosition)
504 nCurrentPosition = newPosition;
505 unsigned stylePosition = familyVector[newPosition];
506 retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(stylePosition);
509 else
511 DoesStyleMatchStyleSheetPredicate predicate(this);
512 rtl::Reference< SfxStyleSheetBase > ref =
513 pBasePool->pImpl->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(
514 0, predicate, nCurrentPosition+1);
515 retval = ref.get();
516 if (retval != nullptr) {
517 nCurrentPosition = pBasePool->pImpl->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
520 pCurrentStyle = retval;
521 return retval;
524 SfxStyleSheetBase* SfxStyleSheetIterator::Find(const OUString& rStr)
526 DoesStyleMatchStyleSheetPredicate predicate(this);
528 std::vector<unsigned> positions =
529 pBasePool->pImpl->mxIndexedStyleSheets->FindPositionsByNameAndPredicate(rStr, predicate,
530 svl::IndexedStyleSheets::SearchBehavior::ReturnFirst);
531 if (positions.empty()) {
532 return nullptr;
535 unsigned pos = positions.front();
536 SfxStyleSheetBase* pStyle = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
537 nCurrentPosition = pos;
538 pCurrentStyle = pStyle;
539 return pCurrentStyle;
542 SfxStyleSearchBits SfxStyleSheetIterator::GetSearchMask() const
544 SfxStyleSearchBits mask = nMask;
546 if ( bSearchUsed )
547 mask |= SfxStyleSearchBits::Used;
548 return mask;
552 SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl()
554 if( !pImpl->pIter || (pImpl->pIter->GetSearchMask() != nMask) || (pImpl->pIter->GetSearchFamily() != nSearchFamily) )
556 pImpl->pIter = CreateIterator( nSearchFamily, nMask );
559 return *pImpl->pIter;
562 SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r ) :
563 pImpl(new SfxStyleSheetBasePool_Impl),
564 rPool(r),
565 nSearchFamily(SfxStyleFamily::Para),
566 nMask(SfxStyleSearchBits::All)
568 #ifdef DBG_UTIL
569 aDbgStyleSheetReferences.mnPools++;
570 #endif
573 SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r ) :
574 SfxBroadcaster( r ),
575 comphelper::OWeakTypeObject(r),
576 pImpl(new SfxStyleSheetBasePool_Impl),
577 rPool(r.rPool),
578 nSearchFamily(r.nSearchFamily),
579 nMask( r.nMask )
581 #ifdef DBG_UTIL
582 aDbgStyleSheetReferences.mnPools++;
583 #endif
585 *this += r;
588 SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
590 #ifdef DBG_UTIL
591 aDbgStyleSheetReferences.mnPools--;
592 #endif
594 Broadcast( SfxHint(SfxHintId::Dying) );
595 Clear();
598 bool SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const OUString& rStyle, const OUString& rParent)
600 SfxStyleSheetIterator aIter(this,eFam,SfxStyleSearchBits::All);
601 SfxStyleSheetBase *pStyle = aIter.Find(rStyle);
602 OSL_ENSURE(pStyle, "Template not found. Writer with solar <2541?");
603 if(pStyle)
604 return pStyle->SetParent(rParent);
605 else
606 return false;
610 void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, SfxStyleSearchBits n)
612 nSearchFamily = eFam; nMask = n;
616 std::unique_ptr<SfxStyleSheetIterator> SfxStyleSheetBasePool::CreateIterator
618 SfxStyleFamily eFam,
619 SfxStyleSearchBits mask
622 return std::make_unique<SfxStyleSheetIterator>(this,eFam,mask);
625 SfxStyleSheetBase* SfxStyleSheetBasePool::Create
627 const OUString& rName,
628 SfxStyleFamily eFam,
629 SfxStyleSearchBits mask
632 return new SfxStyleSheetBase( rName, this, eFam, mask );
635 SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
637 return new SfxStyleSheetBase( r );
640 SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const OUString& rName, SfxStyleFamily eFam, SfxStyleSearchBits mask)
642 OSL_ENSURE( eFam != SfxStyleFamily::All, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" );
644 SfxStyleSheetIterator aIter(this, eFam, mask);
645 rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) );
646 OSL_ENSURE( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" );
648 if( !xStyle.is() )
650 xStyle = Create( rName, eFam, mask );
651 StoreStyleSheet(xStyle);
652 Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetCreated, *xStyle));
654 return *xStyle;
658 * Helper function: If a template with this name exists it is created
659 * anew. All templates that have this template as a parent are reconnected.
661 void SfxStyleSheetBasePool::Add( const SfxStyleSheetBase& rSheet )
663 SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask);
664 SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
665 if (pOld) {
666 Remove( pOld );
668 rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
669 pImpl->mxIndexedStyleSheets->AddStyleSheet(xNew);
670 Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetChanged, *xNew));
673 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
675 if( &r != this )
677 Clear();
678 *this += r;
680 return *this;
683 namespace {
684 struct AddStyleSheetCallback : svl::StyleSheetCallback
686 explicit AddStyleSheetCallback(SfxStyleSheetBasePool *pool)
687 : mPool(pool) {}
689 void DoIt(const SfxStyleSheetBase& ssheet) override
691 mPool->Add(ssheet);
694 SfxStyleSheetBasePool *mPool;
698 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
700 if( &r != this )
702 AddStyleSheetCallback callback(this);
703 pImpl->mxIndexedStyleSheets->ApplyToAllStyleSheets(callback);
705 return *this;
708 sal_uInt16 SfxStyleSheetBasePool::Count()
710 return GetIterator_Impl().Count();
713 SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](sal_uInt16 nIdx)
715 return GetIterator_Impl()[nIdx];
718 SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const OUString& rName,
719 SfxStyleFamily eFam,
720 SfxStyleSearchBits mask)
722 SfxStyleSheetIterator aIter(this,eFam,mask);
723 return aIter.Find(rName);
726 SfxStyleSheetBase* SfxStyleSheetBasePool::First()
728 return GetIterator_Impl().First();
731 SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
733 return GetIterator_Impl().Next();
736 void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
738 if( !p )
739 return;
741 // Reference to keep p alive until after Broadcast call!
742 rtl::Reference<SfxStyleSheetBase> xP(p);
743 bool bWasRemoved = pImpl->mxIndexedStyleSheets->RemoveStyleSheet(xP);
744 if( !bWasRemoved )
745 return;
747 // Adapt all styles which have this style as parant
748 ChangeParent( p->GetName(), p->GetParent() );
750 // #120015# Do not dispose, the removed StyleSheet may still be used in
751 // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal,
752 // this works well under normal conditions (checked breaking and counting
753 // on SfxStyleSheetBase constructors and destructors)
755 // css::uno::Reference< css::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), css::uno::UNO_QUERY );
756 // if( xComp.is() ) try
757 // {
758 // xComp->dispose();
759 // }
760 // catch( css::uno::Exception& )
761 // {
762 // }
763 Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetErased, *p ) );
766 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
768 #if OSL_DEBUG_LEVEL > 0
769 OSL_ENSURE( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
771 SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
772 SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
773 OSL_ENSURE( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
774 if( !p->GetParent().isEmpty() )
776 pOld = aIter.Find( p->GetParent() );
777 OSL_ENSURE( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
779 #endif
780 StoreStyleSheet(rtl::Reference< SfxStyleSheetBase >( p ) );
781 Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetCreated, *p ) );
784 namespace
787 struct StyleSheetDisposerFunctor final : public svl::StyleSheetDisposer
789 explicit StyleSheetDisposerFunctor(SfxStyleSheetBasePool* pool)
790 : mPool(pool) {}
792 void
793 Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet) override
795 cppu::OWeakObject* weakObject = static_cast< ::cppu::OWeakObject* >(styleSheet.get());
796 css::uno::Reference< css::lang::XComponent > xComp( weakObject, css::uno::UNO_QUERY );
797 if( xComp.is() ) try
799 xComp->dispose();
801 catch( css::uno::Exception& )
804 mPool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetErased, *styleSheet));
807 SfxStyleSheetBasePool* mPool;
812 void SfxStyleSheetBasePool::Clear()
814 StyleSheetDisposerFunctor cleanup(this);
815 pImpl->mxIndexedStyleSheets->Clear(cleanup);
818 void SfxStyleSheetBasePool::ChangeParent(const OUString& rOld,
819 const OUString& rNew,
820 bool bVirtual)
822 const SfxStyleSearchBits nTmpMask = GetSearchMask();
823 SetSearchMask(GetSearchFamily());
824 for( SfxStyleSheetBase* p = First(); p; p = Next() )
826 if( p->GetParent() == rOld )
828 if(bVirtual)
829 p->SetParent( rNew );
830 else
831 p->aParent = rNew;
834 SetSearchMask(GetSearchFamily(), nTmpMask);
837 SfxStyleSheet::SfxStyleSheet(const OUString &rName,
838 const SfxStyleSheetBasePool& r_Pool,
839 SfxStyleFamily eFam,
840 SfxStyleSearchBits mask )
841 : SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool* >( &r_Pool ), eFam, mask)
845 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle)
846 : SfxStyleSheetBase(rStyle)
847 , SfxListener( rStyle )
848 , SfxBroadcaster( rStyle )
849 , svl::StyleSheetUser()
853 SfxStyleSheet::~SfxStyleSheet()
855 Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetInDestruction, *this ) );
859 bool SfxStyleSheet::SetParent( const OUString& rName )
861 if(aParent == rName)
862 return true;
863 const OUString aOldParent(aParent);
864 if(SfxStyleSheetBase::SetParent(rName))
866 // Remove from notification chain of the old parent if applicable
867 if(!aOldParent.isEmpty())
869 SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(m_pPool->Find(aOldParent, nFamily));
870 if(pParent)
871 EndListening(*pParent);
873 // Add to the notification chain of the new parent
874 if(!aParent.isEmpty())
876 SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(m_pPool->Find(aParent, nFamily));
877 if(pParent)
878 StartListening(*pParent);
880 return true;
882 return false;
886 * Notify all listeners
888 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
890 Forward(rBC, rHint);
893 bool SfxStyleSheet::isUsedByModel() const
895 return IsUsed();
899 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
900 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
904 SfxStyleSheetBase* SfxStyleSheetPool::Create( const OUString& rName,
905 SfxStyleFamily eFam, SfxStyleSearchBits mask )
907 return new SfxStyleSheet( rName, *this, eFam, mask );
910 SfxUnoStyleSheet::SfxUnoStyleSheet( const OUString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, SfxStyleSearchBits _nMask )
911 : cppu::ImplInheritanceHelper<SfxStyleSheet, css::style::XStyle, css::lang::XUnoTunnel>(_rName, _rPool, _eFamily, _nMask)
915 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const css::uno::Reference< css::style::XStyle >& xStyle )
917 SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() );
918 if( !pRet )
920 css::uno::Reference< css::lang::XUnoTunnel > xUT( xStyle, css::uno::UNO_QUERY );
921 if( xUT.is() )
922 pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier())));
924 return pRet;
928 * XUnoTunnel
930 ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const css::uno::Sequence< ::sal_Int8 >& rId )
932 if( rId.getLength() == 16 && 0 == memcmp( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) )
934 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
936 else
938 return 0;
942 void
943 SfxStyleSheetBasePool::StoreStyleSheet(const rtl::Reference< SfxStyleSheetBase >& xStyle)
945 pImpl->mxIndexedStyleSheets->AddStyleSheet(xStyle);
948 namespace
950 class theSfxUnoStyleSheetIdentifier : public rtl::Static< UnoTunnelIdInit, theSfxUnoStyleSheetIdentifier > {};
953 const css::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier()
955 return theSfxUnoStyleSheetIdentifier::get().getSeq();
958 void
959 SfxStyleSheetBasePool::Reindex()
961 pImpl->mxIndexedStyleSheets->Reindex();
964 const svl::IndexedStyleSheets&
965 SfxStyleSheetBasePool::GetIndexedStyleSheets() const
967 return *pImpl->mxIndexedStyleSheets;
970 SfxStyleSheetBase*
971 SfxStyleSheetBasePool::GetStyleSheetByPositionInIndex(unsigned pos)
973 return pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
976 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */