xref: /AOO41X/main/svl/source/items/style.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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