xref: /trunk/main/svl/source/items/style.cxx (revision 6b46875c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svl.hxx"
26 
27 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
28 #include <com/sun/star/lang/XComponent.hpp>
29 #endif
30 
31 #define _SVSTDARR_STRINGS
32 #define _SVSTDARR_STRINGSSORTDTOR
33 #define _SVSTDARR_BYTESTRINGS
34 #define _SVSTDARR_BYTESTRINGSSORTDTOR
35 
36 #include <rtl/uuid.h>
37 #include <tools/tenccvt.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <unotools/intlwrapper.hxx>
40 #include <svl/smplhint.hxx>
41 #include <svl/poolitem.hxx>
42 #include <svl/itemset.hxx>
43 #include <svl/itempool.hxx>
44 #include <poolio.hxx>
45 #include <svl/filerec.hxx>
46 #include <svl/itemiter.hxx>
47 #include <svl/style.hxx>
48 #include <svl/svstdarr.hxx>
49 #include <unotools/syslocale.hxx>
50 #include <algorithm>
51 
52 #define STYLESTREAM 			"SfxStyleSheets"
53 #define STYLESTREAM_VERSION 	sal_uInt16(50)
54 
55 #ifdef DBG_UTIL
56 class DbgStyleSheetReferences
57 {
58 public:
59 	DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {}
60 	~DbgStyleSheetReferences()
61 	{
62 		OSL_TRACE("DbgStyleSheetReferences\nSfxStyleSheetBase left %ld\nSfxStyleSheetBasePool left %ld\n", mnStyles, mnPools );
63 	}
64 
65 	sal_uInt32 mnStyles;
66 	sal_uInt32 mnPools;
67 }
68 aDbgStyleSheetReferences;
69 
70 #endif
71 
72 TYPEINIT0(SfxStyleSheetBase)
73 
74 TYPEINIT3(SfxStyleSheet, SfxStyleSheetBase, SfxListener, SfxBroadcaster)
75 
76 
77 //=========================================================================
78 
79 TYPEINIT1(SfxStyleSheetHint, SfxHint);
80 TYPEINIT1(SfxStyleSheetHintExtended, SfxStyleSheetHint);
81 TYPEINIT1(SfxStyleSheetPoolHint, SfxHint);
82 
83 SfxStyleSheetHintExtended::SfxStyleSheetHintExtended
84 (
85 	sal_uInt16				nAction,		// SFX_STYLESHEET_... (s.o.)
86 	const String&       rOldName
87 )
88 :	SfxStyleSheetHint( nAction ),
89 	aName( rOldName )
90 {}
91 SfxStyleSheetHintExtended::SfxStyleSheetHintExtended
92 (
93 	sal_uInt16				nAction,		// SFX_STYLESHEET_... (s.o.)
94 	const String&       rOldName,
95 	SfxStyleSheetBase&	rStyleSheet 	// geh"ort weiterhin dem Aufrufer
96 )
97 :	SfxStyleSheetHint( nAction, rStyleSheet ),
98 	aName( rOldName )
99 {}
100 
101 //-------------------------------------------------------------------------
102 
103 SfxStyleSheetHint::SfxStyleSheetHint
104 (
105 	sal_uInt16				nAction,		// SFX_STYLESHEET_... (s.o.)
106 	SfxStyleSheetBase&	rStyleSheet 	// geh"ort weiterhin dem Aufrufer
107 )
108 :	pStyleSh( &rStyleSheet ),
109 	nHint( nAction )
110 {}
111 
112 SfxStyleSheetHint::SfxStyleSheetHint
113 (
114 	sal_uInt16				nAction		// SFX_STYLESHEET_... (s.o.)
115 )
116 :	pStyleSh( NULL ),
117 	nHint( nAction )
118 {}
119 
120 //=========================================================================
121 
122 class SfxStyleSheetBasePool_Impl
123 {
124   public:
125 	SfxStyles aStyles;
126 	SfxStyleSheetIterator *pIter;
127 	SfxStyleSheetBasePool_Impl() : pIter(0){}
128 	~SfxStyleSheetBasePool_Impl(){delete pIter;}
129 };
130 
131 
132 //////////////////////////// SfxStyleSheetBase ///////////////////////////////
133 
134 // Konstruktoren
135 
136 SfxStyleSheetBase::SfxStyleSheetBase( const XubString& rName, SfxStyleSheetBasePool& r, SfxStyleFamily eFam, sal_uInt16 mask )
137 	: rPool( r )
138 	, nFamily( eFam )
139 	, aName( rName )
140 	, aParent()
141 	, aFollow( rName )
142 	, pSet( NULL )
143 	, nMask(mask)
144 	, nHelpId( 0 )
145 	, bMySet( sal_False )
146 {
147 #ifdef DBG_UTIL
148 	aDbgStyleSheetReferences.mnStyles++;
149 #endif
150 }
151 
152 SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r )
153 	: comphelper::OWeakTypeObject()
154 	, rPool( r.rPool )
155 	, nFamily( r.nFamily )
156 	, aName( r.aName )
157 	, aParent( r.aParent )
158 	, aFollow( r.aFollow )
159 	, aHelpFile( r.aHelpFile )
160 	, nMask( r.nMask )
161 	, nHelpId( r.nHelpId )
162 	, bMySet( r.bMySet )
163 {
164 #ifdef DBG_UTIL
165 	aDbgStyleSheetReferences.mnStyles++;
166 #endif
167 	if( r.pSet )
168 		pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet;
169 	else
170 		pSet = NULL;
171 }
172 
173 static SfxStyleSheetBasePool& implGetStaticPool()
174 {
175 	static SfxStyleSheetBasePool* pSheetPool = 0;
176 	static SfxItemPool* pBasePool = 0;
177 	if( !pSheetPool )
178 	{
179 		UniString aName;
180         pBasePool = new SfxItemPool( aName, 0, 0, 0 );
181 		pSheetPool = new SfxStyleSheetBasePool(*pBasePool);
182 	}
183 	return *pSheetPool;
184 }
185 
186 SfxStyleSheetBase::SfxStyleSheetBase()
187 : comphelper::OWeakTypeObject()
188 , rPool( implGetStaticPool() )
189 {
190 }
191 
192 SfxStyleSheetBase::~SfxStyleSheetBase()
193 {
194 #ifdef DBG_UTIL
195 	--aDbgStyleSheetReferences.mnStyles;
196 #endif
197 
198 	if( bMySet )
199 	{
200 		delete pSet;
201 		pSet = 0;
202 	}
203 }
204 
205 sal_uInt16 SfxStyleSheetBase::GetVersion() const
206 {
207 	return 0x0000;
208 }
209 
210 // Namen aendern
211 
212 const XubString& SfxStyleSheetBase::GetName() const
213 {
214 	return aName;
215 }
216 
217 sal_Bool SfxStyleSheetBase::SetName( const XubString& rName )
218 {
219 	if(rName.Len() == 0)
220 		return sal_False;
221 	if( aName != rName )
222 	{
223 		String aOldName = aName;
224 		SfxStyleSheetBase *pOther = rPool.Find( rName, nFamily ) ;
225 		if ( pOther && pOther != this )
226 			return sal_False;
227 
228 		SfxStyleFamily eTmpFam=rPool.GetSearchFamily();
229 		sal_uInt16 nTmpMask=rPool.GetSearchMask();
230 
231 		rPool.SetSearchMask(nFamily);
232 
233 		if ( aName.Len() )
234 			rPool.ChangeParent( aName, rName, sal_False );
235 		if ( aFollow.Equals( aName ) )
236 			aFollow = rName;
237 		aName = rName;
238 		rPool.SetSearchMask(eTmpFam, nTmpMask);
239 		rPool.Broadcast( SfxStyleSheetHintExtended(
240 			SFX_STYLESHEET_MODIFIED, aOldName, *this ) );
241 	}
242 	return sal_True;
243 }
244 
245 rtl::OUString SfxStyleSheetBase::GetDisplayName() const
246 {
247 	if( maDisplayName.getLength() == 0 )
248 	{
249 		return aName;
250 	}
251 	else
252 	{
253 		return maDisplayName;
254 	}
255 }
256 
257 void SfxStyleSheetBase::SetDisplayName( const rtl::OUString& rDisplayName )
258 {
259 	maDisplayName = rDisplayName;
260 }
261 
262 // Parent aendern
263 
264 const XubString& SfxStyleSheetBase::GetParent() const
265 {
266 	return aParent;
267 }
268 
269 sal_Bool SfxStyleSheetBase::SetParent( const XubString& rName )
270 {
271     if ( rName == aName )
272         return sal_False;
273 
274 	if( aParent != rName )
275 	{
276 		SfxStyleSheetBase* pIter = rPool.Find(rName, nFamily);
277 		if( rName.Len() && !pIter )
278 		{
279 			DBG_ERROR( "StyleSheet-Parent nicht gefunden" );
280 			return sal_False;
281 		}
282 		// rekursive Verknuepfungen verhindern
283 		if( aName.Len() )
284 			while(pIter)
285 			{
286 				if(pIter->GetName() == aName && aName != rName)
287 					return sal_False;
288 				pIter = rPool.Find(pIter->GetParent(), nFamily);
289 			}
290 		aParent = rName;
291 	}
292 	rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) );
293 	return sal_True;
294 }
295 
296 // Follow aendern
297 
298 const XubString& SfxStyleSheetBase::GetFollow() const
299 {
300 	return aFollow;
301 }
302 
303 sal_Bool SfxStyleSheetBase::SetFollow( const XubString& rName )
304 {
305 	if( aFollow != rName )
306 	{
307 		if( !rPool.Find( rName, nFamily ) )
308 		{
309 			DBG_ERROR( "StyleSheet-Follow nicht gefunden" );
310 			return sal_False;
311 		}
312 		aFollow = rName;
313 	}
314 	rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) );
315 	return sal_True;
316 }
317 
318 // Itemset setzen. Die Dflt-Implementation legt ein neues Set an.
319 
320 SfxItemSet& SfxStyleSheetBase::GetItemSet()
321 {
322 	if( !pSet )
323 	{
324 		pSet = new SfxItemSet( rPool.GetPool() );
325 		bMySet = sal_True;
326 	}
327 	return *pSet;
328 }
329 
330 // Hilfe-Datei und -ID setzen und abfragen
331 
332 sal_uLong SfxStyleSheetBase::GetHelpId( String& rFile )
333 {
334 	rFile = aHelpFile;
335 	return nHelpId;
336 }
337 
338 void SfxStyleSheetBase::SetHelpId( const String& rFile, sal_uLong nId )
339 {
340 	aHelpFile = rFile;
341 	nHelpId = nId;
342 }
343 
344 // Folgevorlage m"oglich? Default: Ja
345 
346 sal_Bool SfxStyleSheetBase::HasFollowSupport() const
347 {
348 	return sal_True;
349 }
350 
351 // Basisvorlage m"oglich? Default: Ja
352 
353 sal_Bool SfxStyleSheetBase::HasParentSupport() const
354 {
355 	return sal_True;
356 }
357 
358 // Basisvorlage uf NULL setzen m"oglich? Default: Nein
359 
360 sal_Bool SfxStyleSheetBase::HasClearParentSupport() const
361 {
362 	return sal_False;
363 }
364 
365 // Defaultmaessig sind alle StyleSheets Used
366 
367 sal_Bool SfxStyleSheetBase::IsUsed() const
368 {
369 	return sal_True;
370 }
371 
372 // eingestellte Attribute ausgeben
373 
374 
375 XubString SfxStyleSheetBase::GetDescription()
376 {
377 	return GetDescription( SFX_MAPUNIT_CM );
378 }
379 
380 // eingestellte Attribute ausgeben
381 
382 XubString SfxStyleSheetBase::GetDescription( SfxMapUnit eMetric )
383 {
384 	SfxItemIter aIter( GetItemSet() );
385 	XubString aDesc;
386 	const SfxPoolItem* pItem = aIter.FirstItem();
387 
388     IntlWrapper aIntlWrapper(comphelper::getProcessServiceFactory(),
389             SvtSysLocale().GetLanguage());
390 	while ( pItem )
391 	{
392 		XubString aItemPresentation;
393 
394 		if ( !IsInvalidItem( pItem ) &&
395 			 rPool.GetPool().GetPresentation(
396 				*pItem, SFX_ITEM_PRESENTATION_COMPLETE,
397                 eMetric, aItemPresentation, &aIntlWrapper ) )
398         {
399 			if ( aDesc.Len() && aItemPresentation.Len() )
400 				aDesc.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" + "));
401 			if ( aItemPresentation.Len() )
402 				aDesc += aItemPresentation;
403 		}
404 		pItem = aIter.NextItem();
405 	}
406 	return aDesc;
407 }
408 
409 /////////////////////////// SfxStyleSheetIterator ///////////////////////////////
410 
411 SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
412 {
413 	return nSearchFamily;
414 }
415 
416 inline sal_Bool SfxStyleSheetIterator::IsTrivialSearch()
417 {
418 	return nMask == 0xFFFF && GetSearchFamily() == SFX_STYLE_FAMILY_ALL;
419 }
420 
421 sal_Bool SfxStyleSheetIterator::DoesStyleMatch(SfxStyleSheetBase *pStyle)
422 {
423 	return ((GetSearchFamily() == SFX_STYLE_FAMILY_ALL) ||
424 			( pStyle->GetFamily() == GetSearchFamily() ))
425 		&& (( pStyle->GetMask() & ( GetSearchMask() & ~SFXSTYLEBIT_USED )) ||
426 			( bSearchUsed ? pStyle->IsUsed() : sal_False ) ||
427 			GetSearchMask() == SFXSTYLEBIT_ALL );
428 }
429 
430 
431 SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
432 											 SfxStyleFamily eFam, sal_uInt16 n)
433 {
434 	pBasePool=pBase;
435 	nSearchFamily=eFam;
436 	bSearchUsed=sal_False;
437 		if((n != SFXSTYLEBIT_ALL ) && ((n & SFXSTYLEBIT_USED) == SFXSTYLEBIT_USED))
438 	{
439 		bSearchUsed = sal_True;
440 		n &= ~SFXSTYLEBIT_USED;
441 	}
442 	nMask=n;
443 }
444 
445 SfxStyleSheetIterator::~SfxStyleSheetIterator()
446 {
447 }
448 
449 
450 sal_uInt16 SfxStyleSheetIterator::Count()
451 {
452 	sal_uInt16 n = 0;
453 	if( IsTrivialSearch())
454 		n = (sal_uInt16) pBasePool->aStyles.size();
455 	else
456 		for(sal_uInt16 i=0; i<pBasePool->aStyles.size(); i++)
457 		{
458 			SfxStyleSheetBase* pStyle = pBasePool->aStyles[i].get();
459 			if(DoesStyleMatch(pStyle))
460 				n++;
461 		}
462 	return n;
463 }
464 
465 SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_uInt16 nIdx)
466 {
467 	if( IsTrivialSearch())
468 		return pBasePool->aStyles[nIdx].get();
469 
470 	sal_uInt16 z = 0;
471 	for(sal_uInt16 n=0; n<pBasePool->aStyles.size(); n++)
472 	{
473 		SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
474 		if( DoesStyleMatch(pStyle))
475 		{
476 			if(z == nIdx)
477 			{
478 				nAktPosition=n;
479 				return pAktStyle=pStyle;
480 			}
481 			++z;
482 		}
483 	}
484 	DBG_ERROR("falscher Index");
485 	return 0;
486 }
487 
488 SfxStyleSheetBase* SfxStyleSheetIterator::First()
489 {
490 	sal_Int32 nIdx = -1;
491 
492 	if ( IsTrivialSearch() && pBasePool->aStyles.size() )
493 		nIdx = 0;
494 	else
495 		for( sal_uInt16 n = 0; n < pBasePool->aStyles.size(); n++ )
496 		{
497 			SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
498 
499 			if ( DoesStyleMatch( pStyle ) )
500 			{
501 				nIdx = n;
502 				break;
503 			}
504 		}
505 
506 	if ( nIdx != -1 )
507 	{
508 		nAktPosition = (sal_uInt16)nIdx;
509 		return pAktStyle = pBasePool->aStyles[nIdx].get();
510 	}
511 	return 0;
512 }
513 
514 
515 SfxStyleSheetBase* SfxStyleSheetIterator::Next()
516 {
517 	sal_Int32 nIdx = -1;
518 
519 	if ( IsTrivialSearch() &&
520 		 (sal_uInt16)pBasePool->aStyles.size() > nAktPosition + 1 )
521 		nIdx = nAktPosition + 1;
522 	else
523 		for( sal_uInt16 n = nAktPosition + 1; n < pBasePool->aStyles.size(); n++ )
524 		{
525 			SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
526 
527 			if ( DoesStyleMatch( pStyle ) )
528 			{
529 				nIdx = n;
530 				break;
531 			}
532 		}
533 
534 	if ( nIdx != -1 )
535 	{
536 		nAktPosition = (sal_uInt16)nIdx;
537 		return pAktStyle = pBasePool->aStyles[nIdx].get();
538 	}
539 	return 0;
540 }
541 
542 
543 SfxStyleSheetBase* SfxStyleSheetIterator::Find(const XubString& rStr)
544 {
545 	for ( sal_uInt16 n = 0; n < pBasePool->aStyles.size(); n++ )
546 	{
547 		SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
548 
549         // #98454# performance: in case of bSearchUsed==sal_True it may be
550         // significant to first compare the name and only if it matches to call
551         // the style sheet IsUsed() method in DoesStyleMatch().
552         if ( pStyle->GetName().Equals( rStr ) && DoesStyleMatch( pStyle ) )
553 		{
554 			nAktPosition = n;
555 			return pAktStyle = pStyle;
556 		}
557 	}
558 	return 0;
559 }
560 
561 
562 sal_uInt16 SfxStyleSheetIterator::GetSearchMask() const
563 {
564 	sal_uInt16 mask = nMask;
565 
566 	if ( bSearchUsed )
567 		mask |= SFXSTYLEBIT_USED;
568 	return mask;
569 }
570 
571 /////////////////////////// SfxStyleSheetBasePool ///////////////////////////////
572 
573 void SfxStyleSheetBasePool::Replace(
574 	SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget )
575 {
576 	rTarget.SetFollow( rSource.GetFollow() );
577 	rTarget.SetParent( rSource.GetParent() );
578 	SfxItemSet& rSourceSet = rSource.GetItemSet();
579 	SfxItemSet& rTargetSet = rTarget.GetItemSet();
580 	rTargetSet.Intersect( rSourceSet );
581 	rTargetSet.Put( rSourceSet );
582 }
583 
584 SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl()
585 {
586 	SfxStyleSheetIterator*& rpIter = pImp->pIter;
587 	if( !rpIter || (rpIter->GetSearchMask() != nMask) || (rpIter->GetSearchFamily() != nSearchFamily) )
588 	{
589 		delete rpIter;
590 		rpIter = CreateIterator( nSearchFamily, nMask );
591 	}
592 	return *rpIter;
593 }
594 
595 
596 SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r )
597 	: aAppName(r.GetName())
598 	, rPool(r)
599 	, nSearchFamily(SFX_STYLE_FAMILY_PARA)
600 	, nMask(0xFFFF)
601 {
602 #ifdef DBG_UTIL
603 	aDbgStyleSheetReferences.mnPools++;
604 #endif
605 
606 	pImp = new SfxStyleSheetBasePool_Impl;
607 }
608 
609 SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r )
610 	: SfxBroadcaster( r )
611 	, comphelper::OWeakTypeObject()
612     , aAppName(r.aAppName)
613 	, rPool(r.rPool)
614 	, nSearchFamily(r.nSearchFamily)
615 	, nMask( r.nMask )
616 {
617 #ifdef DBG_UTIL
618 	aDbgStyleSheetReferences.mnPools++;
619 #endif
620 
621 	pImp = new SfxStyleSheetBasePool_Impl;
622 	*this += r;
623 }
624 
625 SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
626 {
627 #ifdef DBG_UTIL
628 	aDbgStyleSheetReferences.mnPools--;
629 #endif
630 
631 	Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
632 	Clear();
633 	delete pImp;
634 }
635 
636 sal_Bool SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const XubString& rStyle, const XubString& rParent)
637 {
638 	SfxStyleSheetIterator aIter(this,eFam,SFXSTYLEBIT_ALL);
639 	SfxStyleSheetBase *pStyle =
640 		aIter.Find(rStyle);
641 	DBG_ASSERT(pStyle, "Vorlage nicht gefunden. Writer mit Solar <2541??");
642 	if(pStyle)
643 		return pStyle->SetParent(rParent);
644 	else
645 		return sal_False;
646 }
647 
648 
649 void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, sal_uInt16 n)
650 {
651 	nSearchFamily = eFam; nMask = n;
652 }
653 
654 sal_uInt16 SfxStyleSheetBasePool::GetSearchMask() const
655 {
656 	return nMask;
657 }
658 
659 
660 // Der Name des Streams
661 
662 String SfxStyleSheetBasePool::GetStreamName()
663 {
664 	return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STYLESTREAM));
665 }
666 
667 /////////////////////////////////// Factory ////////////////////////////////
668 
669 
670 
671 SfxStyleSheetIterator* SfxStyleSheetBasePool::CreateIterator
672 (
673  SfxStyleFamily eFam,
674  sal_uInt16 mask
675 )
676 {
677 	return new SfxStyleSheetIterator(this,eFam,mask);
678 }
679 
680 
681 SfxStyleSheetBase* SfxStyleSheetBasePool::Create
682 (
683 	const XubString& rName,
684 	SfxStyleFamily eFam,
685 	sal_uInt16 mask
686 )
687 {
688 	return new SfxStyleSheetBase( rName, *this, eFam, mask );
689 }
690 
691 SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
692 {
693 	return new SfxStyleSheetBase( r );
694 }
695 
696 SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const XubString& rName, SfxStyleFamily eFam, sal_uInt16 mask, sal_uInt16 nPos)
697 {
698 	DBG_ASSERT( eFam != SFX_STYLE_FAMILY_ALL, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" );
699 
700 	SfxStyleSheetIterator aIter(this, eFam, mask);
701 	rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) );
702 	DBG_ASSERT( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" );
703 	SfxStyleSheetIterator& rIter = GetIterator_Impl();
704 
705 	if( !xStyle.is() )
706 	{
707 		xStyle = Create( rName, eFam, mask );
708 		if(0xffff == nPos || nPos == aStyles.size() || nPos == rIter.Count())
709 		{
710 			aStyles.push_back( xStyle );
711 		}
712 		else
713 		{
714 			rIter[nPos];
715 			aStyles.insert( aStyles.begin() + rIter.GetPos(), xStyle );
716 		}
717 		Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *xStyle.get() ) );
718 	}
719 	return *xStyle.get();
720 }
721 
722 /////////////////////////////// Kopieren ///////////////////////////////////
723 
724 // Hilfsroutine: Falls eine Vorlage dieses Namens existiert, wird
725 // sie neu erzeugt. Alle Vorlagen, die diese Vorlage zum Parent haben,
726 // werden umgehaengt.
727 
728 SfxStyleSheetBase& SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet )
729 {
730 	SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask);
731 	SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
732 	Remove( pOld );
733 	rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
734 	aStyles.push_back( xNew );
735 	Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *xNew.get() ) );
736 	return *xNew.get();
737 }
738 
739 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
740 {
741 	if( &r != this )
742 	{
743 		Clear();
744 		*this += r;
745 	}
746 	return *this;
747 }
748 
749 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
750 {
751 	if( &r != this )
752 	{
753 		SfxStyles::const_iterator aIter( r.aStyles.begin() );
754 		while( aIter != r.aStyles.end() )
755 		{
756 			Add(*(*aIter++).get());
757 		}
758 	}
759 	return *this;
760 }
761 
762 //////////////////////////////// Suchen ////////////////////////////////////
763 
764 sal_uInt16 SfxStyleSheetBasePool::Count()
765 {
766 	return GetIterator_Impl().Count();
767 }
768 
769 SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](sal_uInt16 nIdx)
770 {
771 	return GetIterator_Impl()[nIdx];
772 }
773 
774 SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const XubString& rName,
775 											   SfxStyleFamily eFam,
776 											   sal_uInt16 mask)
777 {
778 	SfxStyleSheetIterator aIter(this,eFam,mask);
779 	return aIter.Find(rName);
780 }
781 
782 const SfxStyles& SfxStyleSheetBasePool::GetStyles()
783 {
784 	return aStyles;
785 }
786 
787 SfxStyleSheetBase* SfxStyleSheetBasePool::First()
788 {
789 	return GetIterator_Impl().First();
790 }
791 
792 SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
793 {
794 	return GetIterator_Impl().Next();
795 }
796 
797 //////////////////////////////// Loeschen /////////////////////////////////
798 
799 void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
800 {
801 	if( p )
802 	{
803 		SfxStyles::iterator aIter( std::find( aStyles.begin(), aStyles.end(), rtl::Reference< SfxStyleSheetBase >( p ) ) );
804 		if( aIter != aStyles.end() )
805 		{
806 			// Alle Styles umsetzen, deren Parent dieser hier ist
807 			ChangeParent( p->GetName(), p->GetParent() );
808 
809             // #120015# Do not dispose, the removed StyleSheet may still be used in
810             // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal,
811             // this works well under normal conditions (checked breaking and counting
812             // on SfxStyleSheetBase constructors and destructors)
813             //
814 			// com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY );
815 			// if( xComp.is() ) try
816 			// {
817 			// 	xComp->dispose();
818 			// }
819 			// catch( com::sun::star::uno::Exception& )
820 			// {
821 			// }
822 
823 			aStyles.erase(aIter);
824 			Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) );
825 		}
826 	}
827 }
828 
829 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
830 {
831 	DBG_ASSERT( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
832 
833 	SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
834 	SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
835 	DBG_ASSERT( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
836 	if( p->GetParent().Len() )
837 	{
838 		pOld = aIter.Find( p->GetParent() );
839 		DBG_ASSERT( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
840 	}
841 	aStyles.push_back( rtl::Reference< SfxStyleSheetBase >( p ) );
842 	Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) );
843 }
844 
845 void SfxStyleSheetBasePool::Clear()
846 {
847 	SfxStyles aClearStyles;
848 	aClearStyles.swap( aStyles );
849 
850 	SfxStyles::iterator aIter( aClearStyles.begin() );
851 	while( aIter != aClearStyles.end() )
852 	{
853 		com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY );
854 		if( xComp.is() ) try
855 		{
856 			xComp->dispose();
857 		}
858 		catch( com::sun::star::uno::Exception& )
859 		{
860 		}
861 
862 		Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) );
863 	}
864 }
865 
866 /////////////////////////// Parents umsetzen ////////////////////////////////
867 
868 void SfxStyleSheetBasePool::ChangeParent(const XubString& rOld,
869 										 const XubString& rNew,
870 										 sal_Bool bVirtual)
871 {
872 	const sal_uInt16 nTmpMask = GetSearchMask();
873 	SetSearchMask(GetSearchFamily(), 0xffff);
874 	for( SfxStyleSheetBase* p = First(); p; p = Next() )
875 	{
876 		if( p->GetParent().Equals( rOld ) )
877 		{
878 			if(bVirtual)
879 				p->SetParent( rNew );
880 			else
881 				p->aParent = rNew;
882 		}
883 	}
884 	SetSearchMask(GetSearchFamily(), nTmpMask);
885 }
886 
887 /////////////////////////// Laden/Speichern /////////////////////////////////
888 
889 void SfxStyleSheetBase::Load( SvStream&, sal_uInt16 )
890 {
891 }
892 
893 void SfxStyleSheetBase::Store( SvStream& )
894 {
895 }
896 
897 
898 sal_Bool SfxStyleSheetBasePool::Load( SvStream& rStream )
899 {
900 	// alte Version?
901 	if ( !rPool.IsVer2_Impl() )
902 		return Load1_Impl( rStream );
903 
904 	// gesamten StyleSheetPool in neuer Version aus einem MiniRecord lesen
905 	SfxMiniRecordReader aPoolRec( &rStream, SFX_STYLES_REC );
906 
907 	// Header-Record lesen
908 	short nCharSet = 0;
909 	if ( !rStream.GetError() )
910 	{
911 		SfxSingleRecordReader aHeaderRec( &rStream, SFX_STYLES_REC_HEADER );
912 		if ( !aHeaderRec.IsValid() )
913 			return sal_False;
914 
915 		aAppName = rPool.GetName();
916 		rStream >> nCharSet;
917 	}
918 
919 	// Styles-Record lesen
920 	if ( !rStream.GetError() )
921 	{
922 		SfxMultiRecordReader aStylesRec( &rStream, SFX_STYLES_REC_STYLES );
923 		if ( !aStylesRec.IsValid() )
924 			return sal_False;
925 
926 		rtl_TextEncoding eEnc = GetSOLoadTextEncoding(
927             (rtl_TextEncoding)nCharSet,
928             sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) );
929 		rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
930 		rStream.SetStreamCharSet( eEnc );
931 
932 		sal_uInt16 nStyles;
933 		for ( nStyles = 0; aStylesRec.GetContent(); nStyles++ )
934 		{
935 			// kann nicht mehr weiterlesen?
936 			if ( rStream.GetError() )
937 				break;
938 
939 			// Globale Teile
940 			XubString aName, aParent, aFollow;
941 			String aHelpFile;
942 			sal_uInt16 nFamily, nStyleMask,nCount;
943 			sal_uInt32 nHelpId;
944 			rStream.ReadByteString(aName, eEnc );
945 			rStream.ReadByteString(aParent, eEnc );
946 			rStream.ReadByteString(aFollow, eEnc );
947 			rStream >> nFamily >> nStyleMask;
948 			SfxPoolItem::readByteString(rStream, aHelpFile);
949 			rStream >> nHelpId;
950 
951 			SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask);
952 			rSheet.SetHelpId( aHelpFile, nHelpId );
953 			// Hier erst einmal Parent und Follow zwischenspeichern
954 			rSheet.aParent = aParent;
955 			rSheet.aFollow = aFollow;
956 			sal_uInt32 nPos = rStream.Tell();
957 			rStream >> nCount;
958 			if(nCount)
959 			{
960 				rStream.Seek( nPos );
961 				// Das Laden des ItemSets bedient sich der Methode GetItemSet(),
962 				// damit eigene ItemSets untergeschoben werden koennen
963 				SfxItemSet& rSet = rSheet.GetItemSet();
964 				rSet.ClearItem();
965 	//! 		SfxItemSet aTmpSet( *pTmpPool );
966 				/*!aTmpSet*/ rSet.Load( rStream );
967 				//! rSet.Put( aTmpSet );
968 			}
969 			// Lokale Teile
970 			sal_uInt32 nSize;
971 			sal_uInt16 nVer;
972 			rStream >> nVer >> nSize;
973 			nPos = rStream.Tell() + nSize;
974 			rSheet.Load( rStream, nVer );
975 			rStream.Seek( nPos );
976 		}
977 
978 		//	#72939# only loop through the styles that were really inserted
979 		sal_uLong n = aStyles.size();
980 
981 		//! delete pTmpPool;
982 		// Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
983 		// Mit Setxxx() noch einmal den String eintragen, da diese
984 		// virtuellen Methoden evtl. ueberlagert sind.
985 		for ( sal_uLong i = 0; i < n; i++ )
986 		{
987 			SfxStyleSheetBase* p = aStyles[ i ].get();
988 			XubString aText = p->aParent;
989 			p->aParent.Erase();
990 			p->SetParent( aText );
991 			aText = p->aFollow;
992 			p->aFollow.Erase();
993 			p->SetFollow( aText );
994 		}
995 
996 		rStream.SetStreamCharSet( eOldEnc );
997 	}
998 
999 	// alles klar?
1000 	return sal_Bool( rStream.GetError() == SVSTREAM_OK );
1001 }
1002 
1003 sal_Bool SfxStyleSheetBasePool::Load1_Impl( SvStream& rStream )
1004 {
1005 	aAppName = rPool.GetName();
1006 	sal_uInt16 nVersion;
1007 	short nCharSet;
1008 	rStream >> nVersion;
1009 
1010 	if(nVersion!=STYLESTREAM_VERSION)
1011 		nCharSet=nVersion;
1012 	else
1013 		rStream >> nCharSet;
1014 
1015 	rtl_TextEncoding eEnc = GetSOLoadTextEncoding(
1016         (rtl_TextEncoding)nCharSet,
1017         sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) );
1018 	rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
1019 	rStream.SetStreamCharSet( eEnc );
1020 
1021 	sal_uInt16 nStyles;
1022 	rStream >> nStyles;
1023 	sal_uInt16 i;
1024 	for ( i = 0; i < nStyles; i++ )
1025 	{
1026 		// kann nicht mehr weiterlesen?
1027 		if ( rStream.GetError() )
1028 		{
1029 			nStyles = i;
1030 			break;
1031 		}
1032 
1033 		// Globale Teile
1034 		XubString aName, aParent, aFollow;
1035 		String aHelpFile;
1036 		sal_uInt16 nFamily, nStyleMask,nCount;
1037 		sal_uInt32 nHelpId;
1038 		rStream.ReadByteString(aName, eEnc );
1039 		rStream.ReadByteString(aParent, eEnc );
1040 		rStream.ReadByteString(aFollow, eEnc );
1041 		rStream >> nFamily >> nStyleMask;
1042 		SfxPoolItem::readByteString(rStream, aHelpFile);
1043 		if(nVersion!=STYLESTREAM_VERSION)
1044 		{
1045 			sal_uInt16 nTmpHelpId;
1046 			rStream >> nTmpHelpId;
1047 			nHelpId=nTmpHelpId;
1048 		}
1049 		else
1050 			rStream >> nHelpId;
1051 
1052 		SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask);
1053 		rSheet.SetHelpId( aHelpFile, nHelpId );
1054 		// Hier erst einmal Parent und Follow zwischenspeichern
1055 		rSheet.aParent = aParent;
1056 		rSheet.aFollow = aFollow;
1057 		sal_uInt32 nPos = rStream.Tell();
1058 		rStream >> nCount;
1059 		if(nCount) {
1060 			rStream.Seek( nPos );
1061 			// Das Laden des ItemSets bedient sich der Methode GetItemSet(),
1062 			// damit eigene ItemSets untergeschoben werden koennen
1063 			SfxItemSet& rSet = rSheet.GetItemSet();
1064 			rSet.ClearItem();
1065 //! 		SfxItemSet aTmpSet( *pTmpPool );
1066 			/*!aTmpSet*/ rSet.Load( rStream );
1067 			//! rSet.Put( aTmpSet );
1068 		}
1069 		// Lokale Teile
1070 		sal_uInt32 nSize;
1071 		sal_uInt16 nVer;
1072 		rStream >> nVer >> nSize;
1073 		nPos = rStream.Tell() + nSize;
1074 		rSheet.Load( rStream, nVer );
1075 		rStream.Seek( nPos );
1076 	}
1077 
1078 	//! delete pTmpPool;
1079 	// Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
1080 	// Mit Setxxx() noch einmal den String eintragen, da diese
1081 	// virtuellen Methoden evtl. ueberlagert sind.
1082 	for ( i = 0; i < nStyles; i++ )
1083 	{
1084 		SfxStyleSheetBase* p = aStyles[ i ].get();
1085 		XubString aText = p->aParent;
1086 		p->aParent.Erase();
1087 		p->SetParent( aText );
1088 		aText = p->aFollow;
1089 		p->aFollow.Erase();
1090 		p->SetFollow( aText );
1091 	}
1092 
1093 	rStream.SetStreamCharSet( eOldEnc );
1094 
1095 	return sal_Bool( rStream.GetError() == SVSTREAM_OK );
1096 }
1097 
1098 sal_Bool SfxStyleSheetBasePool::Store( SvStream& rStream, sal_Bool bUsed )
1099 {
1100 	// den ganzen StyleSheet-Pool in einen Mini-Record
1101 	SfxMiniRecordWriter aPoolRec( &rStream, SFX_STYLES_REC );
1102 
1103 	// Erst einmal die Dummies rauszaehlen; die werden nicht gespeichert
1104 	sal_uInt16 nCount = 0;
1105 	for( SfxStyleSheetBase* p = First(); p; p = Next() )
1106 	{
1107 		if(!bUsed || p->IsUsed())
1108 			nCount++;
1109 	}
1110 
1111 	// einen Header-Record vorweg
1112 	rtl_TextEncoding eEnc
1113 		= ::GetSOStoreTextEncoding(
1114             rStream.GetStreamCharSet(),
1115             sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) );
1116 	rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
1117 	rStream.SetStreamCharSet( eEnc );
1118 
1119 	{
1120 		SfxSingleRecordWriter aHeaderRec( &rStream,
1121 				SFX_STYLES_REC_HEADER,
1122 				STYLESTREAM_VERSION );
1123 		rStream << (short) eEnc;
1124 	}
1125 
1126 	// die StyleSheets in einen MultiVarRecord
1127 	{
1128 		// Bug 79478:
1129 		// make a check loop, to be shure, that the converted names are also
1130 		// unique like the originals! In other cases we get a loop.
1131 		SvStringsSortDtor aSortOrigNames( 0, 128 );
1132 		SvStrings aOrigNames( 0, 128 );
1133 		SvByteStringsSortDtor aSortConvNames( 0, 128 );
1134 		SvByteStrings aConvNames( 0, 128 );
1135 
1136 		{
1137 
1138 			for( SfxStyleSheetBase* p = First(); p; p = Next() )
1139 			{
1140 				if(!bUsed || p->IsUsed())
1141 				{
1142 					sal_uInt16 nFamily = (sal_uInt16)p->GetFamily();
1143 					String* pName = new String( p->GetName() );
1144 					ByteString* pConvName = new ByteString( *pName, eEnc );
1145 
1146 					pName->Insert( (sal_Unicode)nFamily, 0 );
1147 					pConvName->Insert( "  ", 0 );
1148 					pConvName->SetChar(
1149                         0,
1150                         sal::static_int_cast< char >(0xff & (nFamily >> 8)) );
1151 					pConvName->SetChar(
1152                         1, sal::static_int_cast< char >(0xff & nFamily) );
1153 
1154 					sal_uInt16 nInsPos, nAdd = aSortConvNames.Count();
1155 					while( !aSortConvNames.Insert( pConvName, nInsPos ) )
1156 						(pConvName->Append( '_' )).Append(
1157 									ByteString::CreateFromInt32( nAdd++ ));
1158 					aOrigNames.Insert( pName, nInsPos );
1159 				}
1160 			}
1161 
1162 			// now we have the list of the names, sorted by convertede names
1163 			// But now we need the sorted list of orignames.
1164 			{
1165 				sal_uInt16 nInsPos, nEnd = aOrigNames.Count();
1166 				const ByteStringPtr* ppB = aSortConvNames.GetData();
1167 				for( sal_uInt16 n = 0; n < nEnd; ++n, ++ppB )
1168 				{
1169 					String* p = aOrigNames.GetObject( n );
1170 					aSortOrigNames.Insert( p, nInsPos );
1171 					aConvNames.Insert( *ppB, nInsPos );
1172 				}
1173 
1174 			}
1175 		}
1176 
1177 
1178 		ByteString sEmpty;
1179 		sal_uInt16 nFndPos;
1180 		String sNm;
1181 		SfxMultiVarRecordWriter aStylesRec( &rStream, SFX_STYLES_REC_STYLES, 0 );
1182 		for( SfxStyleSheetBase* p = First(); p; p = Next() )
1183 		{
1184 			if(!bUsed || p->IsUsed())
1185 			{
1186 				aStylesRec.NewContent();
1187 
1188 				// Globale Teile speichern
1189 				String aHelpFile;
1190 				sal_uInt32 nHelpId = p->GetHelpId( aHelpFile );
1191 				sal_uInt16 nFamily = sal::static_int_cast< sal_uInt16 >(p->GetFamily());
1192 				String sFamily( (sal_Unicode)nFamily );
1193 
1194 				(sNm = sFamily) += p->GetName();
1195 				if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1196 					rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1197 				else
1198 					rStream.WriteByteString( sEmpty );
1199 
1200 				(sNm = sFamily) += p->GetParent();
1201 				if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1202 					rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1203 				else
1204 					rStream.WriteByteString( sEmpty );
1205 
1206 				(sNm = sFamily) += p->GetFollow();
1207 				if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1208 					rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1209 				else
1210 					rStream.WriteByteString( sEmpty );
1211 
1212 				rStream << nFamily << p->GetMask();
1213 				SfxPoolItem::writeByteString(rStream, aHelpFile);
1214 				rStream << nHelpId;
1215 				if(p->pSet)
1216 					p->pSet->Store( rStream );
1217 				else
1218 					rStream << (sal_uInt16)0;
1219 
1220 				// Lokale Teile speichern
1221 				// Vor dem lokalen Teil wird die Laenge der lokalen Daten
1222 				// als sal_uInt32 sowie die Versionsnummer gespeichert.
1223 				rStream << (sal_uInt16) p->GetVersion();
1224 				sal_uLong nPos1 = rStream.Tell();
1225 				rStream << (sal_uInt32) 0;
1226 				p->Store( rStream );
1227 				sal_uLong nPos2 = rStream.Tell();
1228 				rStream.Seek( nPos1 );
1229 				rStream << (sal_uInt32) ( nPos2 - nPos1 - sizeof( sal_uInt32 ) );
1230 				rStream.Seek( nPos2 );
1231 				if( rStream.GetError() != SVSTREAM_OK )
1232 					break;
1233 			}
1234 		}
1235 	}
1236 
1237 	rStream.SetStreamCharSet( eOldEnc );
1238 
1239 	return sal_Bool( rStream.GetError() == SVSTREAM_OK );
1240 }
1241 
1242 SfxItemPool& SfxStyleSheetBasePool::GetPool()
1243 {
1244 	return rPool;
1245 }
1246 
1247 const SfxItemPool& SfxStyleSheetBasePool::GetPool() const
1248 {
1249 	return rPool;
1250 }
1251 
1252 /////////////////////// SfxStyleSheet /////////////////////////////////
1253 
1254 SfxStyleSheet::SfxStyleSheet(const XubString &rName,
1255 							 const SfxStyleSheetBasePool& r_Pool,
1256 							 SfxStyleFamily eFam,
1257 							 sal_uInt16 mask ):
1258 	SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool& >( r_Pool ), eFam, mask)
1259 {}
1260 
1261 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle) :
1262 	SfxStyleSheetBase(rStyle),
1263     SfxListener( rStyle ),
1264     SfxBroadcaster( rStyle )
1265 {}
1266 
1267 SfxStyleSheet::SfxStyleSheet()
1268 {
1269 }
1270 
1271 SfxStyleSheet::~SfxStyleSheet()
1272 {
1273 	Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_INDESTRUCTION, *this ) );
1274 }
1275 
1276 
1277 sal_Bool SfxStyleSheet::SetParent( const XubString& rName )
1278 {
1279 	if(aParent == rName)
1280 		return sal_True;
1281 	const XubString aOldParent(aParent);
1282 	if(SfxStyleSheetBase::SetParent(rName)) {
1283 			// aus der Benachrichtigungskette des alten
1284 			// Parents gfs. austragen
1285 		if(aOldParent.Len()) {
1286 			SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aOldParent, nFamily, 0xffff);
1287 			if(pParent)
1288 				EndListening(*pParent);
1289 		}
1290 			// in die Benachrichtigungskette des neuen
1291 			// Parents eintragen
1292 		if(aParent.Len()) {
1293 			SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aParent, nFamily, 0xffff);
1294 			if(pParent)
1295 				StartListening(*pParent);
1296 		}
1297 		return sal_True;
1298 	}
1299 	return sal_False;
1300 }
1301 
1302 // alle Zuhoerer benachtichtigen
1303 
1304 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
1305 {
1306 	Forward(rBC, rHint);
1307 }
1308 
1309 //////////////////////// SfxStyleSheetPool ///////////////////////////////
1310 
1311 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
1312 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
1313 {
1314 }
1315 
1316 /////////////////////////////////// Factory ////////////////////////////////
1317 
1318 SfxStyleSheetBase* SfxStyleSheetPool::Create( const XubString& rName,
1319 									SfxStyleFamily eFam, sal_uInt16 mask )
1320 {
1321 	return new SfxStyleSheet( rName, *this, eFam, mask );
1322 }
1323 
1324 SfxStyleSheetBase* SfxStyleSheetPool::Create( const SfxStyleSheet& r )
1325 {
1326 	return new SfxStyleSheet( r );
1327 }
1328 /*
1329 sal_Bool SfxStyleSheetPool::CopyTo(SfxStyleSheetPool &, const String &)
1330 {
1331 	return sal_False;
1332 }
1333 */
1334 
1335 // --------------------------------------------------------------------
1336 // class SfxUnoStyleSheet
1337 // --------------------------------------------------------------------
1338 
1339 SfxUnoStyleSheet::SfxUnoStyleSheet( const UniString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, sal_uInt16 _nMaske )
1340 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske )
1341 {
1342 }
1343 
1344 // --------------------------------------------------------------------
1345 SfxUnoStyleSheet::SfxUnoStyleSheet( const SfxStyleSheet& _rSheet )
1346 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rSheet )
1347 {
1348 }
1349 
1350 // --------------------------------------------------------------------
1351 
1352 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle )
1353 {
1354 	SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() );
1355 	if( !pRet )
1356 	{
1357 		::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY );
1358 		if( xUT.is() )
1359 			pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier())));
1360 	}
1361 	return pRet;
1362 }
1363 
1364 // --------------------------------------------------------------------
1365 // XUnoTunnel
1366 // --------------------------------------------------------------------
1367 
1368 ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException)
1369 {
1370 	if( rId.getLength() == 16 && 0 == rtl_compareMemory( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) )
1371 	{
1372 		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
1373 	}
1374 	else
1375 	{
1376 		return 0;
1377 	}
1378 }
1379 
1380 // --------------------------------------------------------------------
1381 
1382 const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier()
1383 {
1384 	static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0;
1385 	if( !pSeq )
1386 	{
1387 		::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
1388 		if( !pSeq )
1389 		{
1390 			static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
1391 			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
1392 			pSeq = &aSeq;
1393 		}
1394 	}
1395 	return *pSeq;
1396 }
1397 
1398 // --------------------------------------------------------------------
1399