/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: styleexp.cxx,v $ * * $Revision: 1.21 $ * * last change: $Author: rt $ $Date: 2007-07-06 09:44:50 $ * * 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 * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef _SVSTDARR_STRINGSSORTDTOR_DECL #define _SVSTDARR_STRINGSSORTDTOR #include #endif #ifndef _XMLOFF_NMSPMAP_HXX #include #endif #ifndef _XMLOFF_XMLNMSPE_HXX #include "xmlnmspe.hxx" #endif #ifndef _XMLOFF_XMLTOKEN_HXX #include #endif #ifndef _XMLOFF_XMLITMAP_HXX //#include "xmlitmap.hxx" #endif #ifndef _XMLOFF_XMLUCONV_HXX #include #endif #ifndef _XMLOFF_XMLKYWD_HXX #include "xmlkywd.hxx" #endif #ifndef _XMLOFF_ATTRLIST_HXX #include #endif #ifndef _XMLOFF_PROPERTYSETMAPPER_HXX #include #endif #ifndef _XMLOFF_XMLEXPPR_HXX #include #endif #ifndef _COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_ #include #endif #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_ #include #endif #ifndef _COM_SUN_STAR_STYLE_XSTYLEFAMILIESSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_STYLE_XSTYLE_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_ #include #endif #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP #include #endif #ifndef _COM_SUN_STAR_TEXT_XCHAPTERNUMBERINGSUPPLIER_HPP_ #include #endif #ifndef _XMLOFF_XMLASTPLP_HXX #include #endif #ifndef _XMLOFF_STYLEEXP_HXX #include #endif #ifndef _XMLOFF_XMLEXP_HXX #include #endif #ifndef _XMLOFF_XMLEVENTEXPORT_HXX #include #endif using namespace ::rtl; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::style; using namespace ::com::sun::star::container; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::text; using namespace ::xmloff::token; using ::com::sun::star::document::XEventsSupplier; XMLStyleExport::XMLStyleExport( SvXMLExport& rExp, const ::rtl::OUString& rPoolStyleName, SvXMLAutoStylePoolP *pAutoStyleP ) : rExport( rExp ), sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ), sIsAutoUpdate( RTL_CONSTASCII_USTRINGPARAM( "IsAutoUpdate" ) ), sFollowStyle( RTL_CONSTASCII_USTRINGPARAM( "FollowStyle" ) ), sNumberingStyleName( RTL_CONSTASCII_USTRINGPARAM( "NumberingStyleName" ) ), sPoolStyleName( rPoolStyleName ), pAutoStylePool( pAutoStyleP ) { } XMLStyleExport::~XMLStyleExport() { } void XMLStyleExport::exportStyleAttributes( const Reference< XStyle >& ) { } void XMLStyleExport::exportStyleContent( const Reference< XStyle >& ) { } sal_Bool XMLStyleExport::exportStyle( const Reference< XStyle >& rStyle, const OUString& rXMLFamily, const UniReference < SvXMLExportPropertyMapper >& rPropMapper, const OUString* pPrefix ) { Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY ); Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); Any aAny; // Don't export styles that aren't existing really. This may be the // case for StarOffice Writer's pool styles. if( xPropSetInfo->hasPropertyByName( sIsPhysical ) ) { aAny = xPropSet->getPropertyValue( sIsPhysical ); if( !*(sal_Bool *)aAny.getValue() ) return sal_False; } // GetExport().CheckAttrList(); // style:name="..." OUString sName; if(pPrefix) sName = *pPrefix; sName += rStyle->getName(); sal_Bool bEncoded = sal_False; const OUString sEncodedStyleName(GetExport().EncodeStyleName( sName, &bEncoded )); GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, sEncodedStyleName ); if( bEncoded ) GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME, sName); // style:family="..." if( rXMLFamily.getLength() > 0 ) GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, rXMLFamily); // style:parent-style-name="..." OUString sParentString(rStyle->getParentStyle()); OUString sParent; if(sParentString.getLength()) { if(pPrefix) sParent = *pPrefix; sParent += sParentString; } else sParent = sPoolStyleName; if( sParent.getLength() ) GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME, GetExport().EncodeStyleName( sParent ) ); // style:next-style-name="..." (paragraph styles only) if( xPropSetInfo->hasPropertyByName( sFollowStyle ) ) { aAny = xPropSet->getPropertyValue( sFollowStyle ); OUString sNextName; aAny >>= sNextName; if( sName != sNextName ) { GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NEXT_STYLE_NAME, GetExport().EncodeStyleName( sNextName ) ); } } // style:auto-update="..." (SW only) if( xPropSetInfo->hasPropertyByName( sIsAutoUpdate ) ) { aAny = xPropSet->getPropertyValue( sIsAutoUpdate ); if( *(sal_Bool *)aAny.getValue() ) GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_AUTO_UPDATE, XML_TRUE ); } // style:list-style-name="..." (SW paragarph styles only) if( xPropSetInfo->hasPropertyByName( sNumberingStyleName ) ) { Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY ); if( PropertyState_DIRECT_VALUE == xPropState->getPropertyState( sNumberingStyleName ) ) { aAny = xPropSet->getPropertyValue( sNumberingStyleName ); if( aAny.hasValue() ) { OUString sListName; aAny >>= sListName; // --> OD 2006-09-21 #i69523# // An direct set empty list style has to be written. Otherwise, // this information is lost and causes an error, if the parent // style has a list style set. if ( !sListName.getLength() ) { GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_LIST_STYLE_NAME, sListName /* empty string */); } else { // --> OD 2006-09-27 #i69627# bool bSuppressListStyle( false ); { if ( !GetExport().writeOutlineStyleAsNormalListStyle() ) { Reference< XChapterNumberingSupplier > xCNSupplier (GetExport().GetModel(), UNO_QUERY); OUString sOutlineName; if (xCNSupplier.is()) { Reference< XIndexReplace > xNumRule ( xCNSupplier->getChapterNumberingRules() ); DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" ); if (xNumRule.is()) { Reference< XPropertySet > xNumRulePropSet (xNumRule, UNO_QUERY); xNumRulePropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Name")) ) >>= sOutlineName; bSuppressListStyle = ( sListName == sOutlineName ); } } } } if ( sListName.getLength() && !bSuppressListStyle ) // <-- { GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_LIST_STYLE_NAME, GetExport().EncodeStyleName( sListName ) ); } } // <-- } } } // style:pool-id="..." is not required any longer since we use // english style names only exportStyleAttributes( rStyle ); // TODO: style:help-file-name="..." and style:help-id="..." can neither // be modified by UI nor by API and that for, have not to be exported // currently. { // SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True ); SvXMLExportPropertyMapper2* pPropMapper2 = dynamic_cast< SvXMLExportPropertyMapper2* >( rPropMapper.get() ); if( pPropMapper2 ) pPropMapper2->SetStyleName( sEncodedStyleName ); // ::std::vector< XMLPropertyState > xPropStates = rPropMapper->Filter( xPropSet ); rPropMapper->exportXML( GetExport(), xPropStates, XML_EXPORT_FLAG_IGN_WS ); if( pPropMapper2 ) pPropMapper2->SetStyleName( OUString() ); exportStyleContent( rStyle ); // , if they are supported by this style Reference xEventsSupp(rStyle, UNO_QUERY); GetExport().GetEventExport().Export(xEventsSupp); } return sal_True; } sal_Bool XMLStyleExport::exportDefaultStyle( const Reference< XPropertySet >& xPropSet, const OUString& rXMLFamily, const UniReference < SvXMLExportPropertyMapper >& rPropMapper ) { Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); Any aAny; // GetExport().CheckAttrList(); { // style:family="..." if( rXMLFamily.getLength() > 0 ) GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, rXMLFamily ); // SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, XML_DEFAULT_STYLE, sal_True, sal_True ); // //::std::vector< XMLPropertyState > xPropStates = // rPropMapper->FilterDefaults( xPropSet ); ::std::vector< XMLPropertyState > xPropStates = rPropMapper->FilterDefaults( xPropSet ); rPropMapper->exportXML( GetExport(), xPropStates, XML_EXPORT_FLAG_IGN_WS ); // exportStyleContent( rStyle ); } return sal_True; } #if 0 void XMLStyleExport::exportStyleFamily( const sal_Char *pFamily, const OUString& rXMLFamily, const UniReference < XMLPropertySetMapper >& rPropMapper, sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix) { const OUString sFamily(OUString::createFromAscii(pFamily )); UniReference < SvXMLExportPropertyMapper > xExpPropMapper = new SvXMLExportPropertyMapper( rPropMapper ); exportStyleFamily( sFamily, rXMLFamily, xExpPropMapper, bUsed, nFamily, pPrefix); } void XMLStyleExport::exportStyleFamily( const OUString& rFamily, const OUString& rXMLFamily, const UniReference < XMLPropertySetMapper >& rPropMapper, sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix) { UniReference < SvXMLExportPropertyMapper > xExpPropMapper = new SvXMLExportPropertyMapper( rPropMapper ); exportStyleFamily( rFamily, rXMLFamily, xExpPropMapper, bUsed, nFamily, pPrefix); } #endif void XMLStyleExport::exportStyleFamily( const sal_Char *pFamily, const OUString& rXMLFamily, const UniReference < SvXMLExportPropertyMapper >& rPropMapper, sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix) { const OUString sFamily(OUString::createFromAscii(pFamily )); exportStyleFamily( sFamily, rXMLFamily, rPropMapper, bUsed, nFamily, pPrefix); } void XMLStyleExport::exportStyleFamily( const OUString& rFamily, const OUString& rXMLFamily, const UniReference < SvXMLExportPropertyMapper >& rPropMapper, sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix) { DBG_ASSERT( GetExport().GetModel().is(), "There is the model?" ); Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), UNO_QUERY ); Reference< XNameAccess > xStyleCont; Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() ); if( xFamilies->hasByName( rFamily ) ) xFamilies->getByName( rFamily ) >>= xStyleCont; if( !xStyleCont.is() ) return; Reference< XNameAccess > xStyles( xStyleCont, UNO_QUERY ); // If next styles are supported and used styles should be exported only, // the next style may be unused but has to be exported, too. In this case // the names of all exported styles are remembered. SvStringsSortDtor *pExportedStyles = 0; sal_Bool bFirstStyle = sal_True; const uno::Sequence< ::rtl::OUString> aSeq = xStyles->getElementNames(); const ::rtl::OUString* pIter = aSeq.getConstArray(); const ::rtl::OUString* pEnd = pIter + aSeq.getLength(); for(;pIter != pEnd;++pIter) { Reference< XStyle > xStyle; try { xStyles->getByName( *pIter ) >>= xStyle; } catch( lang::IndexOutOfBoundsException ) { // due to bugs in prior versions it is possible that // a binary file is missing some critical styles. // The only possible way to deal with this is to // not export them here and remain silent. continue; } DBG_ASSERT( xStyle.is(), "Style not found for export!" ); if( xStyle.is() ) { if( !bUsed || xStyle->isInUse() ) { BOOL bExported = exportStyle( xStyle, rXMLFamily, rPropMapper, pPrefix ); if( bUsed && bFirstStyle && bExported ) { // If this is the first style, find out wether next styles // are supported. Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY ); Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); if( xPropSetInfo->hasPropertyByName( sFollowStyle ) ) pExportedStyles = new SvStringsSortDtor; bFirstStyle = sal_False; } if( pExportedStyles && bExported ) { // If next styles are supported, remember this style's name. String *pTmp = new String( xStyle->getName() ); if( !pExportedStyles->Insert( pTmp ) ) delete pTmp; } } // if an auto style pool is given, remember this style's name as a // style name that must not be used by automatic styles. if( pAutoStylePool ) pAutoStylePool->RegisterName( nFamily, xStyle->getName() ); } } if( pExportedStyles ) { // if next styles are supported, export all next styles that are // unused and that for, haven't been exported in the first loop. pIter = aSeq.getConstArray(); for(;pIter != pEnd;++pIter) { Reference< XStyle > xStyle; xStyles->getByName( *pIter ) >>= xStyle; DBG_ASSERT( xStyle.is(), "Style not found for export!" ); if( xStyle.is() ) { Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY ); Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() ); // styles that aren't existing realy are ignored. if( xPropSetInfo->hasPropertyByName( sIsPhysical ) ) { Any aAny( xPropSet->getPropertyValue( sIsPhysical ) ); if( !*(sal_Bool *)aAny.getValue() ) continue; } if( !xStyle->isInUse() ) continue; if( !xPropSetInfo->hasPropertyByName( sFollowStyle ) ) { DBG_ASSERT( 0==sFollowStyle.getLength(), "no follow style???" ); continue; } OUString sNextName; xPropSet->getPropertyValue( sFollowStyle ) >>= sNextName; String sTmp( sNextName ); // if the next style hasn't been exported by now, export it now // and remember its name. if( xStyle->getName() != sNextName && !pExportedStyles->Seek_Entry( &sTmp ) ) { xStyleCont->getByName( sNextName ) >>= xStyle; DBG_ASSERT( xStyle.is(), "Style not found for export!" ); if( xStyle.is() && exportStyle( xStyle, rXMLFamily, rPropMapper, pPrefix ) ) pExportedStyles->Insert( new String( sTmp ) ); } } } } delete pExportedStyles; }