/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #include #include #include #include #include "xmloff/xmlnmspe.hxx" #include #include "impastpl.hxx" #include #include #include #ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX #include #endif using namespace ::std; using ::rtl::OUString; using ::rtl::OUStringBuffer; 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() { for (;;) { XMLFamilyData_Impl* pData = maFamilyList.Remove( sal_uLong(0) ); if (pData == NULL) { break; } 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 sal_uLong nPos; sal_uInt16 nExportFlags = GetExport().getExportFlags(); sal_Bool bStylesOnly = (nExportFlags & EXPORT_STYLES) != 0 && (nExportFlags & EXPORT_CONTENT) == 0; OUString aPrefix( rStrPrefix ); if( bStylesOnly ) { aPrefix = OUString( 'M' ); aPrefix += rStrPrefix; } XMLFamilyData_Impl *pFamily = new XMLFamilyData_Impl( nFamily, rStrName, rMapper, aPrefix, 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; sal_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, bool bDontSeek ) { sal_Bool bRet(sal_False); sal_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, bDontSeek ) ) { 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; } sal_Bool SvXMLAutoStylePoolP_Impl::AddNamed(const OUString& rName, sal_Int32 nFamily, const OUString& rParent, const ::std::vector< XMLPropertyState >& rProperties ) { // get family and parent the same way as in Add() sal_Bool bRet(sal_False); sal_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->AddNamed( pFamily, rProperties, rName ) ) { pFamily->mnCount++; bRet = sal_True; } } return bRet; } OUString SvXMLAutoStylePoolP_Impl::AddToCache( sal_Int32 nFamily, const OUString& rParent ) { sal_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; sal_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; sal_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) sal_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) // which 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(); }