xref: /AOO41X/main/svl/source/items/style.cxx (revision 707fc0d4d52eb4f69d89a98ffec6918ca5de6326)
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             com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY );
810             if( xComp.is() ) try
811             {
812                 xComp->dispose();
813             }
814             catch( com::sun::star::uno::Exception& )
815             {
816             }
817 
818             aStyles.erase(aIter);
819             Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) );
820         }
821     }
822 }
823 
824 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
825 {
826     DBG_ASSERT( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
827 
828     SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
829     SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
830     DBG_ASSERT( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
831     if( p->GetParent().Len() )
832     {
833         pOld = aIter.Find( p->GetParent() );
834         DBG_ASSERT( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
835     }
836     aStyles.push_back( rtl::Reference< SfxStyleSheetBase >( p ) );
837     Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) );
838 }
839 
840 void SfxStyleSheetBasePool::Clear()
841 {
842     SfxStyles aClearStyles;
843     aClearStyles.swap( aStyles );
844 
845     SfxStyles::iterator aIter( aClearStyles.begin() );
846     while( aIter != aClearStyles.end() )
847     {
848         com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY );
849         if( xComp.is() ) try
850         {
851             xComp->dispose();
852         }
853         catch( com::sun::star::uno::Exception& )
854         {
855         }
856 
857         Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) );
858     }
859 }
860 
861 /////////////////////////// Parents umsetzen ////////////////////////////////
862 
863 void SfxStyleSheetBasePool::ChangeParent(const XubString& rOld,
864                                          const XubString& rNew,
865                                          sal_Bool bVirtual)
866 {
867     const sal_uInt16 nTmpMask = GetSearchMask();
868     SetSearchMask(GetSearchFamily(), 0xffff);
869     for( SfxStyleSheetBase* p = First(); p; p = Next() )
870     {
871         if( p->GetParent().Equals( rOld ) )
872         {
873             if(bVirtual)
874                 p->SetParent( rNew );
875             else
876                 p->aParent = rNew;
877         }
878     }
879     SetSearchMask(GetSearchFamily(), nTmpMask);
880 }
881 
882 /////////////////////////// Laden/Speichern /////////////////////////////////
883 
884 void SfxStyleSheetBase::Load( SvStream&, sal_uInt16 )
885 {
886 }
887 
888 void SfxStyleSheetBase::Store( SvStream& )
889 {
890 }
891 
892 
893 sal_Bool SfxStyleSheetBasePool::Load( SvStream& rStream )
894 {
895     // alte Version?
896     if ( !rPool.IsVer2_Impl() )
897         return Load1_Impl( rStream );
898 
899     // gesamten StyleSheetPool in neuer Version aus einem MiniRecord lesen
900     SfxMiniRecordReader aPoolRec( &rStream, SFX_STYLES_REC );
901 
902     // Header-Record lesen
903     short nCharSet = 0;
904     if ( !rStream.GetError() )
905     {
906         SfxSingleRecordReader aHeaderRec( &rStream, SFX_STYLES_REC_HEADER );
907         if ( !aHeaderRec.IsValid() )
908             return sal_False;
909 
910         aAppName = rPool.GetName();
911         rStream >> nCharSet;
912     }
913 
914     // Styles-Record lesen
915     if ( !rStream.GetError() )
916     {
917         SfxMultiRecordReader aStylesRec( &rStream, SFX_STYLES_REC_STYLES );
918         if ( !aStylesRec.IsValid() )
919             return sal_False;
920 
921         rtl_TextEncoding eEnc = GetSOLoadTextEncoding(
922             (rtl_TextEncoding)nCharSet,
923             sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) );
924         rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
925         rStream.SetStreamCharSet( eEnc );
926 
927         sal_uInt16 nStyles;
928         for ( nStyles = 0; aStylesRec.GetContent(); nStyles++ )
929         {
930             // kann nicht mehr weiterlesen?
931             if ( rStream.GetError() )
932                 break;
933 
934             // Globale Teile
935             XubString aName, aParent, aFollow;
936             String aHelpFile;
937             sal_uInt16 nFamily, nStyleMask,nCount;
938             sal_uInt32 nHelpId;
939             rStream.ReadByteString(aName, eEnc );
940             rStream.ReadByteString(aParent, eEnc );
941             rStream.ReadByteString(aFollow, eEnc );
942             rStream >> nFamily >> nStyleMask;
943             SfxPoolItem::readByteString(rStream, aHelpFile);
944             rStream >> nHelpId;
945 
946             SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask);
947             rSheet.SetHelpId( aHelpFile, nHelpId );
948             // Hier erst einmal Parent und Follow zwischenspeichern
949             rSheet.aParent = aParent;
950             rSheet.aFollow = aFollow;
951             sal_uInt32 nPos = rStream.Tell();
952             rStream >> nCount;
953             if(nCount)
954             {
955                 rStream.Seek( nPos );
956                 // Das Laden des ItemSets bedient sich der Methode GetItemSet(),
957                 // damit eigene ItemSets untergeschoben werden koennen
958                 SfxItemSet& rSet = rSheet.GetItemSet();
959                 rSet.ClearItem();
960     //!         SfxItemSet aTmpSet( *pTmpPool );
961                 /*!aTmpSet*/ rSet.Load( rStream );
962                 //! rSet.Put( aTmpSet );
963             }
964             // Lokale Teile
965             sal_uInt32 nSize;
966             sal_uInt16 nVer;
967             rStream >> nVer >> nSize;
968             nPos = rStream.Tell() + nSize;
969             rSheet.Load( rStream, nVer );
970             rStream.Seek( nPos );
971         }
972 
973         //  #72939# only loop through the styles that were really inserted
974         sal_uLong n = aStyles.size();
975 
976         //! delete pTmpPool;
977         // Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
978         // Mit Setxxx() noch einmal den String eintragen, da diese
979         // virtuellen Methoden evtl. ueberlagert sind.
980         for ( sal_uLong i = 0; i < n; i++ )
981         {
982             SfxStyleSheetBase* p = aStyles[ i ].get();
983             XubString aText = p->aParent;
984             p->aParent.Erase();
985             p->SetParent( aText );
986             aText = p->aFollow;
987             p->aFollow.Erase();
988             p->SetFollow( aText );
989         }
990 
991         rStream.SetStreamCharSet( eOldEnc );
992     }
993 
994     // alles klar?
995     return sal_Bool( rStream.GetError() == SVSTREAM_OK );
996 }
997 
998 sal_Bool SfxStyleSheetBasePool::Load1_Impl( SvStream& rStream )
999 {
1000     aAppName = rPool.GetName();
1001     sal_uInt16 nVersion;
1002     short nCharSet;
1003     rStream >> nVersion;
1004 
1005     if(nVersion!=STYLESTREAM_VERSION)
1006         nCharSet=nVersion;
1007     else
1008         rStream >> nCharSet;
1009 
1010     rtl_TextEncoding eEnc = GetSOLoadTextEncoding(
1011         (rtl_TextEncoding)nCharSet,
1012         sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) );
1013     rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
1014     rStream.SetStreamCharSet( eEnc );
1015 
1016     sal_uInt16 nStyles;
1017     rStream >> nStyles;
1018     sal_uInt16 i;
1019     for ( i = 0; i < nStyles; i++ )
1020     {
1021         // kann nicht mehr weiterlesen?
1022         if ( rStream.GetError() )
1023         {
1024             nStyles = i;
1025             break;
1026         }
1027 
1028         // Globale Teile
1029         XubString aName, aParent, aFollow;
1030         String aHelpFile;
1031         sal_uInt16 nFamily, nStyleMask,nCount;
1032         sal_uInt32 nHelpId;
1033         rStream.ReadByteString(aName, eEnc );
1034         rStream.ReadByteString(aParent, eEnc );
1035         rStream.ReadByteString(aFollow, eEnc );
1036         rStream >> nFamily >> nStyleMask;
1037         SfxPoolItem::readByteString(rStream, aHelpFile);
1038         if(nVersion!=STYLESTREAM_VERSION)
1039         {
1040             sal_uInt16 nTmpHelpId;
1041             rStream >> nTmpHelpId;
1042             nHelpId=nTmpHelpId;
1043         }
1044         else
1045             rStream >> nHelpId;
1046 
1047         SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask);
1048         rSheet.SetHelpId( aHelpFile, nHelpId );
1049         // Hier erst einmal Parent und Follow zwischenspeichern
1050         rSheet.aParent = aParent;
1051         rSheet.aFollow = aFollow;
1052         sal_uInt32 nPos = rStream.Tell();
1053         rStream >> nCount;
1054         if(nCount) {
1055             rStream.Seek( nPos );
1056             // Das Laden des ItemSets bedient sich der Methode GetItemSet(),
1057             // damit eigene ItemSets untergeschoben werden koennen
1058             SfxItemSet& rSet = rSheet.GetItemSet();
1059             rSet.ClearItem();
1060 //!         SfxItemSet aTmpSet( *pTmpPool );
1061             /*!aTmpSet*/ rSet.Load( rStream );
1062             //! rSet.Put( aTmpSet );
1063         }
1064         // Lokale Teile
1065         sal_uInt32 nSize;
1066         sal_uInt16 nVer;
1067         rStream >> nVer >> nSize;
1068         nPos = rStream.Tell() + nSize;
1069         rSheet.Load( rStream, nVer );
1070         rStream.Seek( nPos );
1071     }
1072 
1073     //! delete pTmpPool;
1074     // Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
1075     // Mit Setxxx() noch einmal den String eintragen, da diese
1076     // virtuellen Methoden evtl. ueberlagert sind.
1077     for ( i = 0; i < nStyles; i++ )
1078     {
1079         SfxStyleSheetBase* p = aStyles[ i ].get();
1080         XubString aText = p->aParent;
1081         p->aParent.Erase();
1082         p->SetParent( aText );
1083         aText = p->aFollow;
1084         p->aFollow.Erase();
1085         p->SetFollow( aText );
1086     }
1087 
1088     rStream.SetStreamCharSet( eOldEnc );
1089 
1090     return sal_Bool( rStream.GetError() == SVSTREAM_OK );
1091 }
1092 
1093 sal_Bool SfxStyleSheetBasePool::Store( SvStream& rStream, sal_Bool bUsed )
1094 {
1095     // den ganzen StyleSheet-Pool in einen Mini-Record
1096     SfxMiniRecordWriter aPoolRec( &rStream, SFX_STYLES_REC );
1097 
1098     // Erst einmal die Dummies rauszaehlen; die werden nicht gespeichert
1099     sal_uInt16 nCount = 0;
1100     for( SfxStyleSheetBase* p = First(); p; p = Next() )
1101     {
1102         if(!bUsed || p->IsUsed())
1103             nCount++;
1104     }
1105 
1106     // einen Header-Record vorweg
1107     rtl_TextEncoding eEnc
1108         = ::GetSOStoreTextEncoding(
1109             rStream.GetStreamCharSet(),
1110             sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) );
1111     rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
1112     rStream.SetStreamCharSet( eEnc );
1113 
1114     {
1115         SfxSingleRecordWriter aHeaderRec( &rStream,
1116                 SFX_STYLES_REC_HEADER,
1117                 STYLESTREAM_VERSION );
1118         rStream << (short) eEnc;
1119     }
1120 
1121     // die StyleSheets in einen MultiVarRecord
1122     {
1123         // Bug 79478:
1124         // make a check loop, to be shure, that the converted names are also
1125         // unique like the originals! In other cases we get a loop.
1126         SvStringsSortDtor aSortOrigNames( 0, 128 );
1127         SvStrings aOrigNames( 0, 128 );
1128         SvByteStringsSortDtor aSortConvNames( 0, 128 );
1129         SvByteStrings aConvNames( 0, 128 );
1130 
1131         {
1132 
1133             for( SfxStyleSheetBase* p = First(); p; p = Next() )
1134             {
1135                 if(!bUsed || p->IsUsed())
1136                 {
1137                     sal_uInt16 nFamily = (sal_uInt16)p->GetFamily();
1138                     String* pName = new String( p->GetName() );
1139                     ByteString* pConvName = new ByteString( *pName, eEnc );
1140 
1141                     pName->Insert( (sal_Unicode)nFamily, 0 );
1142                     pConvName->Insert( "  ", 0 );
1143                     pConvName->SetChar(
1144                         0,
1145                         sal::static_int_cast< char >(0xff & (nFamily >> 8)) );
1146                     pConvName->SetChar(
1147                         1, sal::static_int_cast< char >(0xff & nFamily) );
1148 
1149                     sal_uInt16 nInsPos, nAdd = aSortConvNames.Count();
1150                     while( !aSortConvNames.Insert( pConvName, nInsPos ) )
1151                         (pConvName->Append( '_' )).Append(
1152                                     ByteString::CreateFromInt32( nAdd++ ));
1153                     aOrigNames.Insert( pName, nInsPos );
1154                 }
1155             }
1156 
1157             // now we have the list of the names, sorted by convertede names
1158             // But now we need the sorted list of orignames.
1159             {
1160                 sal_uInt16 nInsPos, nEnd = aOrigNames.Count();
1161                 const ByteStringPtr* ppB = aSortConvNames.GetData();
1162                 for( sal_uInt16 n = 0; n < nEnd; ++n, ++ppB )
1163                 {
1164                     String* p = aOrigNames.GetObject( n );
1165                     aSortOrigNames.Insert( p, nInsPos );
1166                     aConvNames.Insert( *ppB, nInsPos );
1167                 }
1168 
1169             }
1170         }
1171 
1172 
1173         ByteString sEmpty;
1174         sal_uInt16 nFndPos;
1175         String sNm;
1176         SfxMultiVarRecordWriter aStylesRec( &rStream, SFX_STYLES_REC_STYLES, 0 );
1177         for( SfxStyleSheetBase* p = First(); p; p = Next() )
1178         {
1179             if(!bUsed || p->IsUsed())
1180             {
1181                 aStylesRec.NewContent();
1182 
1183                 // Globale Teile speichern
1184                 String aHelpFile;
1185                 sal_uInt32 nHelpId = p->GetHelpId( aHelpFile );
1186                 sal_uInt16 nFamily = sal::static_int_cast< sal_uInt16 >(p->GetFamily());
1187                 String sFamily( (sal_Unicode)nFamily );
1188 
1189                 (sNm = sFamily) += p->GetName();
1190                 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1191                     rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1192                 else
1193                     rStream.WriteByteString( sEmpty );
1194 
1195                 (sNm = sFamily) += p->GetParent();
1196                 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1197                     rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1198                 else
1199                     rStream.WriteByteString( sEmpty );
1200 
1201                 (sNm = sFamily) += p->GetFollow();
1202                 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1203                     rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1204                 else
1205                     rStream.WriteByteString( sEmpty );
1206 
1207                 rStream << nFamily << p->GetMask();
1208                 SfxPoolItem::writeByteString(rStream, aHelpFile);
1209                 rStream << nHelpId;
1210                 if(p->pSet)
1211                     p->pSet->Store( rStream );
1212                 else
1213                     rStream << (sal_uInt16)0;
1214 
1215                 // Lokale Teile speichern
1216                 // Vor dem lokalen Teil wird die Laenge der lokalen Daten
1217                 // als sal_uInt32 sowie die Versionsnummer gespeichert.
1218                 rStream << (sal_uInt16) p->GetVersion();
1219                 sal_uLong nPos1 = rStream.Tell();
1220                 rStream << (sal_uInt32) 0;
1221                 p->Store( rStream );
1222                 sal_uLong nPos2 = rStream.Tell();
1223                 rStream.Seek( nPos1 );
1224                 rStream << (sal_uInt32) ( nPos2 - nPos1 - sizeof( sal_uInt32 ) );
1225                 rStream.Seek( nPos2 );
1226                 if( rStream.GetError() != SVSTREAM_OK )
1227                     break;
1228             }
1229         }
1230     }
1231 
1232     rStream.SetStreamCharSet( eOldEnc );
1233 
1234     return sal_Bool( rStream.GetError() == SVSTREAM_OK );
1235 }
1236 
1237 SfxItemPool& SfxStyleSheetBasePool::GetPool()
1238 {
1239     return rPool;
1240 }
1241 
1242 const SfxItemPool& SfxStyleSheetBasePool::GetPool() const
1243 {
1244     return rPool;
1245 }
1246 
1247 /////////////////////// SfxStyleSheet /////////////////////////////////
1248 
1249 SfxStyleSheet::SfxStyleSheet(const XubString &rName,
1250                              const SfxStyleSheetBasePool& r_Pool,
1251                              SfxStyleFamily eFam,
1252                              sal_uInt16 mask ):
1253     SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool& >( r_Pool ), eFam, mask)
1254 {}
1255 
1256 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle) :
1257     SfxStyleSheetBase(rStyle),
1258     SfxListener( rStyle ),
1259     SfxBroadcaster( rStyle )
1260 {}
1261 
1262 SfxStyleSheet::SfxStyleSheet()
1263 {
1264 }
1265 
1266 SfxStyleSheet::~SfxStyleSheet()
1267 {
1268     Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_INDESTRUCTION, *this ) );
1269 }
1270 
1271 
1272 sal_Bool SfxStyleSheet::SetParent( const XubString& rName )
1273 {
1274     if(aParent == rName)
1275         return sal_True;
1276     const XubString aOldParent(aParent);
1277     if(SfxStyleSheetBase::SetParent(rName)) {
1278             // aus der Benachrichtigungskette des alten
1279             // Parents gfs. austragen
1280         if(aOldParent.Len()) {
1281             SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aOldParent, nFamily, 0xffff);
1282             if(pParent)
1283                 EndListening(*pParent);
1284         }
1285             // in die Benachrichtigungskette des neuen
1286             // Parents eintragen
1287         if(aParent.Len()) {
1288             SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aParent, nFamily, 0xffff);
1289             if(pParent)
1290                 StartListening(*pParent);
1291         }
1292         return sal_True;
1293     }
1294     return sal_False;
1295 }
1296 
1297 // alle Zuhoerer benachtichtigen
1298 
1299 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
1300 {
1301     Forward(rBC, rHint);
1302 }
1303 
1304 //////////////////////// SfxStyleSheetPool ///////////////////////////////
1305 
1306 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
1307 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
1308 {
1309 }
1310 
1311 /////////////////////////////////// Factory ////////////////////////////////
1312 
1313 SfxStyleSheetBase* SfxStyleSheetPool::Create( const XubString& rName,
1314                                     SfxStyleFamily eFam, sal_uInt16 mask )
1315 {
1316     return new SfxStyleSheet( rName, *this, eFam, mask );
1317 }
1318 
1319 SfxStyleSheetBase* SfxStyleSheetPool::Create( const SfxStyleSheet& r )
1320 {
1321     return new SfxStyleSheet( r );
1322 }
1323 /*
1324 sal_Bool SfxStyleSheetPool::CopyTo(SfxStyleSheetPool &, const String &)
1325 {
1326     return sal_False;
1327 }
1328 */
1329 
1330 // --------------------------------------------------------------------
1331 // class SfxUnoStyleSheet
1332 // --------------------------------------------------------------------
1333 
1334 SfxUnoStyleSheet::SfxUnoStyleSheet( const UniString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, sal_uInt16 _nMaske )
1335 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske )
1336 {
1337 }
1338 
1339 // --------------------------------------------------------------------
1340 SfxUnoStyleSheet::SfxUnoStyleSheet( const SfxStyleSheet& _rSheet )
1341 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rSheet )
1342 {
1343 }
1344 
1345 // --------------------------------------------------------------------
1346 
1347 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle )
1348 {
1349     SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() );
1350     if( !pRet )
1351     {
1352         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY );
1353         if( xUT.is() )
1354             pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier())));
1355     }
1356     return pRet;
1357 }
1358 
1359 // --------------------------------------------------------------------
1360 // XUnoTunnel
1361 // --------------------------------------------------------------------
1362 
1363 ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException)
1364 {
1365     if( rId.getLength() == 16 && 0 == rtl_compareMemory( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) )
1366     {
1367         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
1368     }
1369     else
1370     {
1371         return 0;
1372     }
1373 }
1374 
1375 // --------------------------------------------------------------------
1376 
1377 const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier()
1378 {
1379     static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0;
1380     if( !pSeq )
1381     {
1382         ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
1383         if( !pSeq )
1384         {
1385             static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
1386             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
1387             pSeq = &aSeq;
1388         }
1389     }
1390     return *pSeq;
1391 }
1392 
1393 // --------------------------------------------------------------------
1394