1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
37 #define _SVSTDARR_STRINGS
38 #define _SVSTDARR_STRINGSSORTDTOR
39 #define _SVSTDARR_BYTESTRINGS
40 #define _SVSTDARR_BYTESTRINGSSORTDTOR
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>
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>
59 #define STYLESTREAM "SfxStyleSheets"
60 #define STYLESTREAM_VERSION USHORT(50)
63 class DbgStyleSheetReferences
66 DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {}
67 ~DbgStyleSheetReferences()
69 OSL_TRACE("DbgStyleSheetReferences\nSfxStyleSheetBase left %ld\nSfxStyleSheetBasePool left %ld\n", mnStyles
, mnPools
);
75 aDbgStyleSheetReferences
;
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
),
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
),
108 //-------------------------------------------------------------------------
110 SfxStyleSheetHint::SfxStyleSheetHint
112 USHORT nAction
, // SFX_STYLESHEET_... (s.o.)
113 SfxStyleSheetBase
& rStyleSheet
// geh"ort weiterhin dem Aufrufer
115 : pStyleSh( &rStyleSheet
),
119 SfxStyleSheetHint::SfxStyleSheetHint
121 USHORT nAction
// SFX_STYLESHEET_... (s.o.)
127 //=========================================================================
129 class SfxStyleSheetBasePool_Impl
133 SfxStyleSheetIterator
*pIter
;
134 SfxStyleSheetBasePool_Impl() : pIter(0){}
135 ~SfxStyleSheetBasePool_Impl(){delete pIter
;}
139 //////////////////////////// SfxStyleSheetBase ///////////////////////////////
143 SfxStyleSheetBase::SfxStyleSheetBase( const XubString
& rName
, SfxStyleSheetBasePool
& r
, SfxStyleFamily eFam
, USHORT mask
)
155 aDbgStyleSheetReferences
.mnStyles
++;
159 SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase
& r
)
160 : comphelper::OWeakTypeObject()
162 , nFamily( r
.nFamily
)
164 , aParent( r
.aParent
)
165 , aFollow( r
.aFollow
)
166 , aHelpFile( r
.aHelpFile
)
168 , nHelpId( r
.nHelpId
)
172 aDbgStyleSheetReferences
.mnStyles
++;
175 pSet
= bMySet
? new SfxItemSet( *r
.pSet
) : r
.pSet
;
180 static SfxStyleSheetBasePool
& implGetStaticPool()
182 static SfxStyleSheetBasePool
* pSheetPool
= 0;
183 static SfxItemPool
* pBasePool
= 0;
187 pBasePool
= new SfxItemPool( aName
, 0, 0, 0 );
188 pSheetPool
= new SfxStyleSheetBasePool(*pBasePool
);
193 SfxStyleSheetBase::SfxStyleSheetBase()
194 : comphelper::OWeakTypeObject()
195 , rPool( implGetStaticPool() )
199 SfxStyleSheetBase::~SfxStyleSheetBase()
202 --aDbgStyleSheetReferences
.mnStyles
;
212 USHORT
SfxStyleSheetBase::GetVersion() const
219 const XubString
& SfxStyleSheetBase::GetName() const
224 BOOL
SfxStyleSheetBase::SetName( const XubString
& rName
)
230 String aOldName
= aName
;
231 SfxStyleSheetBase
*pOther
= rPool
.Find( rName
, nFamily
) ;
232 if ( pOther
&& pOther
!= this )
235 SfxStyleFamily eTmpFam
=rPool
.GetSearchFamily();
236 USHORT nTmpMask
=rPool
.GetSearchMask();
238 rPool
.SetSearchMask(nFamily
);
241 rPool
.ChangeParent( aName
, rName
, FALSE
);
242 if ( aFollow
.Equals( aName
) )
245 rPool
.SetSearchMask(eTmpFam
, nTmpMask
);
246 rPool
.Broadcast( SfxStyleSheetHintExtended(
247 SFX_STYLESHEET_MODIFIED
, aOldName
, *this ) );
252 rtl::OUString
SfxStyleSheetBase::GetDisplayName() const
254 if( maDisplayName
.getLength() == 0 )
260 return maDisplayName
;
264 void SfxStyleSheetBase::SetDisplayName( const rtl::OUString
& rDisplayName
)
266 maDisplayName
= rDisplayName
;
271 const XubString
& SfxStyleSheetBase::GetParent() const
276 BOOL
SfxStyleSheetBase::SetParent( const XubString
& rName
)
278 if ( rName
== aName
)
281 if( aParent
!= rName
)
283 SfxStyleSheetBase
* pIter
= rPool
.Find(rName
, nFamily
);
284 if( rName
.Len() && !pIter
)
286 DBG_ERROR( "StyleSheet-Parent nicht gefunden" );
289 // rekursive Verknuepfungen verhindern
293 if(pIter
->GetName() == aName
&& aName
!= rName
)
295 pIter
= rPool
.Find(pIter
->GetParent(), nFamily
);
299 rPool
.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED
, *this ) );
305 const XubString
& SfxStyleSheetBase::GetFollow() const
310 BOOL
SfxStyleSheetBase::SetFollow( const XubString
& rName
)
312 if( aFollow
!= rName
)
314 if( !rPool
.Find( rName
, nFamily
) )
316 DBG_ERROR( "StyleSheet-Follow nicht gefunden" );
321 rPool
.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED
, *this ) );
325 // Itemset setzen. Die Dflt-Implementation legt ein neues Set an.
327 SfxItemSet
& SfxStyleSheetBase::GetItemSet()
331 pSet
= new SfxItemSet( rPool
.GetPool() );
337 // Hilfe-Datei und -ID setzen und abfragen
339 ULONG
SfxStyleSheetBase::GetHelpId( String
& rFile
)
345 void SfxStyleSheetBase::SetHelpId( const String
& rFile
, ULONG nId
)
351 // Folgevorlage m"oglich? Default: Ja
353 BOOL
SfxStyleSheetBase::HasFollowSupport() const
358 // Basisvorlage m"oglich? Default: Ja
360 BOOL
SfxStyleSheetBase::HasParentSupport() const
365 // Basisvorlage uf NULL setzen m"oglich? Default: Nein
367 BOOL
SfxStyleSheetBase::HasClearParentSupport() const
372 // Defaultmaessig sind alle StyleSheets Used
374 BOOL
SfxStyleSheetBase::IsUsed() const
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() );
393 const SfxPoolItem
* pItem
= aIter
.FirstItem();
395 IntlWrapper
aIntlWrapper(comphelper::getProcessServiceFactory(),
396 Application::GetSettings().GetLanguage());
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();
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
)
444 if((n
!= SFXSTYLEBIT_ALL
) && ((n
& SFXSTYLEBIT_USED
) == SFXSTYLEBIT_USED
))
447 n
&= ~SFXSTYLEBIT_USED
;
452 SfxStyleSheetIterator::~SfxStyleSheetIterator()
457 USHORT
SfxStyleSheetIterator::Count()
460 if( IsTrivialSearch())
461 n
= (USHORT
) pBasePool
->aStyles
.size();
463 for(USHORT i
=0; i
<pBasePool
->aStyles
.size(); i
++)
465 SfxStyleSheetBase
* pStyle
= pBasePool
->aStyles
[i
].get();
466 if(DoesStyleMatch(pStyle
))
472 SfxStyleSheetBase
* SfxStyleSheetIterator::operator[](USHORT nIdx
)
474 if( IsTrivialSearch())
475 return pBasePool
->aStyles
[nIdx
].get();
478 for(USHORT n
=0; n
<pBasePool
->aStyles
.size(); n
++)
480 SfxStyleSheetBase
* pStyle
= pBasePool
->aStyles
[n
].get();
481 if( DoesStyleMatch(pStyle
))
486 return pAktStyle
=pStyle
;
491 DBG_ERROR("falscher Index");
495 SfxStyleSheetBase
* SfxStyleSheetIterator::First()
499 if ( IsTrivialSearch() && pBasePool
->aStyles
.size() )
502 for( USHORT n
= 0; n
< pBasePool
->aStyles
.size(); n
++ )
504 SfxStyleSheetBase
* pStyle
= pBasePool
->aStyles
[n
].get();
506 if ( DoesStyleMatch( pStyle
) )
515 nAktPosition
= (USHORT
)nIdx
;
516 return pAktStyle
= pBasePool
->aStyles
[nIdx
].get();
522 SfxStyleSheetBase
* SfxStyleSheetIterator::Next()
526 if ( IsTrivialSearch() &&
527 (USHORT
)pBasePool
->aStyles
.size() > nAktPosition
+ 1 )
528 nIdx
= nAktPosition
+ 1;
530 for( USHORT n
= nAktPosition
+ 1; n
< pBasePool
->aStyles
.size(); n
++ )
532 SfxStyleSheetBase
* pStyle
= pBasePool
->aStyles
[n
].get();
534 if ( DoesStyleMatch( pStyle
) )
543 nAktPosition
= (USHORT
)nIdx
;
544 return pAktStyle
= pBasePool
->aStyles
[nIdx
].get();
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
) )
562 return pAktStyle
= pStyle
;
569 USHORT
SfxStyleSheetIterator::GetSearchMask() const
574 mask
|= SFXSTYLEBIT_USED
;
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
) )
597 rpIter
= CreateIterator( nSearchFamily
, nMask
);
603 SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool
& r
)
604 : aAppName(r
.GetName())
606 , nSearchFamily(SFX_STYLE_FAMILY_PARA
)
610 aDbgStyleSheetReferences
.mnPools
++;
613 pImp
= new SfxStyleSheetBasePool_Impl
;
616 SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool
& r
)
617 : SfxBroadcaster( r
)
618 , comphelper::OWeakTypeObject()
619 , aAppName(r
.aAppName
)
621 , nSearchFamily(r
.nSearchFamily
)
625 aDbgStyleSheetReferences
.mnPools
++;
628 pImp
= new SfxStyleSheetBasePool_Impl
;
632 SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
635 aDbgStyleSheetReferences
.mnPools
--;
638 Broadcast( SfxSimpleHint(SFX_HINT_DYING
) );
643 BOOL
SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam
, const XubString
& rStyle
, const XubString
& rParent
)
645 SfxStyleSheetIterator
aIter(this,eFam
,SFXSTYLEBIT_ALL
);
646 SfxStyleSheetBase
*pStyle
=
648 DBG_ASSERT(pStyle
, "Vorlage nicht gefunden. Writer mit Solar <2541??");
650 return pStyle
->SetParent(rParent
);
656 void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam
, USHORT n
)
658 nSearchFamily
= eFam
; nMask
= n
;
661 USHORT
SfxStyleSheetBasePool::GetSearchMask() const
667 // Der Name des Streams
669 String
SfxStyleSheetBasePool::GetStreamName()
671 return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STYLESTREAM
));
674 /////////////////////////////////// Factory ////////////////////////////////
678 SfxStyleSheetIterator
* SfxStyleSheetBasePool::CreateIterator
684 return new SfxStyleSheetIterator(this,eFam
,mask
);
688 SfxStyleSheetBase
* SfxStyleSheetBasePool::Create
690 const XubString
& rName
,
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();
714 xStyle
= Create( rName
, eFam
, mask
);
715 if(0xffff == nPos
|| nPos
== aStyles
.size() || nPos
== rIter
.Count())
717 aStyles
.push_back( xStyle
);
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() );
740 rtl::Reference
< SfxStyleSheetBase
> xNew( Create( rSheet
) );
741 aStyles
.push_back( xNew
);
742 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED
, *xNew
.get() ) );
746 SfxStyleSheetBasePool
& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool
& r
)
756 SfxStyleSheetBasePool
& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool
& r
)
760 SfxStyles::const_iterator
aIter( r
.aStyles
.begin() );
761 while( aIter
!= r
.aStyles
.end() )
763 Add(*(*aIter
++).get());
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
,
785 SfxStyleSheetIterator
aIter(this,eFam
,mask
);
786 return aIter
.Find(rName
);
789 const SfxStyles
& SfxStyleSheetBasePool::GetStyles()
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
)
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
,
855 const USHORT nTmpMask
= GetSearchMask();
856 SetSearchMask(GetSearchFamily(), 0xffff);
857 for( SfxStyleSheetBase
* p
= First(); p
; p
= Next() )
859 if( p
->GetParent().Equals( rOld
) )
862 p
->SetParent( 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
)
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
892 if ( !rStream
.GetError() )
894 SfxSingleRecordReader
aHeaderRec( &rStream
, SFX_STYLES_REC_HEADER
);
895 if ( !aHeaderRec
.IsValid() )
898 aAppName
= rPool
.GetName();
902 // Styles-Record lesen
903 if ( !rStream
.GetError() )
905 SfxMultiRecordReader
aStylesRec( &rStream
, SFX_STYLES_REC_STYLES
);
906 if ( !aStylesRec
.IsValid() )
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
);
916 for ( nStyles
= 0; aStylesRec
.GetContent(); nStyles
++ )
918 // kann nicht mehr weiterlesen?
919 if ( rStream
.GetError() )
923 XubString aName
, aParent
, aFollow
;
925 USHORT nFamily
, nStyleMask
,nCount
;
927 rStream
.ReadByteString(aName
, eEnc
);
928 rStream
.ReadByteString(aParent
, eEnc
);
929 rStream
.ReadByteString(aFollow
, eEnc
);
930 rStream
>> nFamily
>> nStyleMask
;
931 SfxPoolItem::readByteString(rStream
, aHelpFile
);
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();
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();
948 //! SfxItemSet aTmpSet( *pTmpPool );
949 /*!aTmpSet*/ rSet
.Load( rStream
);
950 //! rSet.Put( aTmpSet );
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();
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
;
973 p
->SetParent( aText
);
976 p
->SetFollow( aText
);
979 rStream
.SetStreamCharSet( eOldEnc
);
983 return BOOL( rStream
.GetError() == SVSTREAM_OK
);
986 BOOL
SfxStyleSheetBasePool::Load1_Impl( SvStream
& rStream
)
988 aAppName
= rPool
.GetName();
993 if(nVersion
!=STYLESTREAM_VERSION
)
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
);
1007 for ( i
= 0; i
< nStyles
; i
++ )
1009 // kann nicht mehr weiterlesen?
1010 if ( rStream
.GetError() )
1017 XubString aName
, aParent
, aFollow
;
1019 USHORT nFamily
, nStyleMask
,nCount
;
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
)
1029 rStream
>> nTmpHelpId
;
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();
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();
1048 //! SfxItemSet aTmpSet( *pTmpPool );
1049 /*!aTmpSet*/ rSet
.Load( rStream
);
1050 //! rSet.Put( aTmpSet );
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
;
1070 p
->SetParent( aText
);
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
1088 for( SfxStyleSheetBase
* p
= First(); p
; p
= Next() )
1090 if(!bUsed
|| p
->IsUsed())
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
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 );
1133 sal::static_int_cast
< char >(0xff & (nFamily
>> 8)) );
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
);
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
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 ));
1181 rStream
.WriteByteString( sEmpty
);
1183 (sNm
= sFamily
) += p
->GetParent();
1184 if( aSortOrigNames
.Seek_Entry( &sNm
, &nFndPos
))
1185 rStream
.WriteByteString( aConvNames
.GetObject( nFndPos
)->Copy( 2 ));
1187 rStream
.WriteByteString( sEmpty
);
1189 (sNm
= sFamily
) += p
->GetFollow();
1190 if( aSortOrigNames
.Seek_Entry( &sNm
, &nFndPos
))
1191 rStream
.WriteByteString( aConvNames
.GetObject( nFndPos
)->Copy( 2 ));
1193 rStream
.WriteByteString( sEmpty
);
1195 rStream
<< nFamily
<< p
->GetMask();
1196 SfxPoolItem::writeByteString(rStream
, aHelpFile
);
1199 p
->pSet
->Store( rStream
);
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
)
1220 rStream
.SetStreamCharSet( eOldEnc
);
1222 return BOOL( rStream
.GetError() == SVSTREAM_OK
);
1225 SfxItemPool
& SfxStyleSheetBasePool::GetPool()
1230 const SfxItemPool
& SfxStyleSheetBasePool::GetPool() const
1235 /////////////////////// SfxStyleSheet /////////////////////////////////
1237 SfxStyleSheet::SfxStyleSheet(const XubString
&rName
,
1238 const SfxStyleSheetBasePool
& r_Pool
,
1239 SfxStyleFamily eFam
,
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
)
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);
1271 EndListening(*pParent
);
1273 // in die Benachrichtigungskette des neuen
1274 // Parents eintragen
1276 SfxStyleSheet
*pParent
= (SfxStyleSheet
*)rPool
.Find(aParent
, nFamily
, 0xffff);
1278 StartListening(*pParent
);
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 &)
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() );
1340 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XUnoTunnel
> xUT( xStyle
, ::com::sun::star::uno::UNO_QUERY
);
1342 pRet
= reinterpret_cast<SfxUnoStyleSheet
*>(sal::static_int_cast
<sal_uIntPtr
>(xUT
->getSomething( SfxUnoStyleSheet::getIdentifier())));
1347 // --------------------------------------------------------------------
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));
1363 // --------------------------------------------------------------------
1365 const ::com::sun::star::uno::Sequence
< ::sal_Int8
>& SfxUnoStyleSheet::getIdentifier()
1367 static ::com::sun::star::uno::Sequence
< sal_Int8
> * pSeq
= 0;
1370 ::osl::Guard
< ::osl::Mutex
> aGuard( ::osl::Mutex::getGlobalMutex() );
1373 static ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq( 16 );
1374 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
1381 // --------------------------------------------------------------------