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