/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: impastp4.cxx,v $ * * $Revision: 1.18 $ * * last change: $Author: kz $ $Date: 2006-07-06 14:23:26 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 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 * ************************************************************************/ #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef _XMLOFF_XMLASTPLP_HXX #include "xmlaustp.hxx" #endif #ifndef _XMLOFF_XMLTOKEN_HXX #include "xmltoken.hxx" #endif #ifndef _XMLOFF_NMSPMAP_HXX #include "nmspmap.hxx" #endif #ifndef _XMLOFF_XMLNMSPE_HXX #include "xmlnmspe.hxx" #endif #ifndef _XMLOFF_ATTRLIST_HXX #include "attrlist.hxx" #endif #ifndef _XMLOFF_XMLASTPL_IMPL_HXX #include "impastpl.hxx" #endif #ifndef _XMLOFF_XMLEXPPR_HXX #include "xmlexppr.hxx" #endif #ifndef _XMLOFF_XMLEXP_HXX #include "xmlexp.hxx" #endif #ifndef _XMLOFF_FAMILIES_HXX_ #include "families.hxx" #endif #ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX #include "PageMasterStyleMap.hxx" #endif using namespace ::std; using namespace ::rtl; using namespace ::com::sun::star; using namespace ::xmloff::token; //############################################################################# // // Class SvXMLAutoStylePool_Impl // /////////////////////////////////////////////////////////////////////////////// // // ctor/dtor class SvXMLAutoStylePool_Impl // SvXMLAutoStylePoolP_Impl::SvXMLAutoStylePoolP_Impl( SvXMLExport& rExp) : rExport( rExp ), maFamilyList( 5, 5 ) { } SvXMLAutoStylePoolP_Impl::~SvXMLAutoStylePoolP_Impl() { XMLFamilyData_Impl* pData = NULL; while( ( pData = maFamilyList.Remove( ULONG(0) ) ) ) delete pData; } /////////////////////////////////////////////////////////////////////////////// // // Adds stylefamily-informations to sorted list // void SvXMLAutoStylePoolP_Impl::AddFamily( sal_Int32 nFamily, const OUString& rStrName, const UniReference < SvXMLExportPropertyMapper > & rMapper, const OUString& rStrPrefix, sal_Bool bAsFamily ) { // store family in a list if not already stored ULONG nPos; XMLFamilyData_Impl *pFamily = new XMLFamilyData_Impl( nFamily, rStrName, rMapper, rStrPrefix, bAsFamily ); if( !maFamilyList.Seek_Entry( pFamily, &nPos ) ) maFamilyList.Insert( pFamily ); else delete pFamily; } /////////////////////////////////////////////////////////////////////////////// // // Adds a name to list // void SvXMLAutoStylePoolP_Impl::RegisterName( sal_Int32 nFamily, const OUString& rName ) { SvXMLAutoStylePoolNamesP_Impl *pNames = 0; ULONG nPos; XMLFamilyData_Impl aTmp( nFamily ); if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) pNames = maFamilyList.GetObject( nPos )->mpNameList; DBG_ASSERT( pNames, "SvXMLAutoStylePool_Impl::RegisterName: unknown family" ); if( pNames ) { OUString *pName = new OUString( rName ); if( !pNames->Insert( pName ) ) delete pName; } } /////////////////////////////////////////////////////////////////////////////// // // Retrieve the list of registered names // void SvXMLAutoStylePoolP_Impl::GetRegisteredNames( uno::Sequence& rFamilies, uno::Sequence& rNames ) { // collect registered names + families vector aFamilies; vector aNames; // iterate over families sal_uInt32 nCount = maFamilyList.Count(); for( sal_uInt32 i = 0; i < nCount; i++ ) { XMLFamilyData_Impl* pFamily = maFamilyList.GetObject( i ); // iterate over names SvXMLAutoStylePoolNamesP_Impl* pNames = pFamily->mpNameList; sal_uInt32 nNames = ( pNames != NULL ) ? pNames->Count() : 0; for( sal_uInt32 j = 0; j < nNames; j++ ) { aFamilies.push_back( pFamily->mnFamily ); aNames.push_back( *pNames->GetObject( j ) ); } } // copy the families + names into the sequence types DBG_ASSERT( aFamilies.size() == aNames.size(), "families != names" ); rFamilies.realloc( aFamilies.size() ); std::copy( aFamilies.begin(), aFamilies.end(), rFamilies.getArray() ); rNames.realloc( aNames.size() ); std::copy( aNames.begin(), aNames.end(), rNames.getArray() ); } /////////////////////////////////////////////////////////////////////////////// // // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list // if not added, yet. // /*OUString SvXMLAutoStylePoolP_Impl::Add( sal_Int32 nFamily, const OUString& rParent, const vector< XMLPropertyState >& rProperties, sal_Bool bCache )*/ sal_Bool SvXMLAutoStylePoolP_Impl::Add(OUString& rName, sal_Int32 nFamily, const OUString& rParent, const ::std::vector< XMLPropertyState >& rProperties, sal_Bool bCache) { sal_Bool bRet(sal_False); ULONG nPos; XMLFamilyData_Impl *pFamily = 0; XMLFamilyData_Impl aTemporary( nFamily ); if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) ) { pFamily = maFamilyList.GetObject( nPos ); } DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" ); if( pFamily ) { SvXMLAutoStylePoolParentP_Impl aTmp( rParent ); SvXMLAutoStylePoolParentP_Impl *pParent = 0; SvXMLAutoStylePoolParentsP_Impl *pParents = pFamily->mpParentList; if( pParents->Seek_Entry( &aTmp, &nPos ) ) { pParent = pParents->GetObject( nPos ); } else { pParent = new SvXMLAutoStylePoolParentP_Impl( rParent ); pParents->Insert( pParent ); } if( pParent->Add( pFamily, rProperties, rName ) ) { pFamily->mnCount++; bRet = sal_True; } if( bCache ) { if( !pFamily->pCache ) pFamily->pCache = new SvXMLAutoStylePoolCache_Impl( 256, 256 ); if( pFamily->pCache->Count() < MAX_CACHE_SIZE ) pFamily->pCache->Insert( new OUString( rName ), pFamily->pCache->Count() ); } } return bRet; } OUString SvXMLAutoStylePoolP_Impl::AddToCache( sal_Int32 nFamily, const OUString& rParent ) { ULONG nPos; XMLFamilyData_Impl *pFamily = 0; XMLFamilyData_Impl aTmp( nFamily ); if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) { pFamily = maFamilyList.GetObject( nPos ); } DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" ); if( pFamily ) { if( !pFamily->pCache ) pFamily->pCache = new SvXMLAutoStylePoolCache_Impl( 256, 256 ); if( pFamily->pCache->Count() < MAX_CACHE_SIZE ) pFamily->pCache->Insert( new OUString( rParent ), pFamily->pCache->Count() ); } return rParent; } /////////////////////////////////////////////////////////////////////////////// // // Search for a array of XMLPropertyState ( vector< XMLPropertyState > ) in list // OUString SvXMLAutoStylePoolP_Impl::Find( sal_Int32 nFamily, const OUString& rParent, const vector< XMLPropertyState >& rProperties ) const { OUString sName; ULONG nPos; XMLFamilyData_Impl aTemporary( nFamily ); XMLFamilyData_Impl *pFamily = 0; if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) ) { pFamily = maFamilyList.GetObject( nPos ); } DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Find: unknown family" ); if( pFamily ) { SvXMLAutoStylePoolParentP_Impl aTmp( rParent ); const SvXMLAutoStylePoolParentsP_Impl* pParents = pFamily->mpParentList; if( pParents->Seek_Entry( &aTmp, &nPos ) ) sName = pParents->GetObject( nPos )->Find( pFamily, rProperties ); } return sName; } OUString SvXMLAutoStylePoolP_Impl::FindAndRemoveCached( sal_Int32 nFamily ) const { OUString sName; ULONG nPos; XMLFamilyData_Impl aTmp( nFamily ); XMLFamilyData_Impl *pFamily = 0; if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) { pFamily = maFamilyList.GetObject( nPos ); } DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Find: unknown family" ); if( pFamily ) { DBG_ASSERT( pFamily->pCache, "family doesn't have a cache" ); // The cache may be empty already. This happens if it was filled // completly. if( pFamily->pCache && pFamily->pCache->Count() ) { OUString *pName = pFamily->pCache->Remove( 0UL ); sName = *pName; delete pName; } } return sName; } /////////////////////////////////////////////////////////////////////////////// // // export // void SvXMLAutoStylePoolP_Impl::exportXML( sal_Int32 nFamily, const uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > &, const SvXMLUnitConverter&, const SvXMLNamespaceMap&, const SvXMLAutoStylePoolP *pAntiImpl) const { sal_uInt32 nCount = 0; // Get list of parents for current family (nFamily) ULONG nPos; XMLFamilyData_Impl aTmp( nFamily ); XMLFamilyData_Impl *pFamily = 0; if( maFamilyList.Seek_Entry( &aTmp, &nPos ) ) { pFamily = maFamilyList.GetObject( nPos ); nCount = pFamily->mnCount; } DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::exportXML: unknown family" ); if( pFamily && nCount > 0 ) { ///////////////////////////////////////////////////////////////////////////////////// // create, initialize and fill helper-structure (SvXMLAutoStylePoolProperties_Impl) // wich contains a parent-name and a SvXMLAutoStylePoolProperties_Impl // const SvXMLAutoStylePoolParentsP_Impl *pParents = pFamily->mpParentList; SvXMLAutoStylePoolPExport_Impl* aExpStyles = new SvXMLAutoStylePoolPExport_Impl[nCount]; sal_uInt32 i; for( i=0; i < nCount; i++ ) { aExpStyles[i].mpParent = 0; aExpStyles[i].mpProperties = 0; } sal_uInt32 nParents = pParents->Count(); for( i=0; i < nParents; i++ ) { const SvXMLAutoStylePoolParentP_Impl* pParent = pParents->GetObject( i ); sal_uInt32 nProperties = pParent->GetPropertiesList().Count(); for( sal_uInt32 j=0; j < nProperties; j++ ) { const SvXMLAutoStylePoolPropertiesP_Impl *pProperties = pParent->GetPropertiesList().GetObject( j ); nPos = pProperties->GetPos(); DBG_ASSERT( nPos < nCount, "SvXMLAutoStylePool_Impl::exportXML: wrong position" ); if( nPos < nCount ) { DBG_ASSERT( !aExpStyles[nPos].mpProperties, "SvXMLAutoStylePool_Impl::exportXML: double position" ); aExpStyles[nPos].mpProperties = pProperties; aExpStyles[nPos].mpParent = &pParent->GetParent(); } } } ///////////////////////////////////////////////////////////////////////////////////// // // create string to export for each XML-style. That means for each property-list // OUString aStrFamilyName = pFamily->maStrFamilyName; for( i=0; iGetName() ); if( pFamily->bAsFamily ) { GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, aStrFamilyName ); } if( aExpStyles[i].mpParent->getLength() ) { GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME, GetExport().EncodeStyleName( *aExpStyles[i].mpParent ) ); } OUString sName; if( pFamily->bAsFamily ) sName = GetXMLToken(XML_STYLE); else sName = pFamily->maStrFamilyName; pAntiImpl->exportStyleAttributes( GetExport().GetAttrList(), nFamily, aExpStyles[i].mpProperties->GetProperties(), *pFamily->mxMapper.get() , GetExport().GetMM100UnitConverter(), GetExport().GetNamespaceMap() ); SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, sName, sal_True, sal_True ); sal_Int32 nStart(-1); sal_Int32 nEnd(-1); if (nFamily == XML_STYLE_FAMILY_PAGE_MASTER) { nStart = 0; sal_Int32 nIndex = 0; UniReference< XMLPropertySetMapper > aPropMapper = pFamily->mxMapper->getPropertySetMapper(); sal_Int16 nContextID; while(nIndex < aPropMapper->GetEntryCount() && nEnd == -1) { nContextID = aPropMapper->GetEntryContextId( nIndex ); if (nContextID && ((nContextID & CTF_PM_FLAGMASK) != XML_PM_CTF_START)) nEnd = nIndex; nIndex++; } if (nEnd == -1) nEnd = nIndex; } pFamily->mxMapper->exportXML( GetExport(), aExpStyles[i].mpProperties->GetProperties(), nStart, nEnd, XML_EXPORT_FLAG_IGN_WS ); pAntiImpl->exportStyleContent( GetExport().GetDocHandler(), nFamily, aExpStyles[i].mpProperties->GetProperties(), *pFamily->mxMapper.get(), GetExport().GetMM100UnitConverter(), GetExport().GetNamespaceMap() ); } } delete[] aExpStyles; } } void SvXMLAutoStylePoolP_Impl::ClearEntries() { for(sal_uInt32 a = 0L; a < maFamilyList.Count(); a++) maFamilyList[a]->ClearEntries(); }