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