| /************************************************************** |
| * |
| * 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 <tools/debug.hxx> |
| #include <xmloff/xmlaustp.hxx> |
| #include <xmloff/xmltoken.hxx> |
| #include <xmloff/nmspmap.hxx> |
| #include "xmloff/xmlnmspe.hxx" |
| #include <xmloff/attrlist.hxx> |
| #include "impastpl.hxx" |
| #include <xmloff/xmlexppr.hxx> |
| #include <xmloff/xmlexp.hxx> |
| #include <xmloff/families.hxx> |
| #ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX |
| #include <xmloff/PageMasterStyleMap.hxx> |
| #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<sal_Int32>& rFamilies, |
| uno::Sequence<OUString>& rNames ) |
| { |
| // collect registered names + families |
| vector<sal_Int32> aFamilies; |
| vector<OUString> 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) |
| // 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; i<nCount; i++ ) |
| { |
| DBG_ASSERT( aExpStyles[i].mpProperties, |
| "SvXMLAutoStylePool_Impl::exportXML: empty position" ); |
| |
| if( aExpStyles[i].mpProperties ) |
| { |
| GetExport().AddAttribute( |
| XML_NAMESPACE_STYLE, XML_NAME, |
| aExpStyles[i].mpProperties->GetName() ); |
| |
| 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(); |
| } |