summaryrefslogtreecommitdiff
path: root/svtools/source/items/style.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/items/style.cxx')
-rw-r--r--svtools/source/items/style.cxx1201
1 files changed, 1201 insertions, 0 deletions
diff --git a/svtools/source/items/style.cxx b/svtools/source/items/style.cxx
new file mode 100644
index 000000000000..f62020536731
--- /dev/null
+++ b/svtools/source/items/style.cxx
@@ -0,0 +1,1201 @@
+/*************************************************************************
+ *
+ * $RCSfile: style.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:01 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#pragma hdrstop
+
+#include <smplhint.hxx>
+#include <poolitem.hxx>
+#include <itemset.hxx>
+#include <itempool.hxx>
+#include <poolio.hxx>
+#include <filerec.hxx>
+#include <itemiter.hxx>
+#include "style.hxx"
+
+#define STYLESTREAM "SfxStyleSheets"
+#define STYLESTREAM_VERSION USHORT(50)
+
+
+
+TYPEINIT0(SfxStyleSheetBase)
+
+TYPEINIT3(SfxStyleSheet, SfxStyleSheetBase, SfxListener, SfxBroadcaster)
+
+
+//=========================================================================
+
+TYPEINIT1(SfxStyleSheetHint, SfxHint);
+TYPEINIT1(SfxStyleSheetHintExtended, SfxStyleSheetHint);
+TYPEINIT1(SfxStyleSheetPoolHint, SfxHint);
+
+SfxStyleSheetHintExtended::SfxStyleSheetHintExtended
+(
+ USHORT nAction, // SFX_STYLESHEET_... (s.o.)
+ const String& rOldName,
+ SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer
+)
+: SfxStyleSheetHint( nAction, rStyleSheet ),
+ aName( rOldName )
+{}
+
+//-------------------------------------------------------------------------
+
+SfxStyleSheetHint::SfxStyleSheetHint
+(
+ USHORT nAction, // SFX_STYLESHEET_... (s.o.)
+ SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer
+)
+: pStyleSh( &rStyleSheet ),
+ nHint( nAction )
+{}
+
+//=========================================================================
+
+class SfxStyleSheetBasePool_Impl
+{
+ public:
+ SfxStyles aStyles;
+ SfxStyleSheetIterator *pIter;
+ SfxStyleSheetBasePool_Impl() : pIter(0){}
+ ~SfxStyleSheetBasePool_Impl(){delete pIter;}
+};
+
+
+//////////////////////////// SfxStyleSheetBase ///////////////////////////////
+
+// Konstruktoren
+
+SfxStyleSheetBase::SfxStyleSheetBase
+ ( const XubString& rName, SfxStyleSheetBasePool& r, SfxStyleFamily eFam, USHORT mask )
+ : aName( rName ), aParent(), aFollow( rName ),
+ nFamily( eFam ), nMask(mask), rPool( r ),
+ nHelpId( 0 ), pSet( NULL ), bMySet( FALSE )
+{
+}
+
+SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r )
+ : aName( r.aName ), aParent( r.aParent ), aFollow( r.aFollow ),
+ nFamily( r.nFamily ),
+ nMask( r.nMask ),
+ rPool( r.rPool ),
+ nHelpId( r.nHelpId ), aHelpFile( r.aHelpFile ), bMySet( r.bMySet )
+{
+ if( r.pSet )
+ pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet;
+ else
+ pSet = NULL;
+}
+
+SfxStyleSheetBase::~SfxStyleSheetBase()
+{
+ if( bMySet )
+ {
+ delete pSet;
+ pSet = 0;
+ }
+}
+
+USHORT SfxStyleSheetBase::GetVersion() const
+{
+ return 0x0000;
+}
+
+// Namen aendern
+
+const XubString& SfxStyleSheetBase::GetName() const
+{
+ return aName;
+}
+
+BOOL SfxStyleSheetBase::SetName( const XubString& rName )
+{
+ if(rName.Len() == 0)
+ return FALSE;
+ if( aName != rName )
+ {
+ String aOldName = aName;
+ SfxStyleSheetBase *pOther = rPool.Find( rName, nFamily ) ;
+ if ( pOther && pOther != this )
+ return FALSE;
+
+ SfxStyleFamily eTmpFam=rPool.GetSearchFamily();
+ USHORT nTmpMask=rPool.GetSearchMask();
+
+ rPool.SetSearchMask(nFamily);
+
+ if ( aName.Len() )
+ rPool.ChangeParent( aName, rName, FALSE );
+ if ( aFollow.Equals( aName ) )
+ aFollow = rName;
+ aName = rName;
+ rPool.SetSearchMask(eTmpFam, nTmpMask);
+ rPool.Broadcast( SfxStyleSheetHintExtended(
+ SFX_STYLESHEET_MODIFIED, aOldName, *this ) );
+ }
+ return TRUE;
+}
+
+// Parent aendern
+
+const XubString& SfxStyleSheetBase::GetParent() const
+{
+ return aParent;
+}
+
+BOOL SfxStyleSheetBase::SetParent( const XubString& rName )
+{
+ if( aParent != rName )
+ {
+ SfxStyleSheetBase* pIter = rPool.Find(rName, nFamily);
+ if( rName.Len() && !pIter )
+ {
+ DBG_ERROR( "StyleSheet-Parent nicht gefunden" );
+ return FALSE;
+ }
+ // rekursive Verknuepfungen verhindern
+ if( aName.Len() )
+ while(pIter)
+ {
+ if(pIter->GetName() == aName && aName != rName)
+ return FALSE;
+ pIter = rPool.Find(pIter->GetParent(), nFamily);
+ }
+ aParent = rName;
+ }
+ rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) );
+ return TRUE;
+}
+
+// Follow aendern
+
+const XubString& SfxStyleSheetBase::GetFollow() const
+{
+ return aFollow;
+}
+
+BOOL SfxStyleSheetBase::SetFollow( const XubString& rName )
+{
+ if( aFollow != rName )
+ {
+ if( !rPool.Find( rName, nFamily ) )
+ {
+ DBG_ERROR( "StyleSheet-Follow nicht gefunden" );
+ return FALSE;
+ }
+ aFollow = rName;
+ }
+ rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) );
+ return TRUE;
+}
+
+// Itemset setzen. Die Dflt-Implementation legt ein neues Set an.
+
+SfxItemSet& SfxStyleSheetBase::GetItemSet()
+{
+ if( !pSet )
+ {
+ pSet = new SfxItemSet( rPool.GetPool() );
+ bMySet = TRUE;
+ }
+ return *pSet;
+}
+
+// Hilfe-Datei und -ID setzen und abfragen
+
+ULONG SfxStyleSheetBase::GetHelpId( String& rFile )
+{
+ rFile = aHelpFile;
+ return nHelpId;
+}
+
+void SfxStyleSheetBase::SetHelpId( const String& rFile, ULONG nId )
+{
+ aHelpFile = rFile;
+ nHelpId = nId;
+}
+
+// Folgevorlage m"oglich? Default: Ja
+
+BOOL SfxStyleSheetBase::HasFollowSupport() const
+{
+ return TRUE;
+}
+
+// Basisvorlage m"oglich? Default: Ja
+
+BOOL SfxStyleSheetBase::HasParentSupport() const
+{
+ return TRUE;
+}
+
+// Basisvorlage uf NULL setzen m"oglich? Default: Nein
+
+BOOL SfxStyleSheetBase::HasClearParentSupport() const
+{
+ return FALSE;
+}
+
+// Defaultmaessig sind alle StyleSheets Used
+
+BOOL SfxStyleSheetBase::IsUsed() const
+{
+ return TRUE;
+}
+
+// eingestellte Attribute ausgeben
+
+
+XubString SfxStyleSheetBase::GetDescription()
+{
+#if SUPD >= 368
+ return GetDescription( SFX_MAPUNIT_CM );
+
+/*!!!
+ if ( !pSet )
+ GetItemSet();
+ SfxItemIter aIter( *pSet );
+ XubString aDesc;
+ const SfxPoolItem* pItem = aIter.FirstItem();
+
+ while ( pItem )
+ {
+ XubString aItemPresentation;
+
+ if ( !IsInvalidItem( pItem ) &&
+ rPool.GetPool().GetPresentation(
+ *pItem, SFX_ITEM_PRESENTATION_COMPLETE,
+ SFX_MAPUNIT_CM, aItemPresentation ) )
+ {
+ if ( aDesc.Len() && aItemPresentation.Len() )
+#ifndef ENABLEUNICODE
+ aDesc += " + ";
+#else
+ aDesc += L" + ";
+#endif
+ if ( aItemPresentation.Len() )
+ aDesc += aItemPresentation;
+ }
+ pItem = aIter.NextItem();
+ }
+ return aDesc;
+*/
+}
+
+// eingestellte Attribute ausgeben
+
+XubString SfxStyleSheetBase::GetDescription( SfxMapUnit eMetric )
+{
+#endif
+ SfxItemIter aIter( GetItemSet() );
+ XubString aDesc;
+ const SfxPoolItem* pItem = aIter.FirstItem();
+
+ while ( pItem )
+ {
+ XubString aItemPresentation;
+
+#if SUPD >= 368
+ if ( !IsInvalidItem( pItem ) &&
+ rPool.GetPool().GetPresentation(
+ *pItem, SFX_ITEM_PRESENTATION_COMPLETE,
+ eMetric, aItemPresentation ) )
+#else
+ if ( !IsInvalidItem( pItem ) &&
+ rPool.GetPool().GetPresentation(
+ *pItem, SFX_ITEM_PRESENTATION_COMPLETE,
+ SFX_MAPUNIT_CM, aItemPresentation ) )
+#endif
+ {
+ if ( aDesc.Len() && aItemPresentation.Len() )
+ aDesc.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" + "));
+ if ( aItemPresentation.Len() )
+ aDesc += aItemPresentation;
+ }
+ pItem = aIter.NextItem();
+ }
+ return aDesc;
+}
+
+/////////////////////////// SfxStyleSheetIterator ///////////////////////////////
+
+SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
+{
+ return nSearchFamily;
+}
+
+inline BOOL SfxStyleSheetIterator::IsTrivialSearch()
+{
+ return nMask == 0xFFFF && GetSearchFamily() == SFX_STYLE_FAMILY_ALL;
+}
+
+BOOL SfxStyleSheetIterator::DoesStyleMatch(SfxStyleSheetBase *pStyle)
+{
+ return ((GetSearchFamily() == SFX_STYLE_FAMILY_ALL) ||
+ ( pStyle->GetFamily() == GetSearchFamily() ))
+ && (( pStyle->GetMask() & ( GetSearchMask() & ~SFXSTYLEBIT_USED )) ||
+ ( bSearchUsed ? pStyle->IsUsed() : FALSE ) ||
+ GetSearchMask() == SFXSTYLEBIT_ALL );
+}
+
+
+SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
+ SfxStyleFamily eFam, USHORT n)
+{
+ pBasePool=pBase;
+ nSearchFamily=eFam;
+ bSearchUsed=FALSE;
+ int nn=SFXSTYLEBIT_USED;
+ int nnn=SFXSTYLEBIT_ALL;
+ if((n != SFXSTYLEBIT_ALL ) && ((n & SFXSTYLEBIT_USED) == SFXSTYLEBIT_USED))
+ {
+ bSearchUsed = TRUE;
+ n &= ~SFXSTYLEBIT_USED;
+ }
+ nMask=n;
+}
+
+SfxStyleSheetIterator::~SfxStyleSheetIterator()
+{
+}
+
+
+USHORT SfxStyleSheetIterator::Count()
+{
+ USHORT n = 0;
+ if( IsTrivialSearch())
+ n = (USHORT) pBasePool->aStyles.Count();
+ else
+ for(USHORT i=0; i<pBasePool->aStyles.Count(); i++)
+ {
+ SfxStyleSheetBase* pStyle = pBasePool->aStyles.GetObject(i);
+ if(DoesStyleMatch(pStyle))
+ n++;
+ }
+ return n;
+}
+
+SfxStyleSheetBase* SfxStyleSheetIterator::operator[](USHORT nIdx)
+{
+ if( IsTrivialSearch())
+ return pBasePool->aStyles.GetObject(nIdx);
+
+ USHORT z = 0;
+ for(USHORT n=0; n<pBasePool->aStyles.Count(); n++)
+ {
+ SfxStyleSheetBase* pStyle = pBasePool->aStyles.GetObject(n);
+ if( DoesStyleMatch(pStyle))
+ {
+ if(z == nIdx)
+ {
+ nAktPosition=n;
+ return pAktStyle=pStyle;
+ }
+ ++z;
+ }
+ }
+ DBG_ERROR("falscher Index");
+ return 0;
+}
+
+SfxStyleSheetBase* SfxStyleSheetIterator::First()
+{
+ INT32 nIdx = -1;
+
+ if ( IsTrivialSearch() && pBasePool->aStyles.Count() )
+ nIdx = 0;
+ else
+ for( USHORT n = 0; n < pBasePool->aStyles.Count(); n++ )
+ {
+ SfxStyleSheetBase* pStyle = pBasePool->aStyles.GetObject(n);
+
+ if ( DoesStyleMatch( pStyle ) )
+ {
+ nIdx = n;
+ break;
+ }
+ }
+
+ if ( nIdx != -1 )
+ {
+ nAktPosition = (USHORT)nIdx;
+ return pAktStyle = pBasePool->aStyles.GetObject(nIdx);
+ }
+ return 0;
+}
+
+
+SfxStyleSheetBase* SfxStyleSheetIterator::Next()
+{
+ INT32 nIdx = -1;
+
+ if ( IsTrivialSearch() &&
+ (USHORT)pBasePool->aStyles.Count() > nAktPosition + 1 )
+ nIdx = nAktPosition + 1;
+ else
+ for( USHORT n = nAktPosition + 1; n < pBasePool->aStyles.Count(); n++ )
+ {
+ SfxStyleSheetBase* pStyle = pBasePool->aStyles.GetObject(n);
+
+ if ( DoesStyleMatch( pStyle ) )
+ {
+ nIdx = n;
+ break;
+ }
+ }
+
+ if ( nIdx != -1 )
+ {
+ nAktPosition = (USHORT)nIdx;
+ return pAktStyle = pBasePool->aStyles.GetObject(nIdx);
+ }
+ return 0;
+}
+
+
+SfxStyleSheetBase* SfxStyleSheetIterator::Find(const XubString& rStr)
+{
+ for ( USHORT n = 0; n < pBasePool->aStyles.Count(); n++ )
+ {
+ SfxStyleSheetBase* pStyle = pBasePool->aStyles.GetObject(n);
+
+ if ( DoesStyleMatch( pStyle ) &&
+ pStyle->GetName().Equals( rStr ) )
+ {
+ nAktPosition = n;
+ return pAktStyle = pStyle;
+ }
+ }
+ return 0;
+}
+
+
+USHORT SfxStyleSheetIterator::GetSearchMask() const
+{
+ USHORT mask = nMask;
+
+ if ( bSearchUsed )
+ mask |= SFXSTYLEBIT_USED;
+ return mask;
+}
+
+/////////////////////////// SfxStyleSheetBasePool ///////////////////////////////
+
+
+void SfxStyleSheetBasePool::Replace(
+ SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget )
+{
+ rTarget.SetFollow( rSource.GetFollow() );
+ rTarget.SetParent( rSource.GetParent() );
+ SfxItemSet& rSourceSet = rSource.GetItemSet();
+ SfxItemSet& rTargetSet = rTarget.GetItemSet();
+ rTargetSet.Intersect( rSourceSet );
+ rTargetSet.Put( rSourceSet );
+}
+
+SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl()
+{
+ SfxStyleSheetIterator*& rpIter = pImp->pIter;
+ if( !rpIter || rpIter->GetSearchMask() != nMask ||
+ rpIter->GetSearchFamily() != nSearchFamily )
+ {
+ delete rpIter;
+#if SUPD > 363
+ rpIter = CreateIterator( nSearchFamily, nMask );
+#else
+ rpIter = new SfxStyleSheetIterator( this, nSearchFamily, nMask );
+#endif
+ }
+ return *rpIter;
+}
+
+
+SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r )
+: rPool(r), aAppName(r.GetName()),
+ nMask(0xFFFF), nSearchFamily(SFX_STYLE_FAMILY_PARA)
+{
+ pImp = new SfxStyleSheetBasePool_Impl;
+}
+
+SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r )
+: rPool(r.rPool),
+ nMask( r.nMask ), nSearchFamily(r.nSearchFamily),aAppName(r.aAppName)
+{
+ pImp = new SfxStyleSheetBasePool_Impl;
+ *this += r;
+}
+
+SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
+{
+ Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
+ Clear();
+ delete pImp;
+}
+
+BOOL SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const XubString& rStyle, const XubString& rParent)
+{
+ SfxStyleSheetIterator aIter(this,eFam,SFXSTYLEBIT_ALL);
+ SfxStyleSheetBase *pStyle =
+ aIter.Find(rStyle);
+ DBG_ASSERT(pStyle, "Vorlage nicht gefunden. Writer mit Solar <2541??");
+ if(pStyle)
+ return pStyle->SetParent(rParent);
+ else
+ return FALSE;
+}
+
+
+void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, USHORT n)
+{
+ nSearchFamily = eFam; nMask = n;
+}
+
+USHORT SfxStyleSheetBasePool::GetSearchMask() const
+{
+ return nMask;
+}
+
+
+// Der Name des Streams
+
+String SfxStyleSheetBasePool::GetStreamName()
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STYLESTREAM));
+}
+
+/////////////////////////////////// Factory ////////////////////////////////
+
+
+#if SUPD > 363
+
+SfxStyleSheetIterator* SfxStyleSheetBasePool::CreateIterator
+(
+ SfxStyleFamily eFam,
+ USHORT mask
+)
+{
+ return new SfxStyleSheetIterator(this,eFam,mask);
+}
+
+#endif
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Create
+(
+ const XubString& rName,
+ SfxStyleFamily eFam,
+ USHORT mask
+)
+{
+ return new SfxStyleSheetBase( rName, *this, eFam, mask );
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
+{
+ return new SfxStyleSheetBase( r );
+}
+
+SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const XubString& rName,
+ SfxStyleFamily eFam, USHORT mask, USHORT nPos)
+{
+ DBG_ASSERT( eFam != SFX_STYLE_FAMILY_ALL, "FamilyAll als Familie nicht erlaubt" );
+
+ SfxStyleSheetIterator aIter(this, eFam, mask);
+ SfxStyleSheetBase* p = aIter.Find( rName );
+ DBG_ASSERT( !p, "StyleSheet bereits vorhanden" );
+ SfxStyleSheetIterator& rIter = GetIterator_Impl();
+
+ if( !p )
+ {
+ p = Create( rName, eFam, mask );
+ if(0xffff == nPos || nPos == aStyles.Count() ||
+ nPos == rIter.Count())
+ aStyles.Insert( p, aStyles.Count() );
+ else
+ {
+ rIter[nPos];
+ aStyles.Insert(p, rIter.GetPos());
+ }
+ Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) );
+ }
+ return *p;
+}
+
+/////////////////////////////// Kopieren ///////////////////////////////////
+
+// Hilfsroutine: Falls eine Vorlage dieses Namens existiert, wird
+// sie neu erzeugt. Alle Vorlagen, die diese Vorlage zum Parent haben,
+// werden umgehaengt.
+
+SfxStyleSheetBase& SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet )
+{
+ SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask);
+ SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
+ Erase( pOld );
+ SfxStyleSheetBase* pNew = Create( rSheet );
+ aStyles.Insert( pNew, aStyles.Count() );
+ Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *pNew ) );
+ return *pNew;
+}
+
+SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
+{
+ if( &r != this )
+ {
+ Clear();
+ *this += r;
+ }
+ return *this;
+}
+
+SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& rP )
+{
+ if( &rP != this )
+ {
+ // kopieren
+ SfxStyleSheetBasePool& r = (SfxStyleSheetBasePool&) rP;
+ for( SfxStyleSheetBase* p = r.aStyles.First(); p; p = r.aStyles.Next() )
+ Add(*p);
+
+ }
+ return *this;
+}
+
+//////////////////////////////// Suchen ////////////////////////////////////
+
+USHORT SfxStyleSheetBasePool::Count()
+{
+ return GetIterator_Impl().Count();
+}
+
+SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](USHORT nIdx)
+{
+ return GetIterator_Impl()[nIdx];
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const XubString& rName,
+ SfxStyleFamily eFam,
+ USHORT mask)
+{
+ SfxStyleSheetIterator aIter(this,eFam,mask);
+ return aIter.Find(rName);
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::First()
+{
+ return GetIterator_Impl().First();
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
+{
+ return GetIterator_Impl().Next();
+}
+
+//////////////////////////////// Loeschen /////////////////////////////////
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
+{
+ if( p )
+ {
+ // Alle Styles umsetzen, deren Parent dieser hier ist
+ ChangeParent( p->GetName(), p->GetParent() );
+ aStyles.Remove( p );
+ Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) );
+ }
+ return p;
+}
+
+void SfxStyleSheetBasePool::Erase( SfxStyleSheetBase* p )
+{
+ if( p )
+ {
+ Remove(p);
+ delete p;
+ }
+}
+
+void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
+{
+ DBG_ASSERT( p, "Kein StyleSheet?" );
+ SfxStyleSheetIterator aIter(
+ this, p->GetFamily(), p->GetMask());
+ SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
+ DBG_ASSERT( !pOld, "StyleSheet bereits vorhanden" );
+ if( p->GetParent().Len() )
+ {
+ pOld = aIter.Find( p->GetParent() );
+ DBG_ASSERT( pOld, "Parent nicht mehr vorhanden" );
+ }
+ aStyles.Insert( p, aStyles.Count() );
+ Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) );
+}
+
+void SfxStyleSheetBasePool::Clear()
+{
+ while( aStyles.Count() )
+ {
+ SfxStyleSheetBase* p = aStyles.First();
+ aStyles.Remove( p );
+ Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) );
+ delete p;
+ }
+}
+
+/////////////////////////// Parents umsetzen ////////////////////////////////
+
+void SfxStyleSheetBasePool::ChangeParent(const XubString& rOld,
+ const XubString& rNew,
+ BOOL bVirtual)
+{
+ const ULONG nPos = aStyles.GetCurPos();
+ const USHORT nTmpMask = GetSearchMask();
+ SetSearchMask(GetSearchFamily(), 0xffff);
+ for( SfxStyleSheetBase* p = First(); p; p = Next() )
+ {
+ if( p->GetParent().Equals( rOld ) )
+ {
+ if(bVirtual)
+ p->SetParent( rNew );
+ else
+ p->aParent = rNew;
+ }
+ }
+ SetSearchMask(GetSearchFamily(), nTmpMask);
+ aStyles.Seek(nPos);
+}
+
+/////////////////////////// Laden/Speichern /////////////////////////////////
+
+void SfxStyleSheetBase::Load( SvStream&, USHORT )
+{
+}
+
+void SfxStyleSheetBase::Store( SvStream& )
+{
+}
+
+
+BOOL SfxStyleSheetBasePool::Load( SvStream& rStream )
+{
+ // alte Version?
+ if ( !rPool.IsVer2_Impl() )
+ return Load1_Impl( rStream );
+
+ // gesamten StyleSheetPool in neuer Version aus einem MiniRecord lesen
+ SfxMiniRecordReader aPoolRec( &rStream, SFX_STYLES_REC );
+
+ // Header-Record lesen
+ short nCharSet;
+ if ( !rStream.GetError() )
+ {
+ SfxSingleRecordReader aHeaderRec( &rStream, SFX_STYLES_REC_HEADER );
+ if ( !aHeaderRec.IsValid() )
+ return FALSE;
+
+ aAppName = rPool.GetName();
+ rStream >> nCharSet;
+ }
+
+ // Styles-Record lesen
+ if ( !rStream.GetError() )
+ {
+ SfxMultiRecordReader aStylesRec( &rStream, SFX_STYLES_REC_STYLES );
+ if ( !aStylesRec.IsValid() )
+ return FALSE;
+
+ USHORT nCount;
+ for ( nCount = 0; aStylesRec.GetContent(); nCount++ )
+ {
+ // kann nicht mehr weiterlesen?
+ if ( rStream.GetError() )
+ break;
+
+ // Globale Teile
+ XubString aName, aParent, aFollow;
+ String aHelpFile;
+ USHORT nFamily, nMask,nCount;
+ ULONG nHelpId;
+ rStream.ReadByteString(aName, rtl_TextEncoding(nCharSet));
+ rStream.ReadByteString(aParent, rtl_TextEncoding(nCharSet));
+ rStream.ReadByteString(aFollow, rtl_TextEncoding(nCharSet));
+ rStream >> nFamily >> nMask;
+ SfxPoolItem::readByteString(rStream, aHelpFile);
+ rStream >> nHelpId;
+
+#ifndef ENABLEUNICODE
+ // bei Unicode keine Konvertierung erforderlich
+ aName.Convert( (CharSet) nCharSet );
+ aParent.Convert( (CharSet) nCharSet );
+ aFollow.Convert( (CharSet) nCharSet );
+
+ // #72939# When loading from a different CharSet, several style
+ // names may have been converted to the same string, so the styles
+ // can't be inserted. If a style with this name already exists,
+ // generate an internal name so the information from the styles
+ // isn't lost.
+ if ( nCharSet != ::GetSystemCharSet() &&
+ Find( aName, (SfxStyleFamily)nFamily ) != NULL )
+ {
+ DBG_WARNING("style has to be renamed");
+ USHORT nMax = aStyles.Count() + 1;
+ for ( USHORT nAdd=1; nAdd<=nMax; nAdd++ )
+ {
+ aName = '_';
+ aName += nAdd;
+ if ( Find( aName, (SfxStyleFamily)nFamily ) == NULL )
+ break;
+ }
+ }
+#endif
+ SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nMask);
+ rSheet.SetHelpId( aHelpFile, nHelpId );
+ // Hier erst einmal Parent und Follow zwischenspeichern
+ rSheet.aParent = aParent;
+ rSheet.aFollow = aFollow;
+ UINT32 nPos = rStream.Tell();
+ rStream >> nCount;
+ if(nCount)
+ {
+ rStream.Seek( nPos );
+ // Das Laden des ItemSets bedient sich der Methode GetItemSet(),
+ // damit eigene ItemSets untergeschoben werden koennen
+ SfxItemSet& rSet = rSheet.GetItemSet();
+ rSet.ClearItem();
+ //! SfxItemSet aTmpSet( *pTmpPool );
+ /*!aTmpSet*/ rSet.Load( rStream );
+ //! rSet.Put( aTmpSet );
+ }
+ // Lokale Teile
+ UINT32 nSize;
+ USHORT nVer;
+ rStream >> nVer >> nSize;
+ nPos = rStream.Tell() + nSize;
+ rSheet.Load( rStream, nVer );
+ rStream.Seek( nPos );
+ }
+
+ // #72939# only loop through the styles that were really inserted
+ nCount = aStyles.Count();
+
+ //! delete pTmpPool;
+ // Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
+ // Mit Setxxx() noch einmal den String eintragen, da diese
+ // virtuellen Methoden evtl. ueberlagert sind.
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ SfxStyleSheetBase* p = aStyles.GetObject( i );
+ XubString aText = p->aParent;
+ p->aParent.Erase();
+ p->SetParent( aText );
+ aText = p->aFollow;
+ p->aFollow.Erase();
+ p->SetFollow( aText );
+ }
+ }
+
+ // alles klar?
+ return BOOL( rStream.GetError() == SVSTREAM_OK );
+}
+
+BOOL SfxStyleSheetBasePool::Load1_Impl( SvStream& rStream )
+{
+ aAppName = rPool.GetName();
+ USHORT nVersion;
+ short nCharSet;
+ rStream >> nVersion;
+
+ if(nVersion!=STYLESTREAM_VERSION)
+ nCharSet=nVersion;
+ else
+ rStream >> nCharSet;
+
+ USHORT nCount;
+ rStream >> nCount;
+ USHORT i;
+ for ( i = 0; i < nCount; i++ )
+ {
+ // kann nicht mehr weiterlesen?
+ if ( rStream.GetError() )
+ {
+ nCount = i;
+ break;
+ }
+
+ // Globale Teile
+ XubString aName, aParent, aFollow;
+ String aHelpFile;
+ USHORT nFamily, nMask,nCount;
+ ULONG nHelpId;
+ rStream.ReadByteString(aName, rtl_TextEncoding(nCharSet));
+ rStream.ReadByteString(aParent, rtl_TextEncoding(nCharSet));
+ rStream.ReadByteString(aFollow, rtl_TextEncoding(nCharSet));
+ rStream >> nFamily >> nMask;
+ SfxPoolItem::readByteString(rStream, aHelpFile);
+ if(nVersion!=STYLESTREAM_VERSION)
+ {
+ USHORT nTmpHelpId;
+ rStream >> nTmpHelpId;
+ nHelpId=nTmpHelpId;
+ }
+ else
+ rStream >> nHelpId;
+
+#ifndef ENABLEUNICODE
+ // bei Unicode keine Konvertierung erforderlich
+ aName.Convert( (CharSet) nCharSet );
+ aParent.Convert( (CharSet) nCharSet );
+ aFollow.Convert( (CharSet) nCharSet );
+#endif
+ SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nMask);
+ rSheet.SetHelpId( aHelpFile, nHelpId );
+ // Hier erst einmal Parent und Follow zwischenspeichern
+ rSheet.aParent = aParent;
+ rSheet.aFollow = aFollow;
+ UINT32 nPos = rStream.Tell();
+ rStream >> nCount;
+ if(nCount) {
+ rStream.Seek( nPos );
+ // Das Laden des ItemSets bedient sich der Methode GetItemSet(),
+ // damit eigene ItemSets untergeschoben werden koennen
+ SfxItemSet& rSet = rSheet.GetItemSet();
+ rSet.ClearItem();
+//! SfxItemSet aTmpSet( *pTmpPool );
+ /*!aTmpSet*/ rSet.Load( rStream );
+ //! rSet.Put( aTmpSet );
+ }
+ // Lokale Teile
+ UINT32 nSize;
+ USHORT nVer;
+ rStream >> nVer >> nSize;
+ nPos = rStream.Tell() + nSize;
+ rSheet.Load( rStream, nVer );
+ rStream.Seek( nPos );
+ }
+
+ //! delete pTmpPool;
+ // Jetzt Parent und Follow setzen. Alle Sheets sind geladen.
+ // Mit Setxxx() noch einmal den String eintragen, da diese
+ // virtuellen Methoden evtl. ueberlagert sind.
+ for ( i = 0; i < nCount; i++ )
+ {
+ SfxStyleSheetBase* p = aStyles.GetObject( i );
+ XubString aText = p->aParent;
+ p->aParent.Erase();
+ p->SetParent( aText );
+ aText = p->aFollow;
+ p->aFollow.Erase();
+ p->SetFollow( aText );
+ }
+ return BOOL( rStream.GetError() == SVSTREAM_OK );
+}
+
+BOOL SfxStyleSheetBasePool::Store( SvStream& rStream, BOOL bUsed )
+{
+ // den ganzen StyleSheet-Pool in einen Mini-Record
+ SfxMiniRecordWriter aPoolRec( &rStream, SFX_STYLES_REC );
+
+ // Erst einmal die Dummies rauszaehlen; die werden nicht gespeichert
+ USHORT nCount = 0;
+ for( SfxStyleSheetBase* p = First(); p; p = Next() )
+ {
+ if(!bUsed || p->IsUsed())
+ nCount++;
+ }
+
+ // einen Header-Record vorweg
+ rtl_TextEncoding eCharSet
+ = ::GetStoreCharSet( rStream.GetStreamCharSet() );
+ {
+ SfxSingleRecordWriter aHeaderRec( &rStream,
+ SFX_STYLES_REC_HEADER,
+ STYLESTREAM_VERSION );
+ rStream << (short) eCharSet;
+ }
+
+ // die StyleSheets in einen MultiVarRecord
+ {
+ SfxMultiVarRecordWriter aStylesRec( &rStream, SFX_STYLES_REC_STYLES, 0 );
+ for( SfxStyleSheetBase* p = First(); p; p = Next() )
+ {
+ if(!bUsed || p->IsUsed())
+ {
+ aStylesRec.NewContent();
+
+ // Globale Teile speichern
+ String aHelpFile;
+ ULONG nHelpId = p->GetHelpId( aHelpFile );
+ rStream.WriteByteString(p->GetName(), eCharSet);
+ rStream.WriteByteString(p->GetParent(), eCharSet);
+ rStream.WriteByteString(p->GetFollow(), eCharSet);
+ rStream << (USHORT)p->GetFamily() << p->GetMask();
+ SfxPoolItem::writeByteString(rStream, aHelpFile);
+ rStream << nHelpId;
+ if(p->pSet)
+ p->pSet->Store( rStream );
+ else
+ rStream << (USHORT)0;
+
+ // Lokale Teile speichern
+ // Vor dem lokalen Teil wird die Laenge der lokalen Daten
+ // als UINT32 sowie die Versionsnummer gespeichert.
+ rStream << (USHORT) p->GetVersion();
+ ULONG nPos1 = rStream.Tell();
+ rStream << (UINT32) 0;
+ p->Store( rStream );
+ ULONG nPos2 = rStream.Tell();
+ rStream.Seek( nPos1 );
+ rStream << (UINT32) ( nPos2 - nPos1 - sizeof( UINT32 ) );
+ rStream.Seek( nPos2 );
+ if( rStream.GetError() != SVSTREAM_OK )
+ break;
+ }
+ }
+ }
+
+ return BOOL( rStream.GetError() == SVSTREAM_OK );
+}
+
+SfxItemPool& SfxStyleSheetBasePool::GetPool()
+{
+ return rPool;
+}
+
+const SfxItemPool& SfxStyleSheetBasePool::GetPool() const
+{
+ return rPool;
+}
+
+/////////////////////// SfxStyleSheet /////////////////////////////////
+
+SfxStyleSheet::SfxStyleSheet(const XubString &rName,
+ SfxStyleSheetBasePool& rPool,
+ SfxStyleFamily eFam,
+ USHORT mask ):
+ SfxStyleSheetBase(rName, rPool, eFam, mask)
+{}
+
+SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle) :
+ SfxStyleSheetBase(rStyle)
+{}
+
+SfxStyleSheet::~SfxStyleSheet()
+{
+ Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_INDESTRUCTION, *this ) );
+}
+
+
+BOOL SfxStyleSheet::SetParent( const XubString& rName )
+{
+ if(aParent == rName)
+ return TRUE;
+ const XubString aOldParent(aParent);
+ if(SfxStyleSheetBase::SetParent(rName)) {
+ // aus der Benachrichtigungskette des alten
+ // Parents gfs. austragen
+ if(aOldParent.Len()) {
+ SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aOldParent, nFamily, 0xffff);
+ if(pParent)
+ EndListening(*pParent);
+ }
+ // in die Benachrichtigungskette des neuen
+ // Parents eintragen
+ if(aParent.Len()) {
+ SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aParent, nFamily, 0xffff);
+ if(pParent)
+ StartListening(*pParent);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// alle Zuhoerer benachtichtigen
+
+void SfxStyleSheet::SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ SFX_FORWARD(rBC, rBCType, rHint, rHintType);
+}
+
+//////////////////////// SfxStyleSheetPool ///////////////////////////////
+
+SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool& rSet):
+ SfxStyleSheetBasePool(rSet)
+{}
+
+/////////////////////////////////// Factory ////////////////////////////////
+
+SfxStyleSheetBase* SfxStyleSheetPool::Create( const XubString& rName,
+ SfxStyleFamily eFam, USHORT mask )
+{
+ return new SfxStyleSheet( rName, *this, eFam, mask );
+}
+
+SfxStyleSheetBase* SfxStyleSheetPool::Create( const SfxStyleSheet& r )
+{
+ return new SfxStyleSheet( r );
+}
+/*
+BOOL SfxStyleSheetPool::CopyTo(SfxStyleSheetPool &, const String &)
+{
+ return FALSE;
+}
+*/
+