bump product version to 5.0.4.1
[LibreOffice.git] / svl / source / items / style.cxx
blob01da088c0ed4c7754d4fdfd9f0a92c8f93386c78
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 <svl/style.hxx>
22 #include <com/sun/star/lang/XComponent.hpp>
24 #include <sal/log.hxx>
25 #include <tools/tenccvt.hxx>
26 #include <osl/diagnose.h>
27 #include <comphelper/processfactory.hxx>
28 #include <unotools/intlwrapper.hxx>
29 #include <svl/smplhint.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>
39 #include <string.h>
41 #ifdef DBG_UTIL
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;
57 aDbgStyleSheetReferences;
59 #endif
61 TYPEINIT0(SfxStyleSheetBase)
63 TYPEINIT3(SfxStyleSheet, SfxStyleSheetBase, SfxListener, SfxBroadcaster)
65 SfxStyleSheetHintExtended::SfxStyleSheetHintExtended
67 sal_uInt16 nAction, // SfxStyleSheetHintId::... (see above)
68 const OUString& rOldName,
69 SfxStyleSheetBase& rStyleSheet // Remains with the caller
71 : SfxStyleSheetHint( nAction, rStyleSheet ),
72 aName( rOldName )
76 SfxStyleSheetHint::SfxStyleSheetHint
78 sal_uInt16 nAction, // SfxStyleSheetHintId::... (see above)
79 SfxStyleSheetBase& rStyleSheet // Remains with the caller
81 : pStyleSh( &rStyleSheet ),
82 nHint( nAction )
86 class SfxStyleSheetBasePool_Impl
88 private:
89 SfxStyleSheetBasePool_Impl(const SfxStyleSheetBasePool_Impl&) SAL_DELETED_FUNCTION;
90 SfxStyleSheetBasePool_Impl& operator=(const SfxStyleSheetBasePool_Impl&) SAL_DELETED_FUNCTION;
91 public:
92 SfxStyleSheetIteratorPtr pIter;
94 /** This member holds the indexed style sheets.
96 * @internal
97 * This member is private and not protected in order to have more control which style sheets are added
98 * where. Ideally, all calls which add/remove/change style sheets are done in the base class.
100 std::shared_ptr<svl::IndexedStyleSheets> mxIndexedStyleSheets;
102 SfxStyleSheetBasePool_Impl() :
103 mxIndexedStyleSheets(new svl::IndexedStyleSheets) {}
107 SfxStyleSheetBase::SfxStyleSheetBase( const OUString& rName, SfxStyleSheetBasePool* p, SfxStyleFamily eFam, sal_uInt16 mask )
108 : pPool( p )
109 , nFamily( eFam )
110 , aName( rName )
111 , aParent()
112 , aFollow( rName )
113 , pSet( NULL )
114 , nMask(mask)
115 , nHelpId( 0 )
116 , bMySet( false )
117 , bHidden( false )
119 #ifdef DBG_UTIL
120 aDbgStyleSheetReferences.mnStyles++;
121 #endif
124 SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r )
125 : comphelper::OWeakTypeObject()
126 , pPool( r.pPool )
127 , nFamily( r.nFamily )
128 , aName( r.aName )
129 , aParent( r.aParent )
130 , aFollow( r.aFollow )
131 , aHelpFile( r.aHelpFile )
132 , nMask( r.nMask )
133 , nHelpId( r.nHelpId )
134 , bMySet( r.bMySet )
135 , bHidden( r.bHidden )
137 #ifdef DBG_UTIL
138 aDbgStyleSheetReferences.mnStyles++;
139 #endif
140 if( r.pSet )
141 pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet;
142 else
143 pSet = NULL;
146 SfxStyleSheetBase::~SfxStyleSheetBase()
148 #ifdef DBG_UTIL
149 --aDbgStyleSheetReferences.mnStyles;
150 #endif
152 if( bMySet )
154 delete pSet;
155 pSet = 0;
159 // Change name
160 const OUString& SfxStyleSheetBase::GetName() const
162 return aName;
165 bool SfxStyleSheetBase::SetName(const OUString& rName, bool bReIndexNow)
167 if(rName.isEmpty())
168 return false;
170 if( aName != rName )
172 OUString aOldName = aName;
173 SfxStyleSheetBase *pOther = pPool->Find( rName, nFamily ) ;
174 if ( pOther && pOther != this )
175 return false;
177 SfxStyleFamily eTmpFam = pPool->GetSearchFamily();
178 sal_uInt16 nTmpMask = pPool->GetSearchMask();
180 pPool->SetSearchMask(nFamily);
182 if ( !aName.isEmpty() )
183 pPool->ChangeParent( aName, rName, false );
185 if ( aFollow == aName )
186 aFollow = rName;
187 aName = rName;
188 if (bReIndexNow)
189 pPool->Reindex();
190 pPool->SetSearchMask(eTmpFam, nTmpMask);
191 pPool->Broadcast( SfxStyleSheetHintExtended(
192 SfxStyleSheetHintId::MODIFIED, aOldName, *this ) );
194 return true;
197 OUString SfxStyleSheetBase::GetDisplayName() const
199 if( maDisplayName.isEmpty() )
201 return aName;
203 else
205 return maDisplayName;
209 // Change Parent
210 const OUString& SfxStyleSheetBase::GetParent() const
212 return aParent;
215 bool SfxStyleSheetBase::SetParent( const OUString& rName )
217 if ( rName == aName )
218 return false;
220 if( aParent != rName )
222 SfxStyleSheetBase* pIter = pPool->Find(rName, nFamily);
223 if( !rName.isEmpty() && !pIter )
225 OSL_FAIL( "StyleSheet-Parent not found" );
226 return false;
228 // prevent recursive linkages
229 if( !aName.isEmpty() )
231 while(pIter)
233 if(pIter->GetName() == aName)
234 return false;
235 pIter = pPool->Find(pIter->GetParent(), nFamily);
238 aParent = rName;
240 pPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::MODIFIED, *this ) );
241 return true;
244 void SfxStyleSheetBase::SetHidden( bool hidden )
246 bHidden = hidden;
247 pPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::MODIFIED, *this ) );
251 * Change follow
253 const OUString& SfxStyleSheetBase::GetFollow() const
255 return aFollow;
258 bool SfxStyleSheetBase::SetFollow( const OUString& rName )
260 if( aFollow != rName )
262 if( !pPool->Find( rName, nFamily ) )
264 SAL_WARN( "svl", "StyleSheet-Follow not found" );
265 return false;
267 aFollow = rName;
269 pPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::MODIFIED, *this ) );
270 return true;
274 * Set Itemset
275 * The default implementation creates a new set
277 SfxItemSet& SfxStyleSheetBase::GetItemSet()
279 if( !pSet )
281 pSet = new SfxItemSet( pPool->GetPool() );
282 bMySet = true;
284 return *pSet;
287 std::unique_ptr<SfxItemSet> SfxStyleSheetBase::GetItemSetForPreview()
289 return std::unique_ptr<SfxItemSet>(new SfxItemSet(GetItemSet()));
293 * Set help file and ID and return it
295 sal_uLong SfxStyleSheetBase::GetHelpId( OUString& rFile )
297 rFile = aHelpFile;
298 return nHelpId;
301 void SfxStyleSheetBase::SetHelpId( const OUString& rFile, sal_uLong nId )
303 aHelpFile = rFile;
304 nHelpId = nId;
308 * Next style possible?
309 * Default: Yes
311 bool SfxStyleSheetBase::HasFollowSupport() const
313 return true;
317 * Base template possible?
318 * Default: Yes
320 bool SfxStyleSheetBase::HasParentSupport() const
322 return true;
326 * Setting base template to NULL possible?
327 * Default: No
329 bool SfxStyleSheetBase::HasClearParentSupport() const
331 return false;
335 * By default all stylesheets are set to used
337 bool SfxStyleSheetBase::IsUsed() const
339 return true;
343 * Return set attributes
345 OUString SfxStyleSheetBase::GetDescription()
347 return GetDescription( SFX_MAPUNIT_CM );
351 * Return set attributes
353 OUString SfxStyleSheetBase::GetDescription( SfxMapUnit eMetric )
355 SfxItemIter aIter( GetItemSet() );
356 OUString aDesc;
357 const SfxPoolItem* pItem = aIter.FirstItem();
359 IntlWrapper aIntlWrapper( SvtSysLocale().GetLanguageTag() );
360 while ( pItem )
362 OUString aItemPresentation;
364 if ( !IsInvalidItem( pItem ) &&
365 pPool->GetPool().GetPresentation(
366 *pItem, eMetric, aItemPresentation, &aIntlWrapper ) )
368 if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
369 aDesc += " + ";
370 if ( !aItemPresentation.isEmpty() )
371 aDesc += aItemPresentation;
373 pItem = aIter.NextItem();
375 return aDesc;
378 SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
380 return nSearchFamily;
383 inline bool SfxStyleSheetIterator::IsTrivialSearch()
385 return (( nMask & SFXSTYLEBIT_ALL_VISIBLE ) == SFXSTYLEBIT_ALL_VISIBLE) &&
386 (GetSearchFamily() == SFX_STYLE_FAMILY_ALL);
389 namespace {
391 struct DoesStyleMatchStyleSheetPredicate SAL_FINAL : public svl::StyleSheetPredicate
393 DoesStyleMatchStyleSheetPredicate(SfxStyleSheetIterator *it)
394 : mIterator(it) {;}
396 bool
397 Check(const SfxStyleSheetBase& styleSheet) SAL_OVERRIDE
399 bool bMatchFamily = ((mIterator->GetSearchFamily() == SFX_STYLE_FAMILY_ALL) ||
400 ( styleSheet.GetFamily() == mIterator->GetSearchFamily() ));
402 bool bUsed = mIterator->SearchUsed() && styleSheet.IsUsed( );
404 bool bSearchHidden = ( mIterator->GetSearchMask() & SFXSTYLEBIT_HIDDEN );
405 bool bMatchVisibility = !( !bSearchHidden && styleSheet.IsHidden() && !bUsed );
406 bool bOnlyHidden = mIterator->GetSearchMask( ) == SFXSTYLEBIT_HIDDEN && styleSheet.IsHidden( );
408 bool bMatches = bMatchFamily && bMatchVisibility
409 && (( styleSheet.GetMask() & ( mIterator->GetSearchMask() & ~SFXSTYLEBIT_USED )) ||
410 bUsed || bOnlyHidden ||
411 ( mIterator->GetSearchMask() & SFXSTYLEBIT_ALL_VISIBLE ) == SFXSTYLEBIT_ALL_VISIBLE );
412 return bMatches;
415 SfxStyleSheetIterator *mIterator;
420 SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
421 SfxStyleFamily eFam, sal_uInt16 n)
422 : pAktStyle(NULL)
423 , nAktPosition(0)
425 pBasePool=pBase;
426 nSearchFamily=eFam;
427 bSearchUsed=false;
428 if( (( n & SFXSTYLEBIT_ALL_VISIBLE ) != SFXSTYLEBIT_ALL_VISIBLE )
429 && ((n & SFXSTYLEBIT_USED) == SFXSTYLEBIT_USED))
431 bSearchUsed = true;
432 n &= ~SFXSTYLEBIT_USED;
434 nMask=n;
437 SfxStyleSheetIterator::~SfxStyleSheetIterator()
441 sal_uInt16 SfxStyleSheetIterator::Count()
443 sal_uInt16 n = 0;
444 if( IsTrivialSearch())
446 n = (sal_uInt16) pBasePool->pImp->mxIndexedStyleSheets->GetNumberOfStyleSheets();
448 else if(nMask == SFXSTYLEBIT_ALL)
450 n = static_cast<sal_uInt16>(pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).size());
452 else
454 DoesStyleMatchStyleSheetPredicate predicate(this);
455 n = pBasePool->pImp->mxIndexedStyleSheets->GetNumberOfStyleSheetsWithPredicate(predicate);
457 return n;
460 SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_uInt16 nIdx)
462 SfxStyleSheetBase* retval = NULL;
463 if( IsTrivialSearch())
465 retval = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(nIdx).get();
466 nAktPosition = nIdx;
468 else if(nMask == SFXSTYLEBIT_ALL)
470 rtl::Reference< SfxStyleSheetBase > ref =
471 pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(
472 pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).at(nIdx))
474 retval = ref.get();
475 nAktPosition = nIdx;
477 else
479 DoesStyleMatchStyleSheetPredicate predicate(this);
480 rtl::Reference< SfxStyleSheetBase > ref =
481 pBasePool->pImp->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(nIdx, predicate);
482 if (ref.get() != NULL)
484 nAktPosition = pBasePool->pImp->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
485 retval = ref.get();
489 if (retval == NULL)
491 OSL_FAIL("Incorrect index");
494 return retval;
497 SfxStyleSheetBase* SfxStyleSheetIterator::First()
499 if (Count() != 0) {
500 return operator[](0);
502 else {
503 return NULL;
508 SfxStyleSheetBase* SfxStyleSheetIterator::Next()
510 SfxStyleSheetBase* retval = NULL;
512 if ( IsTrivialSearch() )
514 unsigned nStyleSheets = pBasePool->pImp->mxIndexedStyleSheets->GetNumberOfStyleSheets();
515 unsigned newPosition = nAktPosition +1;
516 if (nStyleSheets > newPosition)
518 nAktPosition = newPosition;
519 retval = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(nAktPosition).get();
522 else if(nMask == SFXSTYLEBIT_ALL)
524 unsigned newPosition = nAktPosition +1;
525 const std::vector<unsigned>& familyVector =
526 pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily);
527 if (familyVector.size() > newPosition)
529 nAktPosition = newPosition;
530 unsigned stylePosition = familyVector.at(newPosition);
531 retval = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(stylePosition).get();
534 else
536 DoesStyleMatchStyleSheetPredicate predicate(this);
537 rtl::Reference< SfxStyleSheetBase > ref =
538 pBasePool->pImp->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(
539 0, predicate, nAktPosition+1);
540 retval = ref.get();
541 if (retval != NULL) {
542 nAktPosition = pBasePool->pImp->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
545 pAktStyle = retval;
546 return retval;
549 SfxStyleSheetBase* SfxStyleSheetIterator::Find(const OUString& rStr)
551 DoesStyleMatchStyleSheetPredicate predicate(this);
553 std::vector<unsigned> positions =
554 pBasePool->pImp->mxIndexedStyleSheets->FindPositionsByNameAndPredicate(rStr, predicate,
555 svl::IndexedStyleSheets::RETURN_FIRST);
556 if (positions.empty()) {
557 return NULL;
560 unsigned pos = positions.front();
561 SfxStyleSheetBase* pStyle = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(pos).get();
562 nAktPosition = pos;
563 pAktStyle = pStyle;
564 return pAktStyle;
567 sal_uInt16 SfxStyleSheetIterator::GetSearchMask() const
569 sal_uInt16 mask = nMask;
571 if ( bSearchUsed )
572 mask |= SFXSTYLEBIT_USED;
573 return mask;
577 void SfxStyleSheetBasePool::Replace( SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget )
579 rTarget.SetFollow( rSource.GetFollow() );
580 rTarget.SetParent( rSource.GetParent() );
581 SfxItemSet& rSourceSet = rSource.GetItemSet();
582 SfxItemSet& rTargetSet = rTarget.GetItemSet();
583 rTargetSet.Intersect( rSourceSet );
584 rTargetSet.Put( rSourceSet );
587 SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl()
589 if( !pImp->pIter || (pImp->pIter->GetSearchMask() != nMask) || (pImp->pIter->GetSearchFamily() != nSearchFamily) )
591 pImp->pIter = CreateIterator( nSearchFamily, nMask );
594 return *pImp->pIter;
597 SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r ) :
598 pImp(new SfxStyleSheetBasePool_Impl),
599 aAppName(r.GetName()),
600 rPool(r),
601 nSearchFamily(SFX_STYLE_FAMILY_PARA),
602 nMask(SFXSTYLEBIT_ALL)
604 #ifdef DBG_UTIL
605 aDbgStyleSheetReferences.mnPools++;
606 #endif
609 SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r ) :
610 SfxBroadcaster( r ),
611 comphelper::OWeakTypeObject(),
612 pImp(new SfxStyleSheetBasePool_Impl),
613 aAppName(r.aAppName),
614 rPool(r.rPool),
615 nSearchFamily(r.nSearchFamily),
616 nMask( r.nMask )
618 #ifdef DBG_UTIL
619 aDbgStyleSheetReferences.mnPools++;
620 #endif
622 *this += r;
625 SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
627 #ifdef DBG_UTIL
628 aDbgStyleSheetReferences.mnPools--;
629 #endif
631 Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
632 Clear();
633 delete pImp;
636 bool SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const OUString& rStyle, const OUString& rParent)
638 SfxStyleSheetIterator aIter(this,eFam,SFXSTYLEBIT_ALL);
639 SfxStyleSheetBase *pStyle = aIter.Find(rStyle);
640 OSL_ENSURE(pStyle, "Template not found. Writer with solar <2541?");
641 if(pStyle)
642 return pStyle->SetParent(rParent);
643 else
644 return false;
648 void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, sal_uInt16 n)
650 nSearchFamily = eFam; nMask = n;
654 SfxStyleSheetIteratorPtr SfxStyleSheetBasePool::CreateIterator
656 SfxStyleFamily eFam,
657 sal_uInt16 mask
660 return SfxStyleSheetIteratorPtr(new SfxStyleSheetIterator(this,eFam,mask));
663 SfxStyleSheetBase* SfxStyleSheetBasePool::Create
665 const OUString& rName,
666 SfxStyleFamily eFam,
667 sal_uInt16 mask
670 return new SfxStyleSheetBase( rName, this, eFam, mask );
673 SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
675 return new SfxStyleSheetBase( r );
678 SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const OUString& rName, SfxStyleFamily eFam, sal_uInt16 mask)
680 OSL_ENSURE( eFam != SFX_STYLE_FAMILY_ALL, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" );
682 SfxStyleSheetIterator aIter(this, eFam, mask);
683 rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) );
684 OSL_ENSURE( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" );
686 if( !xStyle.is() )
688 xStyle = Create( rName, eFam, mask );
689 StoreStyleSheet(xStyle);
690 Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::CREATED, *xStyle.get() ) );
692 return *xStyle.get();
696 * Helper function: If a template with this name exists it is created
697 * anew. All templates that have this template as a parent are reconnected.
699 SfxStyleSheetBase& SfxStyleSheetBasePool::Add( const SfxStyleSheetBase& rSheet )
701 SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask);
702 SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
703 if (pOld) {
704 Remove( pOld );
706 rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
707 pImp->mxIndexedStyleSheets->AddStyleSheet(xNew);
708 Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::CHANGED, *xNew.get() ) );
709 return *xNew.get();
712 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
714 if( &r != this )
716 Clear();
717 *this += r;
719 return *this;
722 namespace {
723 struct AddStyleSheetCallback : svl::StyleSheetCallback
725 AddStyleSheetCallback(SfxStyleSheetBasePool *pool)
726 : mPool(pool) {;}
728 void DoIt(const SfxStyleSheetBase& ssheet) SAL_OVERRIDE
730 mPool->Add(ssheet);
733 SfxStyleSheetBasePool *mPool;
737 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
739 if( &r != this )
741 AddStyleSheetCallback callback(this);
742 pImp->mxIndexedStyleSheets->ApplyToAllStyleSheets(callback);
744 return *this;
747 sal_uInt16 SfxStyleSheetBasePool::Count()
749 return GetIterator_Impl().Count();
752 SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](sal_uInt16 nIdx)
754 return GetIterator_Impl()[nIdx];
757 SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const OUString& rName,
758 SfxStyleFamily eFam,
759 sal_uInt16 mask)
761 SfxStyleSheetIterator aIter(this,eFam,mask);
762 return aIter.Find(rName);
765 SfxStyleSheetBase* SfxStyleSheetBasePool::First()
767 return GetIterator_Impl().First();
770 SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
772 return GetIterator_Impl().Next();
775 void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
777 if( p )
779 // Reference to keep p alive until after Broadcast call!
780 rtl::Reference<SfxStyleSheetBase> xP(p);
781 bool bWasRemoved = pImp->mxIndexedStyleSheets->RemoveStyleSheet(xP);
782 if( bWasRemoved )
784 // Adapt all styles which have this style as parant
785 ChangeParent( p->GetName(), p->GetParent() );
787 // #120015# Do not dispose, the removed StyleSheet may still be used in
788 // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal,
789 // this works well under normal conditions (checked breaking and counting
790 // on SfxStyleSheetBase constructors and destructors)
792 // com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY );
793 // if( xComp.is() ) try
794 // {
795 // xComp->dispose();
796 // }
797 // catch( com::sun::star::uno::Exception& )
798 // {
799 // }
800 Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::ERASED, *p ) );
805 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
807 #if OSL_DEBUG_LEVEL > 0
808 OSL_ENSURE( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
810 SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
811 SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
812 OSL_ENSURE( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
813 if( !p->GetParent().isEmpty() )
815 pOld = aIter.Find( p->GetParent() );
816 OSL_ENSURE( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
818 #endif
819 StoreStyleSheet(rtl::Reference< SfxStyleSheetBase >( p ) );
820 Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::CREATED, *p ) );
823 namespace
826 struct StyleSheetDisposerFunctor SAL_FINAL : public svl::StyleSheetDisposer
828 StyleSheetDisposerFunctor(SfxStyleSheetBasePool* pool)
829 : mPool(pool) {;}
831 void
832 Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet) SAL_OVERRIDE
834 cppu::OWeakObject* weakObject = static_cast< ::cppu::OWeakObject* >(styleSheet.get());
835 com::sun::star::uno::Reference< com::sun::star::lang::XComponent >
836 xComp( weakObject, com::sun::star::uno::UNO_QUERY );
837 if( xComp.is() ) try
839 xComp->dispose();
841 catch( com::sun::star::uno::Exception& )
844 mPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::ERASED, *styleSheet.get() ) );
847 SfxStyleSheetBasePool* mPool;
852 void SfxStyleSheetBasePool::Clear()
854 StyleSheetDisposerFunctor cleanup(this);
855 pImp->mxIndexedStyleSheets->Clear(cleanup);
858 void SfxStyleSheetBasePool::ChangeParent(const OUString& rOld,
859 const OUString& rNew,
860 bool bVirtual)
862 const sal_uInt16 nTmpMask = GetSearchMask();
863 SetSearchMask(GetSearchFamily(), SFXSTYLEBIT_ALL);
864 for( SfxStyleSheetBase* p = First(); p; p = Next() )
866 if( p->GetParent() == rOld )
868 if(bVirtual)
869 p->SetParent( rNew );
870 else
871 p->aParent = rNew;
874 SetSearchMask(GetSearchFamily(), nTmpMask);
877 void SfxStyleSheetBase::Load( SvStream&, sal_uInt16 )
881 void SfxStyleSheetBase::Store( SvStream& )
885 SfxStyleSheet::SfxStyleSheet(const OUString &rName,
886 const SfxStyleSheetBasePool& r_Pool,
887 SfxStyleFamily eFam,
888 sal_uInt16 mask )
889 : SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool* >( &r_Pool ), eFam, mask)
893 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle)
894 : SfxStyleSheetBase(rStyle)
895 , SfxListener( rStyle )
896 , SfxBroadcaster( rStyle )
897 , svl::StyleSheetUser()
901 SfxStyleSheet::~SfxStyleSheet()
903 Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::INDESTRUCTION, *this ) );
907 bool SfxStyleSheet::SetParent( const OUString& rName )
909 if(aParent == rName)
910 return true;
911 const OUString aOldParent(aParent);
912 if(SfxStyleSheetBase::SetParent(rName))
914 // Remove from notification chain of the old parent if applicable
915 if(!aOldParent.isEmpty())
917 SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(pPool->Find(aOldParent, nFamily, SFXSTYLEBIT_ALL));
918 if(pParent)
919 EndListening(*pParent);
921 // Add to the notification chain of the new parent
922 if(!aParent.isEmpty())
924 SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(pPool->Find(aParent, nFamily, SFXSTYLEBIT_ALL));
925 if(pParent)
926 StartListening(*pParent);
928 return true;
930 return false;
934 * Notify all listeners
936 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
938 Forward(rBC, rHint);
941 bool SfxStyleSheet::isUsedByModel() const
943 return IsUsed();
947 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
948 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
952 SfxStyleSheetBase* SfxStyleSheetPool::Create( const OUString& rName,
953 SfxStyleFamily eFam, sal_uInt16 mask )
955 return new SfxStyleSheet( rName, *this, eFam, mask );
958 SfxUnoStyleSheet::SfxUnoStyleSheet( const OUString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, sal_uInt16 _nMaske )
959 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske )
963 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle )
965 SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() );
966 if( !pRet )
968 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY );
969 if( xUT.is() )
970 pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier())));
972 return pRet;
976 * XUnoTunnel
978 ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException, std::exception)
980 if( rId.getLength() == 16 && 0 == memcmp( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) )
982 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
984 else
986 return 0;
990 void
991 SfxStyleSheetBasePool::StoreStyleSheet(rtl::Reference< SfxStyleSheetBase > xStyle)
993 pImp->mxIndexedStyleSheets->AddStyleSheet(xStyle);
996 namespace
998 class theSfxUnoStyleSheetIdentifier : public rtl::Static< UnoTunnelIdInit, theSfxUnoStyleSheetIdentifier > {};
1001 const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier()
1003 return theSfxUnoStyleSheetIdentifier::get().getSeq();
1006 void
1007 SfxStyleSheetBasePool::Reindex()
1009 pImp->mxIndexedStyleSheets->Reindex();
1012 const svl::IndexedStyleSheets&
1013 SfxStyleSheetBasePool::GetIndexedStyleSheets() const
1015 return *pImp->mxIndexedStyleSheets;
1018 rtl::Reference<SfxStyleSheetBase>
1019 SfxStyleSheetBasePool::GetStyleSheetByPositionInIndex(unsigned pos)
1021 return pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
1024 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */