Update ooo320-m1
[ooovba.git] / svtools / source / items / style.cxx
blob31bcfcc12046b782cfec9c169cb9bbdb8e4529e9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: style.cxx,v $
10 * $Revision: 1.19.60.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #ifndef GCC
35 #endif
37 #define _SVSTDARR_STRINGS
38 #define _SVSTDARR_STRINGSSORTDTOR
39 #define _SVSTDARR_BYTESTRINGS
40 #define _SVSTDARR_BYTESTRINGSSORTDTOR
42 #include <rtl/uuid.h>
43 #include <tools/tenccvt.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <unotools/intlwrapper.hxx>
46 #include <svtools/smplhint.hxx>
47 #include <svtools/poolitem.hxx>
48 #include <svtools/itemset.hxx>
49 #include <svtools/itempool.hxx>
50 #include <poolio.hxx>
51 #include <svtools/filerec.hxx>
52 #include <svtools/itemiter.hxx>
53 #include <svtools/style.hxx>
54 #include <svtools/svstdarr.hxx>
55 #include <vcl/svapp.hxx>
57 #include <algorithm>
59 #define STYLESTREAM "SfxStyleSheets"
60 #define STYLESTREAM_VERSION USHORT(50)
62 #ifdef DBG_UTIL
63 class DbgStyleSheetReferences
65 public:
66 DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {}
67 ~DbgStyleSheetReferences()
69 OSL_TRACE("DbgStyleSheetReferences\nSfxStyleSheetBase left %ld\nSfxStyleSheetBasePool left %ld\n", mnStyles, mnPools );
72 sal_uInt32 mnStyles;
73 sal_uInt32 mnPools;
75 aDbgStyleSheetReferences;
77 #endif
79 TYPEINIT0(SfxStyleSheetBase)
81 TYPEINIT3(SfxStyleSheet, SfxStyleSheetBase, SfxListener, SfxBroadcaster)
84 //=========================================================================
86 TYPEINIT1(SfxStyleSheetHint, SfxHint);
87 TYPEINIT1(SfxStyleSheetHintExtended, SfxStyleSheetHint);
88 TYPEINIT1(SfxStyleSheetPoolHint, SfxHint);
90 SfxStyleSheetHintExtended::SfxStyleSheetHintExtended
92 USHORT nAction, // SFX_STYLESHEET_... (s.o.)
93 const String& rOldName
95 : SfxStyleSheetHint( nAction ),
96 aName( rOldName )
98 SfxStyleSheetHintExtended::SfxStyleSheetHintExtended
100 USHORT nAction, // SFX_STYLESHEET_... (s.o.)
101 const String& rOldName,
102 SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer
104 : SfxStyleSheetHint( nAction, rStyleSheet ),
105 aName( rOldName )
108 //-------------------------------------------------------------------------
110 SfxStyleSheetHint::SfxStyleSheetHint
112 USHORT nAction, // SFX_STYLESHEET_... (s.o.)
113 SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer
115 : pStyleSh( &rStyleSheet ),
116 nHint( nAction )
119 SfxStyleSheetHint::SfxStyleSheetHint
121 USHORT nAction // SFX_STYLESHEET_... (s.o.)
123 : pStyleSh( NULL ),
124 nHint( nAction )
127 //=========================================================================
129 class SfxStyleSheetBasePool_Impl
131 public:
132 SfxStyles aStyles;
133 SfxStyleSheetIterator *pIter;
134 SfxStyleSheetBasePool_Impl() : pIter(0){}
135 ~SfxStyleSheetBasePool_Impl(){delete pIter;}
139 //////////////////////////// SfxStyleSheetBase ///////////////////////////////
141 // Konstruktoren
143 SfxStyleSheetBase::SfxStyleSheetBase( const XubString& rName, SfxStyleSheetBasePool& r, SfxStyleFamily eFam, USHORT mask )
144 : rPool( r )
145 , nFamily( eFam )
146 , aName( rName )
147 , aParent()
148 , aFollow( rName )
149 , pSet( NULL )
150 , nMask(mask)
151 , nHelpId( 0 )
152 , bMySet( FALSE )
154 #ifdef DBG_UTIL
155 aDbgStyleSheetReferences.mnStyles++;
156 #endif
159 SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r )
160 : comphelper::OWeakTypeObject()
161 , rPool( r.rPool )
162 , nFamily( r.nFamily )
163 , aName( r.aName )
164 , aParent( r.aParent )
165 , aFollow( r.aFollow )
166 , aHelpFile( r.aHelpFile )
167 , nMask( r.nMask )
168 , nHelpId( r.nHelpId )
169 , bMySet( r.bMySet )
171 #ifdef DBG_UTIL
172 aDbgStyleSheetReferences.mnStyles++;
173 #endif
174 if( r.pSet )
175 pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet;
176 else
177 pSet = NULL;
180 static SfxStyleSheetBasePool& implGetStaticPool()
182 static SfxStyleSheetBasePool* pSheetPool = 0;
183 static SfxItemPool* pBasePool = 0;
184 if( !pSheetPool )
186 UniString aName;
187 pBasePool = new SfxItemPool( aName, 0, 0, 0 );
188 pSheetPool = new SfxStyleSheetBasePool(*pBasePool);
190 return *pSheetPool;
193 SfxStyleSheetBase::SfxStyleSheetBase()
194 : comphelper::OWeakTypeObject()
195 , rPool( implGetStaticPool() )
199 SfxStyleSheetBase::~SfxStyleSheetBase()
201 #ifdef DBG_UTIL
202 --aDbgStyleSheetReferences.mnStyles;
203 #endif
205 if( bMySet )
207 delete pSet;
208 pSet = 0;
212 USHORT SfxStyleSheetBase::GetVersion() const
214 return 0x0000;
217 // Namen aendern
219 const XubString& SfxStyleSheetBase::GetName() const
221 return aName;
224 BOOL SfxStyleSheetBase::SetName( const XubString& rName )
226 if(rName.Len() == 0)
227 return FALSE;
228 if( aName != rName )
230 String aOldName = aName;
231 SfxStyleSheetBase *pOther = rPool.Find( rName, nFamily ) ;
232 if ( pOther && pOther != this )
233 return FALSE;
235 SfxStyleFamily eTmpFam=rPool.GetSearchFamily();
236 USHORT nTmpMask=rPool.GetSearchMask();
238 rPool.SetSearchMask(nFamily);
240 if ( aName.Len() )
241 rPool.ChangeParent( aName, rName, FALSE );
242 if ( aFollow.Equals( aName ) )
243 aFollow = rName;
244 aName = rName;
245 rPool.SetSearchMask(eTmpFam, nTmpMask);
246 rPool.Broadcast( SfxStyleSheetHintExtended(
247 SFX_STYLESHEET_MODIFIED, aOldName, *this ) );
249 return TRUE;
252 rtl::OUString SfxStyleSheetBase::GetDisplayName() const
254 if( maDisplayName.getLength() == 0 )
256 return aName;
258 else
260 return maDisplayName;
264 void SfxStyleSheetBase::SetDisplayName( const rtl::OUString& rDisplayName )
266 maDisplayName = rDisplayName;
269 // Parent aendern
271 const XubString& SfxStyleSheetBase::GetParent() const
273 return aParent;
276 BOOL SfxStyleSheetBase::SetParent( const XubString& rName )
278 if ( rName == aName )
279 return FALSE;
281 if( aParent != rName )
283 SfxStyleSheetBase* pIter = rPool.Find(rName, nFamily);
284 if( rName.Len() && !pIter )
286 DBG_ERROR( "StyleSheet-Parent nicht gefunden" );
287 return FALSE;
289 // rekursive Verknuepfungen verhindern
290 if( aName.Len() )
291 while(pIter)
293 if(pIter->GetName() == aName && aName != rName)
294 return FALSE;
295 pIter = rPool.Find(pIter->GetParent(), nFamily);
297 aParent = rName;
299 rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) );
300 return TRUE;
303 // Follow aendern
305 const XubString& SfxStyleSheetBase::GetFollow() const
307 return aFollow;
310 BOOL SfxStyleSheetBase::SetFollow( const XubString& rName )
312 if( aFollow != rName )
314 if( !rPool.Find( rName, nFamily ) )
316 DBG_ERROR( "StyleSheet-Follow nicht gefunden" );
317 return FALSE;
319 aFollow = rName;
321 rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) );
322 return TRUE;
325 // Itemset setzen. Die Dflt-Implementation legt ein neues Set an.
327 SfxItemSet& SfxStyleSheetBase::GetItemSet()
329 if( !pSet )
331 pSet = new SfxItemSet( rPool.GetPool() );
332 bMySet = TRUE;
334 return *pSet;
337 // Hilfe-Datei und -ID setzen und abfragen
339 ULONG SfxStyleSheetBase::GetHelpId( String& rFile )
341 rFile = aHelpFile;
342 return nHelpId;
345 void SfxStyleSheetBase::SetHelpId( const String& rFile, ULONG nId )
347 aHelpFile = rFile;
348 nHelpId = nId;
351 // Folgevorlage m"oglich? Default: Ja
353 BOOL SfxStyleSheetBase::HasFollowSupport() const
355 return TRUE;
358 // Basisvorlage m"oglich? Default: Ja
360 BOOL SfxStyleSheetBase::HasParentSupport() const
362 return TRUE;
365 // Basisvorlage uf NULL setzen m"oglich? Default: Nein
367 BOOL SfxStyleSheetBase::HasClearParentSupport() const
369 return FALSE;
372 // Defaultmaessig sind alle StyleSheets Used
374 BOOL SfxStyleSheetBase::IsUsed() const
376 return TRUE;
379 // eingestellte Attribute ausgeben
382 XubString SfxStyleSheetBase::GetDescription()
384 return GetDescription( SFX_MAPUNIT_CM );
387 // eingestellte Attribute ausgeben
389 XubString SfxStyleSheetBase::GetDescription( SfxMapUnit eMetric )
391 SfxItemIter aIter( GetItemSet() );
392 XubString aDesc;
393 const SfxPoolItem* pItem = aIter.FirstItem();
395 IntlWrapper aIntlWrapper(comphelper::getProcessServiceFactory(),
396 Application::GetSettings().GetLanguage());
397 while ( pItem )
399 XubString aItemPresentation;
401 if ( !IsInvalidItem( pItem ) &&
402 rPool.GetPool().GetPresentation(
403 *pItem, SFX_ITEM_PRESENTATION_COMPLETE,
404 eMetric, aItemPresentation, &aIntlWrapper ) )
406 if ( aDesc.Len() && aItemPresentation.Len() )
407 aDesc.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" + "));
408 if ( aItemPresentation.Len() )
409 aDesc += aItemPresentation;
411 pItem = aIter.NextItem();
413 return aDesc;
416 /////////////////////////// SfxStyleSheetIterator ///////////////////////////////
418 SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
420 return nSearchFamily;
423 inline BOOL SfxStyleSheetIterator::IsTrivialSearch()
425 return nMask == 0xFFFF && GetSearchFamily() == SFX_STYLE_FAMILY_ALL;
428 BOOL SfxStyleSheetIterator::DoesStyleMatch(SfxStyleSheetBase *pStyle)
430 return ((GetSearchFamily() == SFX_STYLE_FAMILY_ALL) ||
431 ( pStyle->GetFamily() == GetSearchFamily() ))
432 && (( pStyle->GetMask() & ( GetSearchMask() & ~SFXSTYLEBIT_USED )) ||
433 ( bSearchUsed ? pStyle->IsUsed() : FALSE ) ||
434 GetSearchMask() == SFXSTYLEBIT_ALL );
438 SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
439 SfxStyleFamily eFam, USHORT n)
441 pBasePool=pBase;
442 nSearchFamily=eFam;
443 bSearchUsed=FALSE;
444 if((n != SFXSTYLEBIT_ALL ) && ((n & SFXSTYLEBIT_USED) == SFXSTYLEBIT_USED))
446 bSearchUsed = TRUE;
447 n &= ~SFXSTYLEBIT_USED;
449 nMask=n;
452 SfxStyleSheetIterator::~SfxStyleSheetIterator()
457 USHORT SfxStyleSheetIterator::Count()
459 USHORT n = 0;
460 if( IsTrivialSearch())
461 n = (USHORT) pBasePool->aStyles.size();
462 else
463 for(USHORT i=0; i<pBasePool->aStyles.size(); i++)
465 SfxStyleSheetBase* pStyle = pBasePool->aStyles[i].get();
466 if(DoesStyleMatch(pStyle))
467 n++;
469 return n;
472 SfxStyleSheetBase* SfxStyleSheetIterator::operator[](USHORT nIdx)
474 if( IsTrivialSearch())
475 return pBasePool->aStyles[nIdx].get();
477 USHORT z = 0;
478 for(USHORT n=0; n<pBasePool->aStyles.size(); n++)
480 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
481 if( DoesStyleMatch(pStyle))
483 if(z == nIdx)
485 nAktPosition=n;
486 return pAktStyle=pStyle;
488 ++z;
491 DBG_ERROR("falscher Index");
492 return 0;
495 SfxStyleSheetBase* SfxStyleSheetIterator::First()
497 INT32 nIdx = -1;
499 if ( IsTrivialSearch() && pBasePool->aStyles.size() )
500 nIdx = 0;
501 else
502 for( USHORT n = 0; n < pBasePool->aStyles.size(); n++ )
504 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
506 if ( DoesStyleMatch( pStyle ) )
508 nIdx = n;
509 break;
513 if ( nIdx != -1 )
515 nAktPosition = (USHORT)nIdx;
516 return pAktStyle = pBasePool->aStyles[nIdx].get();
518 return 0;
522 SfxStyleSheetBase* SfxStyleSheetIterator::Next()
524 INT32 nIdx = -1;
526 if ( IsTrivialSearch() &&
527 (USHORT)pBasePool->aStyles.size() > nAktPosition + 1 )
528 nIdx = nAktPosition + 1;
529 else
530 for( USHORT n = nAktPosition + 1; n < pBasePool->aStyles.size(); n++ )
532 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
534 if ( DoesStyleMatch( pStyle ) )
536 nIdx = n;
537 break;
541 if ( nIdx != -1 )
543 nAktPosition = (USHORT)nIdx;
544 return pAktStyle = pBasePool->aStyles[nIdx].get();
546 return 0;
550 SfxStyleSheetBase* SfxStyleSheetIterator::Find(const XubString& rStr)
552 for ( USHORT n = 0; n < pBasePool->aStyles.size(); n++ )
554 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
556 // #98454# performance: in case of bSearchUsed==TRUE it may be
557 // significant to first compare the name and only if it matches to call
558 // the style sheet IsUsed() method in DoesStyleMatch().
559 if ( pStyle->GetName().Equals( rStr ) && DoesStyleMatch( pStyle ) )
561 nAktPosition = n;
562 return pAktStyle = pStyle;
565 return 0;
569 USHORT SfxStyleSheetIterator::GetSearchMask() const
571 USHORT mask = nMask;
573 if ( bSearchUsed )
574 mask |= SFXSTYLEBIT_USED;
575 return mask;
578 /////////////////////////// SfxStyleSheetBasePool ///////////////////////////////
580 void SfxStyleSheetBasePool::Replace(
581 SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget )
583 rTarget.SetFollow( rSource.GetFollow() );
584 rTarget.SetParent( rSource.GetParent() );
585 SfxItemSet& rSourceSet = rSource.GetItemSet();
586 SfxItemSet& rTargetSet = rTarget.GetItemSet();
587 rTargetSet.Intersect( rSourceSet );
588 rTargetSet.Put( rSourceSet );
591 SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl()
593 SfxStyleSheetIterator*& rpIter = pImp->pIter;
594 if( !rpIter || (rpIter->GetSearchMask() != nMask) || (rpIter->GetSearchFamily() != nSearchFamily) )
596 delete rpIter;
597 rpIter = CreateIterator( nSearchFamily, nMask );
599 return *rpIter;
603 SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r )
604 : aAppName(r.GetName())
605 , rPool(r)
606 , nSearchFamily(SFX_STYLE_FAMILY_PARA)
607 , nMask(0xFFFF)
609 #ifdef DBG_UTIL
610 aDbgStyleSheetReferences.mnPools++;
611 #endif
613 pImp = new SfxStyleSheetBasePool_Impl;
616 SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r )
617 : SfxBroadcaster( r )
618 , comphelper::OWeakTypeObject()
619 , aAppName(r.aAppName)
620 , rPool(r.rPool)
621 , nSearchFamily(r.nSearchFamily)
622 , nMask( r.nMask )
624 #ifdef DBG_UTIL
625 aDbgStyleSheetReferences.mnPools++;
626 #endif
628 pImp = new SfxStyleSheetBasePool_Impl;
629 *this += r;
632 SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
634 #ifdef DBG_UTIL
635 aDbgStyleSheetReferences.mnPools--;
636 #endif
638 Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
639 Clear();
640 delete pImp;
643 BOOL SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const XubString& rStyle, const XubString& rParent)
645 SfxStyleSheetIterator aIter(this,eFam,SFXSTYLEBIT_ALL);
646 SfxStyleSheetBase *pStyle =
647 aIter.Find(rStyle);
648 DBG_ASSERT(pStyle, "Vorlage nicht gefunden. Writer mit Solar <2541??");
649 if(pStyle)
650 return pStyle->SetParent(rParent);
651 else
652 return FALSE;
656 void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, USHORT n)
658 nSearchFamily = eFam; nMask = n;
661 USHORT SfxStyleSheetBasePool::GetSearchMask() const
663 return nMask;
667 // Der Name des Streams
669 String SfxStyleSheetBasePool::GetStreamName()
671 return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STYLESTREAM));
674 /////////////////////////////////// Factory ////////////////////////////////
678 SfxStyleSheetIterator* SfxStyleSheetBasePool::CreateIterator
680 SfxStyleFamily eFam,
681 USHORT mask
684 return new SfxStyleSheetIterator(this,eFam,mask);
688 SfxStyleSheetBase* SfxStyleSheetBasePool::Create
690 const XubString& rName,
691 SfxStyleFamily eFam,
692 USHORT mask
695 return new SfxStyleSheetBase( rName, *this, eFam, mask );
698 SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
700 return new SfxStyleSheetBase( r );
703 SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const XubString& rName, SfxStyleFamily eFam, USHORT mask, USHORT nPos)
705 DBG_ASSERT( eFam != SFX_STYLE_FAMILY_ALL, "svtools::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" );
707 SfxStyleSheetIterator aIter(this, eFam, mask);
708 rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) );
709 DBG_ASSERT( !xStyle.is(), "svtools::SfxStyleSheetBasePool::Make(), StyleSheet already exists" );
710 SfxStyleSheetIterator& rIter = GetIterator_Impl();
712 if( !xStyle.is() )
714 xStyle = Create( rName, eFam, mask );
715 if(0xffff == nPos || nPos == aStyles.size() || nPos == rIter.Count())
717 aStyles.push_back( xStyle );
719 else
721 rIter[nPos];
722 aStyles.insert( aStyles.begin() + rIter.GetPos(), xStyle );
724 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *xStyle.get() ) );
726 return *xStyle.get();
729 /////////////////////////////// Kopieren ///////////////////////////////////
731 // Hilfsroutine: Falls eine Vorlage dieses Namens existiert, wird
732 // sie neu erzeugt. Alle Vorlagen, die diese Vorlage zum Parent haben,
733 // werden umgehaengt.
735 SfxStyleSheetBase& SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet )
737 SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask);
738 SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
739 Remove( pOld );
740 rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
741 aStyles.push_back( xNew );
742 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *xNew.get() ) );
743 return *xNew.get();
746 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
748 if( &r != this )
750 Clear();
751 *this += r;
753 return *this;
756 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
758 if( &r != this )
760 SfxStyles::const_iterator aIter( r.aStyles.begin() );
761 while( aIter != r.aStyles.end() )
763 Add(*(*aIter++).get());
766 return *this;
769 //////////////////////////////// Suchen ////////////////////////////////////
771 USHORT SfxStyleSheetBasePool::Count()
773 return GetIterator_Impl().Count();
776 SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](USHORT nIdx)
778 return GetIterator_Impl()[nIdx];
781 SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const XubString& rName,
782 SfxStyleFamily eFam,
783 USHORT mask)
785 SfxStyleSheetIterator aIter(this,eFam,mask);
786 return aIter.Find(rName);
789 const SfxStyles& SfxStyleSheetBasePool::GetStyles()
791 return aStyles;
794 SfxStyleSheetBase* SfxStyleSheetBasePool::First()
796 return GetIterator_Impl().First();
799 SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
801 return GetIterator_Impl().Next();
804 //////////////////////////////// Loeschen /////////////////////////////////
806 void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
808 if( p )
810 SfxStyles::iterator aIter( std::find( aStyles.begin(), aStyles.end(), rtl::Reference< SfxStyleSheetBase >( p ) ) );
811 if( aIter != aStyles.end() )
813 // Alle Styles umsetzen, deren Parent dieser hier ist
814 ChangeParent( p->GetName(), p->GetParent() );
815 aStyles.erase(aIter);
816 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) );
821 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
823 DBG_ASSERT( p, "svtools::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
825 SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
826 SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
827 DBG_ASSERT( !pOld, "svtools::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
828 if( p->GetParent().Len() )
830 pOld = aIter.Find( p->GetParent() );
831 DBG_ASSERT( pOld, "svtools::SfxStyleSheetBasePool::Insert(), Parent not found!" );
833 aStyles.push_back( rtl::Reference< SfxStyleSheetBase >( p ) );
834 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) );
837 void SfxStyleSheetBasePool::Clear()
839 SfxStyles aClearStyles;
840 aClearStyles.swap( aStyles );
842 SfxStyles::iterator aIter( aClearStyles.begin() );
843 while( aIter != aClearStyles.end() )
845 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) );
849 /////////////////////////// Parents umsetzen ////////////////////////////////
851 void SfxStyleSheetBasePool::ChangeParent(const XubString& rOld,
852 const XubString& rNew,
853 BOOL bVirtual)
855 const USHORT nTmpMask = GetSearchMask();
856 SetSearchMask(GetSearchFamily(), 0xffff);
857 for( SfxStyleSheetBase* p = First(); p; p = Next() )
859 if( p->GetParent().Equals( rOld ) )
861 if(bVirtual)
862 p->SetParent( rNew );
863 else
864 p->aParent = rNew;
867 SetSearchMask(GetSearchFamily(), nTmpMask);
870 /////////////////////////// Laden/Speichern /////////////////////////////////
872 void SfxStyleSheetBase::Load( SvStream&, USHORT )
876 void SfxStyleSheetBase::Store( SvStream& )
881 BOOL SfxStyleSheetBasePool::Load( SvStream& rStream )
883 // alte Version?
884 if ( !rPool.IsVer2_Impl() )
885 return Load1_Impl( rStream );
887 // gesamten StyleSheetPool in neuer Version aus einem MiniRecord lesen
888 SfxMiniRecordReader aPoolRec( &rStream, SFX_STYLES_REC );
890 // Header-Record lesen
891 short nCharSet = 0;
892 if ( !rStream.GetError() )
894 SfxSingleRecordReader aHeaderRec( &rStream, SFX_STYLES_REC_HEADER );
895 if ( !aHeaderRec.IsValid() )
896 return FALSE;
898 aAppName = rPool.GetName();
899 rStream >> nCharSet;
902 // Styles-Record lesen
903 if ( !rStream.GetError() )
905 SfxMultiRecordReader aStylesRec( &rStream, SFX_STYLES_REC_STYLES );
906 if ( !aStylesRec.IsValid() )
907 return FALSE;
909 rtl_TextEncoding eEnc = GetSOLoadTextEncoding(
910 (rtl_TextEncoding)nCharSet,
911 sal::static_int_cast< USHORT >(rStream.GetVersion()) );
912 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
913 rStream.SetStreamCharSet( eEnc );
915 USHORT nStyles;
916 for ( nStyles = 0; aStylesRec.GetContent(); nStyles++ )
918 // kann nicht mehr weiterlesen?
919 if ( rStream.GetError() )
920 break;
922 // Globale Teile
923 XubString aName, aParent, aFollow;
924 String aHelpFile;
925 USHORT nFamily, nStyleMask,nCount;
926 sal_uInt32 nHelpId;
927 rStream.ReadByteString(aName, eEnc );
928 rStream.ReadByteString(aParent, eEnc );
929 rStream.ReadByteString(aFollow, eEnc );
930 rStream >> nFamily >> nStyleMask;
931 SfxPoolItem::readByteString(rStream, aHelpFile);
932 rStream >> nHelpId;
934 SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask);
935 rSheet.SetHelpId( aHelpFile, nHelpId );
936 // Hier erst einmal Parent und Follow zwischenspeichern
937 rSheet.aParent = aParent;
938 rSheet.aFollow = aFollow;
939 UINT32 nPos = rStream.Tell();
940 rStream >> nCount;
941 if(nCount)
943 rStream.Seek( nPos );
944 // Das Laden des ItemSets bedient sich der Methode GetItemSet(),
945 // damit eigene ItemSets untergeschoben werden koennen
946 SfxItemSet& rSet = rSheet.GetItemSet();
947 rSet.ClearItem();
948 //! SfxItemSet aTmpSet( *pTmpPool );
949 /*!aTmpSet*/ rSet.Load( rStream );
950 //! rSet.Put( aTmpSet );
952 // Lokale Teile
953 UINT32 nSize;
954 USHORT nVer;
955 rStream >> nVer >> nSize;
956 nPos = rStream.Tell() + nSize;
957 rSheet.Load( rStream, nVer );
958 rStream.Seek( nPos );
961 // #72939# only loop through the styles that were really inserted
962 ULONG n = aStyles.size();
964 //! delete pTmpPool;
965 // Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
966 // Mit Setxxx() noch einmal den String eintragen, da diese
967 // virtuellen Methoden evtl. ueberlagert sind.
968 for ( ULONG i = 0; i < n; i++ )
970 SfxStyleSheetBase* p = aStyles[ i ].get();
971 XubString aText = p->aParent;
972 p->aParent.Erase();
973 p->SetParent( aText );
974 aText = p->aFollow;
975 p->aFollow.Erase();
976 p->SetFollow( aText );
979 rStream.SetStreamCharSet( eOldEnc );
982 // alles klar?
983 return BOOL( rStream.GetError() == SVSTREAM_OK );
986 BOOL SfxStyleSheetBasePool::Load1_Impl( SvStream& rStream )
988 aAppName = rPool.GetName();
989 USHORT nVersion;
990 short nCharSet;
991 rStream >> nVersion;
993 if(nVersion!=STYLESTREAM_VERSION)
994 nCharSet=nVersion;
995 else
996 rStream >> nCharSet;
998 rtl_TextEncoding eEnc = GetSOLoadTextEncoding(
999 (rtl_TextEncoding)nCharSet,
1000 sal::static_int_cast< USHORT >(rStream.GetVersion()) );
1001 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
1002 rStream.SetStreamCharSet( eEnc );
1004 USHORT nStyles;
1005 rStream >> nStyles;
1006 USHORT i;
1007 for ( i = 0; i < nStyles; i++ )
1009 // kann nicht mehr weiterlesen?
1010 if ( rStream.GetError() )
1012 nStyles = i;
1013 break;
1016 // Globale Teile
1017 XubString aName, aParent, aFollow;
1018 String aHelpFile;
1019 USHORT nFamily, nStyleMask,nCount;
1020 sal_uInt32 nHelpId;
1021 rStream.ReadByteString(aName, eEnc );
1022 rStream.ReadByteString(aParent, eEnc );
1023 rStream.ReadByteString(aFollow, eEnc );
1024 rStream >> nFamily >> nStyleMask;
1025 SfxPoolItem::readByteString(rStream, aHelpFile);
1026 if(nVersion!=STYLESTREAM_VERSION)
1028 USHORT nTmpHelpId;
1029 rStream >> nTmpHelpId;
1030 nHelpId=nTmpHelpId;
1032 else
1033 rStream >> nHelpId;
1035 SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask);
1036 rSheet.SetHelpId( aHelpFile, nHelpId );
1037 // Hier erst einmal Parent und Follow zwischenspeichern
1038 rSheet.aParent = aParent;
1039 rSheet.aFollow = aFollow;
1040 UINT32 nPos = rStream.Tell();
1041 rStream >> nCount;
1042 if(nCount) {
1043 rStream.Seek( nPos );
1044 // Das Laden des ItemSets bedient sich der Methode GetItemSet(),
1045 // damit eigene ItemSets untergeschoben werden koennen
1046 SfxItemSet& rSet = rSheet.GetItemSet();
1047 rSet.ClearItem();
1048 //! SfxItemSet aTmpSet( *pTmpPool );
1049 /*!aTmpSet*/ rSet.Load( rStream );
1050 //! rSet.Put( aTmpSet );
1052 // Lokale Teile
1053 UINT32 nSize;
1054 USHORT nVer;
1055 rStream >> nVer >> nSize;
1056 nPos = rStream.Tell() + nSize;
1057 rSheet.Load( rStream, nVer );
1058 rStream.Seek( nPos );
1061 //! delete pTmpPool;
1062 // Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
1063 // Mit Setxxx() noch einmal den String eintragen, da diese
1064 // virtuellen Methoden evtl. ueberlagert sind.
1065 for ( i = 0; i < nStyles; i++ )
1067 SfxStyleSheetBase* p = aStyles[ i ].get();
1068 XubString aText = p->aParent;
1069 p->aParent.Erase();
1070 p->SetParent( aText );
1071 aText = p->aFollow;
1072 p->aFollow.Erase();
1073 p->SetFollow( aText );
1076 rStream.SetStreamCharSet( eOldEnc );
1078 return BOOL( rStream.GetError() == SVSTREAM_OK );
1081 BOOL SfxStyleSheetBasePool::Store( SvStream& rStream, BOOL bUsed )
1083 // den ganzen StyleSheet-Pool in einen Mini-Record
1084 SfxMiniRecordWriter aPoolRec( &rStream, SFX_STYLES_REC );
1086 // Erst einmal die Dummies rauszaehlen; die werden nicht gespeichert
1087 USHORT nCount = 0;
1088 for( SfxStyleSheetBase* p = First(); p; p = Next() )
1090 if(!bUsed || p->IsUsed())
1091 nCount++;
1094 // einen Header-Record vorweg
1095 rtl_TextEncoding eEnc
1096 = ::GetSOStoreTextEncoding(
1097 rStream.GetStreamCharSet(),
1098 sal::static_int_cast< USHORT >(rStream.GetVersion()) );
1099 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet();
1100 rStream.SetStreamCharSet( eEnc );
1103 SfxSingleRecordWriter aHeaderRec( &rStream,
1104 SFX_STYLES_REC_HEADER,
1105 STYLESTREAM_VERSION );
1106 rStream << (short) eEnc;
1109 // die StyleSheets in einen MultiVarRecord
1111 // Bug 79478:
1112 // make a check loop, to be shure, that the converted names are also
1113 // unique like the originals! In other cases we get a loop.
1114 SvStringsSortDtor aSortOrigNames( 0, 128 );
1115 SvStrings aOrigNames( 0, 128 );
1116 SvByteStringsSortDtor aSortConvNames( 0, 128 );
1117 SvByteStrings aConvNames( 0, 128 );
1121 for( SfxStyleSheetBase* p = First(); p; p = Next() )
1123 if(!bUsed || p->IsUsed())
1125 USHORT nFamily = (USHORT)p->GetFamily();
1126 String* pName = new String( p->GetName() );
1127 ByteString* pConvName = new ByteString( *pName, eEnc );
1129 pName->Insert( (sal_Unicode)nFamily, 0 );
1130 pConvName->Insert( " ", 0 );
1131 pConvName->SetChar(
1133 sal::static_int_cast< char >(0xff & (nFamily >> 8)) );
1134 pConvName->SetChar(
1135 1, sal::static_int_cast< char >(0xff & nFamily) );
1137 USHORT nInsPos, nAdd = aSortConvNames.Count();
1138 while( !aSortConvNames.Insert( pConvName, nInsPos ) )
1139 (pConvName->Append( '_' )).Append(
1140 ByteString::CreateFromInt32( nAdd++ ));
1141 aOrigNames.Insert( pName, nInsPos );
1145 // now we have the list of the names, sorted by convertede names
1146 // But now we need the sorted list of orignames.
1148 USHORT nInsPos, nEnd = aOrigNames.Count();
1149 const ByteStringPtr* ppB = aSortConvNames.GetData();
1150 for( USHORT n = 0; n < nEnd; ++n, ++ppB )
1152 String* p = aOrigNames.GetObject( n );
1153 aSortOrigNames.Insert( p, nInsPos );
1154 aConvNames.Insert( *ppB, nInsPos );
1161 ByteString sEmpty;
1162 USHORT nFndPos;
1163 String sNm;
1164 SfxMultiVarRecordWriter aStylesRec( &rStream, SFX_STYLES_REC_STYLES, 0 );
1165 for( SfxStyleSheetBase* p = First(); p; p = Next() )
1167 if(!bUsed || p->IsUsed())
1169 aStylesRec.NewContent();
1171 // Globale Teile speichern
1172 String aHelpFile;
1173 sal_uInt32 nHelpId = p->GetHelpId( aHelpFile );
1174 USHORT nFamily = sal::static_int_cast< USHORT >(p->GetFamily());
1175 String sFamily( (sal_Unicode)nFamily );
1177 (sNm = sFamily) += p->GetName();
1178 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1179 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1180 else
1181 rStream.WriteByteString( sEmpty );
1183 (sNm = sFamily) += p->GetParent();
1184 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1185 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1186 else
1187 rStream.WriteByteString( sEmpty );
1189 (sNm = sFamily) += p->GetFollow();
1190 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos ))
1191 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 ));
1192 else
1193 rStream.WriteByteString( sEmpty );
1195 rStream << nFamily << p->GetMask();
1196 SfxPoolItem::writeByteString(rStream, aHelpFile);
1197 rStream << nHelpId;
1198 if(p->pSet)
1199 p->pSet->Store( rStream );
1200 else
1201 rStream << (USHORT)0;
1203 // Lokale Teile speichern
1204 // Vor dem lokalen Teil wird die Laenge der lokalen Daten
1205 // als UINT32 sowie die Versionsnummer gespeichert.
1206 rStream << (USHORT) p->GetVersion();
1207 ULONG nPos1 = rStream.Tell();
1208 rStream << (UINT32) 0;
1209 p->Store( rStream );
1210 ULONG nPos2 = rStream.Tell();
1211 rStream.Seek( nPos1 );
1212 rStream << (UINT32) ( nPos2 - nPos1 - sizeof( UINT32 ) );
1213 rStream.Seek( nPos2 );
1214 if( rStream.GetError() != SVSTREAM_OK )
1215 break;
1220 rStream.SetStreamCharSet( eOldEnc );
1222 return BOOL( rStream.GetError() == SVSTREAM_OK );
1225 SfxItemPool& SfxStyleSheetBasePool::GetPool()
1227 return rPool;
1230 const SfxItemPool& SfxStyleSheetBasePool::GetPool() const
1232 return rPool;
1235 /////////////////////// SfxStyleSheet /////////////////////////////////
1237 SfxStyleSheet::SfxStyleSheet(const XubString &rName,
1238 const SfxStyleSheetBasePool& r_Pool,
1239 SfxStyleFamily eFam,
1240 USHORT mask ):
1241 SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool& >( r_Pool ), eFam, mask)
1244 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle) :
1245 SfxStyleSheetBase(rStyle),
1246 SfxListener( rStyle ),
1247 SfxBroadcaster( rStyle )
1250 SfxStyleSheet::SfxStyleSheet()
1254 SfxStyleSheet::~SfxStyleSheet()
1256 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_INDESTRUCTION, *this ) );
1260 BOOL SfxStyleSheet::SetParent( const XubString& rName )
1262 if(aParent == rName)
1263 return TRUE;
1264 const XubString aOldParent(aParent);
1265 if(SfxStyleSheetBase::SetParent(rName)) {
1266 // aus der Benachrichtigungskette des alten
1267 // Parents gfs. austragen
1268 if(aOldParent.Len()) {
1269 SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aOldParent, nFamily, 0xffff);
1270 if(pParent)
1271 EndListening(*pParent);
1273 // in die Benachrichtigungskette des neuen
1274 // Parents eintragen
1275 if(aParent.Len()) {
1276 SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aParent, nFamily, 0xffff);
1277 if(pParent)
1278 StartListening(*pParent);
1280 return TRUE;
1282 return FALSE;
1285 // alle Zuhoerer benachtichtigen
1287 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
1289 Forward(rBC, rHint);
1292 //////////////////////// SfxStyleSheetPool ///////////////////////////////
1294 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
1295 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
1299 /////////////////////////////////// Factory ////////////////////////////////
1301 SfxStyleSheetBase* SfxStyleSheetPool::Create( const XubString& rName,
1302 SfxStyleFamily eFam, USHORT mask )
1304 return new SfxStyleSheet( rName, *this, eFam, mask );
1307 SfxStyleSheetBase* SfxStyleSheetPool::Create( const SfxStyleSheet& r )
1309 return new SfxStyleSheet( r );
1312 BOOL SfxStyleSheetPool::CopyTo(SfxStyleSheetPool &, const String &)
1314 return FALSE;
1318 // --------------------------------------------------------------------
1319 // class SfxUnoStyleSheet
1320 // --------------------------------------------------------------------
1322 SfxUnoStyleSheet::SfxUnoStyleSheet( const UniString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, USHORT _nMaske )
1323 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske )
1327 // --------------------------------------------------------------------
1328 SfxUnoStyleSheet::SfxUnoStyleSheet( const SfxStyleSheet& _rSheet )
1329 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rSheet )
1333 // --------------------------------------------------------------------
1335 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle )
1337 SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() );
1338 if( !pRet )
1340 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY );
1341 if( xUT.is() )
1342 pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier())));
1344 return pRet;
1347 // --------------------------------------------------------------------
1348 // XUnoTunnel
1349 // --------------------------------------------------------------------
1351 ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException)
1353 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) )
1355 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
1357 else
1359 return 0;
1363 // --------------------------------------------------------------------
1365 const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier()
1367 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0;
1368 if( !pSeq )
1370 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
1371 if( !pSeq )
1373 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
1374 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
1375 pSeq = &aSeq;
1378 return *pSeq;
1381 // --------------------------------------------------------------------