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