/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "XMLStarBasicExportHandler.hxx" #include "XMLScriptExportHandler.hxx" #include #include #include #include #include #include #include #include #include #include #include #include "XMLImageMapExport.hxx" #include "XMLBase64Export.hxx" #include #include #include #include #include #include #include "XMLBasicExportFilter.hxx" #include #include #include #include #include #include "PropertySetMerger.hxx" #include #include #include #include #include #include #include #include #include #include #include "RDFaExportHelper.hxx" #include using namespace ::osl; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::container; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::document; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::xml::sax; using namespace ::com::sun::star::io; using namespace ::xmloff::token; sal_Char const sXML_1_1[] = "1.1"; sal_Char const sXML_1_2[] = "1.2"; #define XML_MODEL_SERVICE_WRITER "com.sun.star.text.TextDocument" #define XML_MODEL_SERVICE_CALC "com.sun.star.sheet.SpreadsheetDocument" #define XML_MODEL_SERVICE_DRAW "com.sun.star.drawing.DrawingDocument" #define XML_MODEL_SERVICE_IMPRESS "com.sun.star.presentation.PresentationDocument" #define XML_MODEL_SERVICE_MATH "com.sun.star.formula.FormulaProperties" #define XML_MODEL_SERVICE_CHART "com.sun.star.chart.ChartDocument" #define XML_USEPRETTYPRINTING "UsePrettyPrinting" namespace { struct XMLServiceMapEntry_Impl { const sal_Char *sModelService; sal_Int32 nModelServiceLen; const sal_Char *sFilterService; sal_Int32 nFilterServiceLen; }; } #define SERVICE_MAP_ENTRY( app ) \ { XML_MODEL_SERVICE_##app, sizeof(XML_MODEL_SERVICE_##app)-1, \ XML_EXPORT_FILTER_##app, sizeof(XML_EXPORT_FILTER_##app)-1 } const XMLServiceMapEntry_Impl aServiceMap[] = { SERVICE_MAP_ENTRY( WRITER ), SERVICE_MAP_ENTRY( CALC ), SERVICE_MAP_ENTRY( IMPRESS ),// Impress supports DrawingDocument, too, so SERVICE_MAP_ENTRY( DRAW ), // it must appear before Draw SERVICE_MAP_ENTRY( MATH ), SERVICE_MAP_ENTRY( CHART ), { 0, 0, 0, 0 } }; class SettingsExportFacade : public ::xmloff::XMLSettingsExportContext { public: explicit SettingsExportFacade( SvXMLExport& i_rExport ) :m_rExport( i_rExport ) { } virtual ~SettingsExportFacade() { } virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const OUString& i_rValue ) override; virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ) override; virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const bool i_bIgnoreWhitespace ) override; virtual void EndElement( const bool i_bIgnoreWhitespace ) override; virtual void Characters( const OUString& i_rCharacters ) override; virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > GetComponentContext() const override; private: SvXMLExport& m_rExport; ::std::stack< OUString > m_aElements; }; void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const OUString& i_rValue ) { m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_rValue ); } void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ) { m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_eValue ); } void SettingsExportFacade::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const bool i_bIgnoreWhitespace ) { const OUString sElementName( m_rExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_CONFIG, GetXMLToken( i_eName ) ) ); m_rExport.StartElement( sElementName, i_bIgnoreWhitespace ); m_aElements.push( sElementName ); } void SettingsExportFacade::EndElement( const bool i_bIgnoreWhitespace ) { const OUString sElementName( m_aElements.top() ); m_rExport.EndElement( sElementName, i_bIgnoreWhitespace ); m_aElements.pop(); } void SettingsExportFacade::Characters( const OUString& i_rCharacters ) { m_rExport.GetDocHandler()->characters( i_rCharacters ); } Reference< XComponentContext > SettingsExportFacade::GetComponentContext() const { return m_rExport.getComponentContext(); } class SvXMLExportEventListener : public cppu::WeakImplHelper< com::sun::star::lang::XEventListener > { private: SvXMLExport* pExport; public: explicit SvXMLExportEventListener(SvXMLExport* pExport); virtual ~SvXMLExportEventListener(); // XEventListener virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) throw(::com::sun::star::uno::RuntimeException, std::exception) override; }; SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport* pTempExport) : pExport(pTempExport) { } SvXMLExportEventListener::~SvXMLExportEventListener() { } // XEventListener void SAL_CALL SvXMLExportEventListener::disposing( const lang::EventObject& ) throw(uno::RuntimeException, std::exception) { if (pExport) { pExport->DisposingModel(); pExport = NULL; } } class SvXMLExport_Impl { public: SvXMLExport_Impl(); ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper; uno::Reference< uri::XUriReferenceFactory > mxUriReferenceFactory; OUString msPackageURI; OUString msPackageURIScheme; // Written OpenDocument file format doesn't fit to the created text document (#i69627#) bool mbOutlineStyleAsNormalListStyle; bool mbSaveBackwardCompatibleODF; uno::Reference< embed::XStorage > mxTargetStorage; SvtSaveOptions maSaveOptions; /// relative path of stream in package, e.g. "someobject/content.xml" OUString mStreamPath; /// name of stream in package, e.g., "content.xml" OUString mStreamName; OUString maSrcShellID; OUString maDestShellID; /// stack of backed up namespace maps /// long: depth at which namespace map has been backed up into the stack ::std::stack< ::std::pair< SvXMLNamespaceMap *, long > > mNamespaceMaps; /// counts depth (number of open elements/start tags) long mDepth; ::std::unique_ptr< ::xmloff::RDFaExportHelper> mpRDFaHelper; bool mbExportTextNumberElement; bool mbNullDateInitialized; void SetSchemeOf( const OUString& rOrigFileName ) { sal_Int32 nSep = rOrigFileName.indexOf(':'); if( nSep != -1 ) msPackageURIScheme = rOrigFileName.copy( 0, nSep ); } }; SvXMLExport_Impl::SvXMLExport_Impl() // Written OpenDocument file format doesn't fit to the created text document (#i69627#) : mbOutlineStyleAsNormalListStyle( false ) ,mbSaveBackwardCompatibleODF( true ) ,mStreamName() ,mNamespaceMaps() ,mDepth(0) ,mpRDFaHelper() // lazy ,mbExportTextNumberElement( false ) ,mbNullDateInitialized( false ) { mxUriReferenceFactory = uri::UriReferenceFactory::create( comphelper::getProcessComponentContext() ); } void SvXMLExport::SetDocHandler( const uno::Reference< xml::sax::XDocumentHandler > &rHandler ) { mxHandler = rHandler; mxExtHandler = uno::Reference( mxHandler, UNO_QUERY ); } void SvXMLExport::_InitCtor() { // note: it is not necessary to add XML_NP_XML (it is declared implicitly) if( getExportFlags() & ~SvXMLExportFlags::OASIS ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_OFFICE), GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE ); mpNamespaceMap->Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO ); } if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_FO), GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO ); } if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::SETTINGS) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK ); } if( getExportFlags() & SvXMLExportFlags::SETTINGS ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_CONFIG), GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG ); } if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC ); mpNamespaceMap->Add( GetXMLToken(XML_NP_META), GetXMLToken(XML_N_META), XML_NAMESPACE_META ); } if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::FONTDECLS) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE ); } // namespaces for documents if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC ); mpNamespaceMap->Add( GetXMLToken(XML_NP_TEXT), GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT ); mpNamespaceMap->Add( GetXMLToken(XML_NP_DRAW), GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW ); mpNamespaceMap->Add( GetXMLToken(XML_NP_DR3D), GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D ); mpNamespaceMap->Add( GetXMLToken(XML_NP_SVG), GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG ); mpNamespaceMap->Add( GetXMLToken(XML_NP_CHART), GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART ); mpNamespaceMap->Add( GetXMLToken(XML_NP_RPT), GetXMLToken(XML_N_RPT), XML_NAMESPACE_REPORT ); mpNamespaceMap->Add( GetXMLToken(XML_NP_TABLE), GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE ); mpNamespaceMap->Add( GetXMLToken(XML_NP_NUMBER),GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER ); mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOW), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW ); mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOC), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC ); mpNamespaceMap->Add( GetXMLToken(XML_NP_OF), GetXMLToken(XML_N_OF), XML_NAMESPACE_OF ); if (getDefaultVersion() > SvtSaveOptions::ODFVER_012) { mpNamespaceMap->Add( GetXMLToken(XML_NP_TABLE_EXT), GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT); mpNamespaceMap->Add( GetXMLToken(XML_NP_CALC_EXT), GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT); mpNamespaceMap->Add( GetXMLToken(XML_NP_DRAW_EXT), GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT); mpNamespaceMap->Add( GetXMLToken(XML_NP_LO_EXT), GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT); mpNamespaceMap->Add( GetXMLToken(XML_NP_FIELD), GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD ); } } if( getExportFlags() & (SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_MATH), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH ); mpNamespaceMap->Add( GetXMLToken(XML_NP_FORM), GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM ); } if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_SCRIPT), GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT ); mpNamespaceMap->Add( GetXMLToken(XML_NP_DOM), GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM ); } if( getExportFlags() & SvXMLExportFlags::CONTENT ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_XFORMS_1_0), GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS ); mpNamespaceMap->Add( GetXMLToken(XML_NP_XSD), GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD ); mpNamespaceMap->Add( GetXMLToken(XML_NP_XSI), GetXMLToken(XML_N_XSI), XML_NAMESPACE_XSI ); mpNamespaceMap->Add( GetXMLToken(XML_NP_FORMX), GetXMLToken(XML_N_FORMX), XML_NAMESPACE_FORMX ); } // RDFa: needed for content and header/footer styles if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_XHTML), GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML ); } // GRDDL: to convert RDFa and meta.xml to RDF if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_GRDDL), GetXMLToken(XML_N_GRDDL), XML_NAMESPACE_GRDDL ); } // CSS Text Level 3 for distributed text justification. if ( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES) ) { mpNamespaceMap->Add( GetXMLToken(XML_NP_CSS3TEXT), GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT ); } mxAttrList = static_cast(mpAttrList); msGraphicObjectProtocol = "vnd.sun.star.GraphicObject:"; msEmbeddedObjectProtocol = "vnd.sun.star.EmbeddedObject:"; if (mxModel.is() && !mxEventListener.is()) { mxEventListener.set( new SvXMLExportEventListener(this)); mxModel->addEventListener(mxEventListener); } // Determine model type (#i51726#) _DetermineModelType(); // cl: but only if we do export to current oasis format, old openoffice format *must* always be compatible if( getExportFlags() & SvXMLExportFlags::OASIS ) { mpImpl->mbSaveBackwardCompatibleODF = officecfg::Office::Common::Save::Document:: SaveBackwardCompatibleODF::get( comphelper::getProcessComponentContext() ); } } // Shapes in Writer cannot be named via context menu (#i51726#) void SvXMLExport::_DetermineModelType() { meModelType = SvtModuleOptions::EFactory::UNKNOWN_FACTORY; if ( mxModel.is() ) { meModelType = SvtModuleOptions::ClassifyFactoryByModel( mxModel ); } } SvXMLExport::SvXMLExport( sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/, const uno::Reference< uno::XComponentContext >& xContext, OUString const & implementationName, const enum XMLTokenEnum eClass, SvXMLExportFlags nExportFlags ) : mpImpl( new SvXMLExport_Impl ), m_xContext(xContext), m_implementationName(implementationName), mpAttrList( new SvXMLAttributeList ), mpNamespaceMap( new SvXMLNamespaceMap ), mpUnitConv( new SvXMLUnitConverter( xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit) ), mpNumExport(0L), mpProgressBarHelper( NULL ), mpEventExport( NULL ), mpImageMapExport( NULL ), mpXMLErrors( NULL ), mbExtended( false ), meClass( eClass ), mnExportFlags( nExportFlags ), mnErrorFlags( SvXMLErrorFlags::NO ), msWS( GetXMLToken(XML_WS) ), mbSaveLinkedSections(true) { SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" ); _InitCtor(); } SvXMLExport::SvXMLExport( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext, OUString const & implementationName, const OUString &rFileName, sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/, const uno::Reference< xml::sax::XDocumentHandler > & rHandler) : mpImpl( new SvXMLExport_Impl ), m_xContext(xContext), m_implementationName(implementationName), mxHandler( rHandler ), mxExtHandler( rHandler, uno::UNO_QUERY ), mpAttrList( new SvXMLAttributeList ), msOrigFileName( rFileName ), mpNamespaceMap( new SvXMLNamespaceMap ), mpUnitConv( new SvXMLUnitConverter( xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit) ), mpNumExport(0L), mpProgressBarHelper( NULL ), mpEventExport( NULL ), mpImageMapExport( NULL ), mpXMLErrors( NULL ), mbExtended( false ), meClass( XML_TOKEN_INVALID ), mnExportFlags( SvXMLExportFlags::NONE ), mnErrorFlags( SvXMLErrorFlags::NO ), msWS( GetXMLToken(XML_WS) ), mbSaveLinkedSections(true) { SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" ); mpImpl->SetSchemeOf( msOrigFileName ); _InitCtor(); if (mxNumberFormatsSupplier.is()) mpNumExport = new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier); } SvXMLExport::SvXMLExport( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext, OUString const & implementationName, const OUString &rFileName, const uno::Reference< xml::sax::XDocumentHandler > & rHandler, const Reference< XModel >& rModel, FieldUnit const eDefaultFieldUnit) : mpImpl( new SvXMLExport_Impl ), m_xContext(xContext), m_implementationName(implementationName), mxModel( rModel ), mxHandler( rHandler ), mxExtHandler( rHandler, uno::UNO_QUERY ), mxNumberFormatsSupplier (rModel, uno::UNO_QUERY), mpAttrList( new SvXMLAttributeList ), msOrigFileName( rFileName ), mpNamespaceMap( new SvXMLNamespaceMap ), mpUnitConv( new SvXMLUnitConverter( xContext, util::MeasureUnit::MM_100TH, SvXMLUnitConverter::GetMeasureUnit(eDefaultFieldUnit)) ), mpNumExport(0L), mpProgressBarHelper( NULL ), mpEventExport( NULL ), mpImageMapExport( NULL ), mpXMLErrors( NULL ), mbExtended( false ), meClass( XML_TOKEN_INVALID ), mnExportFlags( SvXMLExportFlags::NONE ), mnErrorFlags( SvXMLErrorFlags::NO ), msWS( GetXMLToken(XML_WS) ), mbSaveLinkedSections(true) { SAL_WARN_IF(!xContext.is(), "xmloff.core", "got no service manager" ); mpImpl->SetSchemeOf( msOrigFileName ); _InitCtor(); if (mxNumberFormatsSupplier.is()) mpNumExport = new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier); } SvXMLExport::~SvXMLExport() { delete mpXMLErrors; delete mpImageMapExport; delete mpEventExport; delete mpNamespaceMap; delete mpUnitConv; if (mpProgressBarHelper || mpNumExport) { if (mxExportInfo.is()) { uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); if (xPropertySetInfo.is()) { if (mpProgressBarHelper) { OUString sProgressMax(XML_PROGRESSMAX); OUString sProgressCurrent(XML_PROGRESSCURRENT); OUString sRepeat(XML_PROGRESSREPEAT); if (xPropertySetInfo->hasPropertyByName(sProgressMax) && xPropertySetInfo->hasPropertyByName(sProgressCurrent)) { sal_Int32 nProgressMax(mpProgressBarHelper->GetReference()); sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue()); uno::Any aAny; aAny <<= nProgressMax; mxExportInfo->setPropertyValue(sProgressMax, aAny); aAny <<= nProgressCurrent; mxExportInfo->setPropertyValue(sProgressCurrent, aAny); } if (xPropertySetInfo->hasPropertyByName(sRepeat)) mxExportInfo->setPropertyValue(sRepeat, css::uno::makeAny(mpProgressBarHelper->GetRepeat())); } if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES))) { OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES); if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats)) { uno::Sequence aWasUsed; mpNumExport->GetWasUsed(aWasUsed); uno::Any aAny; aAny <<= aWasUsed; mxExportInfo->setPropertyValue(sWrittenNumberFormats, aAny); } } } } delete mpProgressBarHelper; delete mpNumExport; } if (mxEventListener.is() && mxModel.is()) mxModel->removeEventListener(mxEventListener); delete mpImpl; } // XExporter void SAL_CALL SvXMLExport::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc ) throw(lang::IllegalArgumentException, uno::RuntimeException, std::exception) { mxModel = uno::Reference< frame::XModel >::query( xDoc ); if( !mxModel.is() ) throw lang::IllegalArgumentException(); if (mxModel.is() && ! mxEventListener.is()) { mxEventListener.set( new SvXMLExportEventListener(this)); mxModel->addEventListener(mxEventListener); } if(!mxNumberFormatsSupplier.is() ) { mxNumberFormatsSupplier.set(mxModel, css::uno::UNO_QUERY); if(mxNumberFormatsSupplier.is() && mxHandler.is()) mpNumExport = new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier); } if (mxExportInfo.is()) { uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); if (xPropertySetInfo.is()) { OUString sUsePrettyPrinting(XML_USEPRETTYPRINTING); if (xPropertySetInfo->hasPropertyByName(sUsePrettyPrinting)) { uno::Any aAny = mxExportInfo->getPropertyValue(sUsePrettyPrinting); if (::cppu::any2bool(aAny)) mnExportFlags |= SvXMLExportFlags::PRETTY; else mnExportFlags &= ~SvXMLExportFlags::PRETTY; } if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES))) { OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES); if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats)) { uno::Any aAny = mxExportInfo->getPropertyValue(sWrittenNumberFormats); uno::Sequence aWasUsed; if(aAny >>= aWasUsed) mpNumExport->SetWasUsed(aWasUsed); } } } } if ( mpImpl->mbSaveBackwardCompatibleODF ) mnExportFlags |= SvXMLExportFlags::SAVEBACKWARDCOMPATIBLE; else mnExportFlags &= ~SvXMLExportFlags::SAVEBACKWARDCOMPATIBLE; // namespaces for user defined attributes Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY ); if( xFactory.is() ) { try { Reference < XInterface > xIfc = xFactory->createInstance("com.sun.star.xml.NamespaceMap"); if( xIfc.is() ) { Reference< XNameAccess > xNamespaceMap( xIfc, UNO_QUERY ); if( xNamespaceMap.is() ) { Sequence< OUString > aPrefixes( xNamespaceMap->getElementNames() ); OUString* pPrefix = aPrefixes.getArray(); const sal_Int32 nCount = aPrefixes.getLength(); sal_Int32 nIndex; OUString aURL; for( nIndex = 0; nIndex < nCount; ++nIndex, ++pPrefix ) { if( xNamespaceMap->getByName( *pPrefix ) >>= aURL ) _GetNamespaceMap().Add( *pPrefix, aURL ); } } } } catch(const com::sun::star::uno::Exception&) { } } // Determine model type (#i51726#) _DetermineModelType(); } // XInitialize void SAL_CALL SvXMLExport::initialize( const uno::Sequence< uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) { // #93186# we need to queryInterface every single Any with any expected outcome. This variable hold the queryInterface results. const sal_Int32 nAnyCount = aArguments.getLength(); const uno::Any* pAny = aArguments.getConstArray(); for( sal_Int32 nIndex = 0; nIndex < nAnyCount; nIndex++, pAny++ ) { Reference xValue; *pAny >>= xValue; // status indicator uno::Reference xTmpStatus( xValue, UNO_QUERY ); if ( xTmpStatus.is() ) mxStatusIndicator = xTmpStatus; // graphic resolver uno::Reference xTmpGraphic( xValue, UNO_QUERY ); if ( xTmpGraphic.is() ) mxGraphicResolver = xTmpGraphic; // object resolver uno::Reference xTmpObjectResolver( xValue, UNO_QUERY ); if ( xTmpObjectResolver.is() ) mxEmbeddedResolver = xTmpObjectResolver; // document handler uno::Reference xTmpDocHandler( xValue, UNO_QUERY ); if( xTmpDocHandler.is() ) { mxHandler = xTmpDocHandler; *pAny >>= mxExtHandler; if (mxNumberFormatsSupplier.is() && mpNumExport == NULL) mpNumExport = new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier); } // property set to transport data across uno::Reference xTmpPropertySet( xValue, UNO_QUERY ); if( xTmpPropertySet.is() ) mxExportInfo = xTmpPropertySet; } if( mxExportInfo.is() ) { uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); OUString sPropName( "BaseURI" ); if( xPropertySetInfo->hasPropertyByName(sPropName) ) { uno::Any aAny = mxExportInfo->getPropertyValue(sPropName); aAny >>= msOrigFileName; mpImpl->msPackageURI = msOrigFileName; mpImpl->SetSchemeOf( msOrigFileName ); } OUString sRelPath; sPropName = "StreamRelPath"; if( xPropertySetInfo->hasPropertyByName(sPropName) ) { uno::Any aAny = mxExportInfo->getPropertyValue(sPropName); aAny >>= sRelPath; } OUString sName; sPropName = "StreamName"; if( xPropertySetInfo->hasPropertyByName(sPropName) ) { uno::Any aAny = mxExportInfo->getPropertyValue(sPropName); aAny >>= sName; } if( !msOrigFileName.isEmpty() && !sName.isEmpty() ) { INetURLObject aBaseURL( msOrigFileName ); if( !sRelPath.isEmpty() ) aBaseURL.insertName( sRelPath ); aBaseURL.insertName( sName ); msOrigFileName = aBaseURL.GetMainURL(INetURLObject::DECODE_TO_IURI); } mpImpl->mStreamName = sName; // Note: may be empty (XSLT) // Written OpenDocument file format doesn't fit to the created text document (#i69627#) const OUString sOutlineStyleAsNormalListStyle( "OutlineStyleAsNormalListStyle" ); if( xPropertySetInfo->hasPropertyByName( sOutlineStyleAsNormalListStyle ) ) { uno::Any aAny = mxExportInfo->getPropertyValue( sOutlineStyleAsNormalListStyle ); aAny >>= (mpImpl->mbOutlineStyleAsNormalListStyle); } OUString sTargetStorage( "TargetStorage" ); if( xPropertySetInfo->hasPropertyByName( sTargetStorage ) ) mxExportInfo->getPropertyValue( sTargetStorage ) >>= mpImpl->mxTargetStorage; const OUString sExportTextNumberElement( "ExportTextNumberElement" ); if( xPropertySetInfo->hasPropertyByName( sExportTextNumberElement ) ) { uno::Any aAny = mxExportInfo->getPropertyValue( sExportTextNumberElement ); aAny >>= (mpImpl->mbExportTextNumberElement); } } } // XFilter sal_Bool SAL_CALL SvXMLExport::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor ) throw(uno::RuntimeException, std::exception) { // check for xHandler first... should have been supplied in initialize if( !mxHandler.is() ) return sal_False; try { const sal_Int32 nPropCount = aDescriptor.getLength(); const SvXMLExportFlags nTest = SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS; if( (mnExportFlags & nTest) == nTest && msOrigFileName.isEmpty() ) { // evaluate descriptor only for flat files and if a base URI // has not been provided already const beans::PropertyValue* pProps = aDescriptor.getConstArray(); for( sal_Int32 nIndex = 0; nIndex < nPropCount; nIndex++, pProps++ ) { const OUString& rPropName = pProps->Name; const Any& rValue = pProps->Value; if ( rPropName == "FileName" ) { if( !(rValue >>= msOrigFileName ) ) return sal_False; } else if ( rPropName == "FilterName" ) { if( !(rValue >>= msFilterName ) ) return sal_False; } } } const beans::PropertyValue* pProps = aDescriptor.getConstArray(); for (sal_Int32 nIndex = 0; nIndex < nPropCount; ++nIndex, ++pProps) { const OUString& rPropName = pProps->Name; const Any& rValue = pProps->Value; if (rPropName == "SourceShellID") { if (!(rValue >>= mpImpl->maSrcShellID)) return false; } else if (rPropName == "DestinationShellID") { if (!(rValue >>= mpImpl->maDestShellID)) return false; } } exportDoc( meClass ); } catch(const uno::Exception& e) { // We must catch exceptions, because according to the // API definition export must not throw one! css::uno::Any ex(cppu::getCaughtException()); SetError( XMLERROR_FLAG_ERROR | XMLERROR_FLAG_SEVERE | XMLERROR_API, Sequence(), ex.getValueTypeName() + ": \"" + e.Message + "\"", NULL ); } // return true only if no error occurred return (GetErrorFlags() & (SvXMLErrorFlags::DO_NOTHING|SvXMLErrorFlags::ERROR_OCCURRED)) == SvXMLErrorFlags::NO; } void SAL_CALL SvXMLExport::cancel() throw(uno::RuntimeException, std::exception) { // stop export Sequence aEmptySeq; SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq); } OUString SAL_CALL SvXMLExport::getName( ) throw (::com::sun::star::uno::RuntimeException, std::exception) { return msFilterName; } void SAL_CALL SvXMLExport::setName( const OUString& ) throw (::com::sun::star::uno::RuntimeException, std::exception) { // do nothing, because it is not possible to set the FilterName } // XServiceInfo OUString SAL_CALL SvXMLExport::getImplementationName( ) throw(uno::RuntimeException, std::exception) { return m_implementationName; } sal_Bool SAL_CALL SvXMLExport::supportsService( const OUString& rServiceName ) throw(uno::RuntimeException, std::exception) { return cppu::supportsService(this, rServiceName); } uno::Sequence< OUString > SAL_CALL SvXMLExport::getSupportedServiceNames( ) throw(uno::RuntimeException, std::exception) { uno::Sequence aSeq(2); aSeq[0] = "com.sun.star.document.ExportFilter"; aSeq[1] = "com.sun.star.xml.XMLExportFilter"; return aSeq; } OUString SvXMLExport::EnsureNamespace(OUString const & i_rNamespace, OUString const & i_rPreferredPrefix) { OUString sPrefix; sal_uInt16 nKey( _GetNamespaceMap().GetKeyByName( i_rNamespace ) ); if( XML_NAMESPACE_UNKNOWN == nKey ) { // There is no prefix for the namespace, so // we have to generate one and have to add it. sPrefix = i_rPreferredPrefix; nKey = _GetNamespaceMap().GetKeyByPrefix( sPrefix ); sal_Int32 n( 0 ); OUStringBuffer buf; while( nKey != USHRT_MAX ) { buf.append( i_rPreferredPrefix ); buf.append( ++n ); sPrefix = buf.makeStringAndClear(); nKey = _GetNamespaceMap().GetKeyByPrefix( sPrefix ); } if (mpImpl->mNamespaceMaps.empty() || (mpImpl->mNamespaceMaps.top().second != mpImpl->mDepth)) { // top was created for lower depth... need a new namespace map! mpImpl->mNamespaceMaps.push( ::std::make_pair(mpNamespaceMap, mpImpl->mDepth) ); mpNamespaceMap = new SvXMLNamespaceMap( *mpNamespaceMap ); } // add the namespace to the map and as attribute mpNamespaceMap->Add( sPrefix, i_rNamespace ); buf.append( GetXMLToken(XML_XMLNS) ); buf.append( ':' ); buf.append( sPrefix ); AddAttribute( buf.makeStringAndClear(), i_rNamespace ); } else { // If there is a prefix for the namespace, reuse that. sPrefix = _GetNamespaceMap().GetPrefixByKey( nKey ); } return sPrefix; } void SvXMLExport::AddAttributeASCII( sal_uInt16 nPrefixKey, const sal_Char *pName, const sal_Char *pValue ) { OUString sName( OUString::createFromAscii( pName ) ); OUString sValue( OUString::createFromAscii( pValue ) ); mpAttrList->AddAttribute( _GetNamespaceMap().GetQNameByKey( nPrefixKey, sName ), sValue ); } void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const sal_Char *pName, const OUString& rValue ) { OUString sName( OUString::createFromAscii( pName ) ); mpAttrList->AddAttribute( _GetNamespaceMap().GetQNameByKey( nPrefixKey, sName ), rValue ); } void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const OUString& rName, const OUString& rValue ) { mpAttrList->AddAttribute( _GetNamespaceMap().GetQNameByKey( nPrefixKey, rName ), rValue ); } void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, enum XMLTokenEnum eName, const OUString& rValue ) { mpAttrList->AddAttribute( _GetNamespaceMap().GetQNameByKey( nPrefixKey, GetXMLToken(eName) ), rValue ); } void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, enum XMLTokenEnum eName, enum XMLTokenEnum eValue) { mpAttrList->AddAttribute( _GetNamespaceMap().GetQNameByKey( nPrefixKey, GetXMLToken(eName) ), GetXMLToken(eValue) ); } void SvXMLExport::AddAttribute( const OUString& rQName, const OUString& rValue ) { mpAttrList->AddAttribute( rQName, rValue ); } void SvXMLExport::AddAttribute( const OUString& rQName, enum ::xmloff::token::XMLTokenEnum eValue ) { mpAttrList->AddAttribute( rQName, GetXMLToken(eValue) ); } void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc, const ::com::sun::star::lang::Locale& rLocale, bool bWriteEmpty, enum ::xmloff::token::XMLTokenEnum eClass ) { if (rLocale.Variant.isEmpty()) { // Per convention The BCP 47 string is always stored in Variant, if // that is empty we have a plain language-country combination, no need // to convert to LanguageTag first. Also catches the case of empty // locale denoting system locale. xmloff::token::XMLTokenEnum eLanguage, eCountry; switch (eClass) { default: case XML_LANGUAGE: eLanguage = XML_LANGUAGE; eCountry = XML_COUNTRY; break; case XML_LANGUAGE_ASIAN: eLanguage = XML_LANGUAGE_ASIAN; eCountry = XML_COUNTRY_ASIAN; if (nPrefix == XML_NAMESPACE_FO) nPrefix = XML_NAMESPACE_STYLE; break; case XML_LANGUAGE_COMPLEX: eLanguage = XML_LANGUAGE_COMPLEX; eCountry = XML_COUNTRY_COMPLEX; if (nPrefix == XML_NAMESPACE_FO) nPrefix = XML_NAMESPACE_STYLE; break; } if (bWriteEmpty || !rLocale.Language.isEmpty()) AddAttribute( nPrefix, eLanguage, rLocale.Language); if (bWriteEmpty || !rLocale.Country.isEmpty()) AddAttribute( nPrefix, eCountry, rLocale.Country); } else { LanguageTag aLanguageTag( rLocale); AddLanguageTagAttributes( nPrefix, nPrefixRfc, aLanguageTag, bWriteEmpty, eClass); } } void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc, const LanguageTag& rLanguageTag, bool bWriteEmpty, xmloff::token::XMLTokenEnum eClass ) { xmloff::token::XMLTokenEnum eLanguage, eScript, eCountry, eRfcLanguageTag; switch (eClass) { default: case XML_LANGUAGE: eLanguage = XML_LANGUAGE; eScript = XML_SCRIPT; eCountry = XML_COUNTRY; eRfcLanguageTag = XML_RFC_LANGUAGE_TAG; break; case XML_LANGUAGE_ASIAN: eLanguage = XML_LANGUAGE_ASIAN; eScript = XML_SCRIPT_ASIAN; eCountry = XML_COUNTRY_ASIAN; eRfcLanguageTag = XML_RFC_LANGUAGE_TAG_ASIAN; if (nPrefix == XML_NAMESPACE_FO) nPrefix = XML_NAMESPACE_STYLE; break; case XML_LANGUAGE_COMPLEX: eLanguage = XML_LANGUAGE_COMPLEX; eScript = XML_SCRIPT_COMPLEX; eCountry = XML_COUNTRY_COMPLEX; eRfcLanguageTag = XML_RFC_LANGUAGE_TAG_COMPLEX; if (nPrefix == XML_NAMESPACE_FO) nPrefix = XML_NAMESPACE_STYLE; break; } if (rLanguageTag.isIsoODF()) { if (bWriteEmpty || !rLanguageTag.isSystemLocale()) { AddAttribute( nPrefix, eLanguage, rLanguageTag.getLanguage()); if (rLanguageTag.hasScript() && getDefaultVersion() >= SvtSaveOptions::ODFVER_012) AddAttribute( nPrefix, eScript, rLanguageTag.getScript()); if (bWriteEmpty || !rLanguageTag.getCountry().isEmpty()) AddAttribute( nPrefix, eCountry, rLanguageTag.getCountry()); } } else { if (getDefaultVersion() >= SvtSaveOptions::ODFVER_012) AddAttribute( nPrefixRfc, eRfcLanguageTag, rLanguageTag.getBcp47()); // Also in case of non-pure-ISO tag store best matching fo: attributes // for consumers not handling *:rfc-language-tag, ensuring that only // valid ISO codes are stored. Here the bWriteEmpty parameter has no // meaning. OUString aLanguage, aScript, aCountry; rLanguageTag.getIsoLanguageScriptCountry( aLanguage, aScript, aCountry); if (!aLanguage.isEmpty()) { AddAttribute( nPrefix, eLanguage, aLanguage); if (!aScript.isEmpty() && getDefaultVersion() >= SvtSaveOptions::ODFVER_012) AddAttribute( nPrefix, eScript, aScript); if (!aCountry.isEmpty()) AddAttribute( nPrefix, eCountry, aCountry); } } } void SvXMLExport::AddAttributeList( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { if( xAttrList.is()) mpAttrList->AppendAttributeList( xAttrList ); } void SvXMLExport::ClearAttrList() { mpAttrList->Clear(); } #ifdef DBG_UTIL void SvXMLExport::CheckAttrList() { SAL_WARN_IF( mpAttrList->getLength(), "xmloff.core", "XMLExport::CheckAttrList: list is not empty" ); } #endif void SvXMLExport::ImplExportMeta() { CheckAttrList(); _ExportMeta(); } void SvXMLExport::ImplExportSettings() { CheckAttrList(); ::std::list< SettingsGroup > aSettings; sal_Int32 nSettingsCount = 0; // view settings uno::Sequence< beans::PropertyValue > aViewSettings; GetViewSettingsAndViews( aViewSettings ); aSettings.push_back( SettingsGroup( XML_VIEW_SETTINGS, aViewSettings ) ); nSettingsCount += aViewSettings.getLength(); // configuration settings uno::Sequence aConfigSettings; GetConfigurationSettings( aConfigSettings ); aSettings.push_back( SettingsGroup( XML_CONFIGURATION_SETTINGS, aConfigSettings ) ); nSettingsCount += aConfigSettings.getLength(); // any document specific settings nSettingsCount += GetDocumentSpecificSettings( aSettings ); { SvXMLElementExport aElem( *this, nSettingsCount != 0, XML_NAMESPACE_OFFICE, XML_SETTINGS, true, true ); SettingsExportFacade aSettingsExportContext( *this ); XMLSettingsExportHelper aSettingsExportHelper( aSettingsExportContext ); for ( ::std::list< SettingsGroup >::const_iterator settings = aSettings.begin(); settings != aSettings.end(); ++settings ) { if ( !settings->aSettings.getLength() ) continue; OUString sSettingsName( GetXMLToken( settings->eGroupName ) ); OUString sQName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OOO, sSettingsName ); aSettingsExportHelper.exportAllSettings( settings->aSettings, sQName ); } } } void SvXMLExport::ImplExportStyles( bool ) { CheckAttrList(); { // SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_STYLES, true, true ); _ExportStyles( false ); } // transfer style names (+ families) TO other components (if appropriate) if( ( !( mnExportFlags & SvXMLExportFlags::CONTENT ) ) && mxExportInfo.is() ) { static OUString sStyleNames( "StyleNames" ); static OUString sStyleFamilies( "StyleFamilies" ); uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); if ( xPropertySetInfo->hasPropertyByName( sStyleNames ) && xPropertySetInfo->hasPropertyByName( sStyleFamilies ) ) { Sequence aStyleFamilies; Sequence aStyleNames; mxAutoStylePool->GetRegisteredNames( aStyleFamilies, aStyleNames ); mxExportInfo->setPropertyValue( sStyleNames, makeAny( aStyleNames ) ); mxExportInfo->setPropertyValue( sStyleFamilies, makeAny( aStyleFamilies ) ); } } } void SvXMLExport::ImplExportAutoStyles( bool ) { // transfer style names (+ families) FROM other components (if appropriate) OUString sStyleNames( "StyleNames" ); OUString sStyleFamilies( "StyleFamilies" ); if( ( !( mnExportFlags & SvXMLExportFlags::STYLES ) ) && mxExportInfo.is() && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleNames ) && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleFamilies ) ) { Sequence aStyleFamilies; mxExportInfo->getPropertyValue( sStyleFamilies ) >>= aStyleFamilies; Sequence aStyleNames; mxExportInfo->getPropertyValue( sStyleNames ) >>= aStyleNames; mxAutoStylePool->RegisterNames( aStyleFamilies, aStyleNames ); } { // SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES, true, true ); _ExportAutoStyles(); } } void SvXMLExport::ImplExportMasterStyles( bool ) { { // SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_MASTER_STYLES, true, true ); _ExportMasterStyles(); } } void SvXMLExport::ImplExportContent() { CheckAttrList(); CheckAttrList(); { SvXMLElementExport aElemrnt( *this, XML_NAMESPACE_OFFICE, XML_BODY, true, true ); { XMLTokenEnum eClass = meClass; if( XML_TEXT_GLOBAL == eClass ) { AddAttribute( XML_NAMESPACE_TEXT, XML_GLOBAL, GetXMLToken( XML_TRUE ) ); eClass = XML_TEXT; } if ( XML_GRAPHICS == eClass ) eClass = XML_DRAWING; // SetBodyAttributes(); SvXMLElementExport aElem( *this, meClass != XML_TOKEN_INVALID, XML_NAMESPACE_OFFICE, eClass, true, true ); _ExportContent(); } } } void SvXMLExport::SetBodyAttributes() { } static void lcl_AddGrddl(SvXMLExport & rExport, const SvXMLExportFlags /*nExportMode*/) { // check version >= 1.2 switch (rExport.getDefaultVersion()) { case SvtSaveOptions::ODFVER_011: // fall through case SvtSaveOptions::ODFVER_010: return; default: break; } // #i115030#: disabled, the XSLT is not finished, and not available via HTTP #if 0 if (SvXMLExportFlags::SETTINGS != nExportMode) // meta, content, styles { rExport.AddAttribute( XML_NAMESPACE_GRDDL, XML_TRANSFORMATION, OUString("http://FIXME") ); } #endif } void SvXMLExport::addChaffWhenEncryptedStorage() { uno::Reference< embed::XEncryptionProtectedSource2 > xEncr(mpImpl->mxTargetStorage, uno::UNO_QUERY); if (xEncr.is() && xEncr->hasEncryptionData() && mxExtHandler.is()) { mxExtHandler->comment(OStringToOUString(comphelper::xml::makeXMLChaff(), RTL_TEXTENCODING_ASCII_US)); } } sal_uInt32 SvXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass ) { bool bOwnGraphicResolver = false; bool bOwnEmbeddedResolver = false; if( !mxGraphicResolver.is() || !mxEmbeddedResolver.is() ) { Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY ); if( xFactory.is() ) { try { if( !mxGraphicResolver.is() ) { mxGraphicResolver = Reference< XGraphicObjectResolver >::query( xFactory->createInstance( "com.sun.star.document.ExportGraphicObjectResolver" )); bOwnGraphicResolver = mxGraphicResolver.is(); } if( !mxEmbeddedResolver.is() ) { mxEmbeddedResolver = Reference< XEmbeddedObjectResolver >::query( xFactory->createInstance( "com.sun.star.document.ExportEmbeddedObjectResolver" )); bOwnEmbeddedResolver = mxEmbeddedResolver.is(); } } catch(const com::sun::star::uno::Exception&) { } } } if( (getExportFlags() & SvXMLExportFlags::OASIS) == SvXMLExportFlags::NONE ) { try { ::comphelper::PropertyMapEntry const aInfoMap[] = { { OUString("Class"), 0, ::cppu::UnoType::get(), PropertyAttribute::MAYBEVOID, 0}, { OUString(), 0, css::uno::Type(), 0, 0 } }; Reference< XPropertySet > xConvPropSet( ::comphelper::GenericPropertySet_CreateInstance( new ::comphelper::PropertySetInfo( aInfoMap ) ) ); Any aAny; aAny <<= GetXMLToken( eClass ); xConvPropSet->setPropertyValue( "Class", aAny ); Reference< XPropertySet > xPropSet = mxExportInfo.is() ? PropertySetMerger_CreateInstance( mxExportInfo, xConvPropSet ) : xConvPropSet; Sequence aArgs( 3 ); aArgs[0] <<= mxHandler; aArgs[1] <<= xPropSet; aArgs[2] <<= mxModel; // get filter component Reference< xml::sax::XDocumentHandler > xTmpDocHandler( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.comp.Oasis2OOoTransformer", aArgs, m_xContext), UNO_QUERY); SAL_WARN_IF(!xTmpDocHandler.is(), "xmloff.core", "can't instantiate OASIS transformer component" ); if( xTmpDocHandler.is() ) { mxHandler = xTmpDocHandler; mxExtHandler = uno::Reference( mxHandler, UNO_QUERY ); } } catch(const com::sun::star::uno::Exception&) { } } mxHandler->startDocument(); addChaffWhenEncryptedStorage(); // CheckAttrList(); // namespace attributes // ( The namespace decls should be first attributes in the element; // some faulty XML parsers (JAXP1.1) have a problem with this, // also it's more elegant ) sal_uInt16 nPos = mpNamespaceMap->GetFirstKey(); while( USHRT_MAX != nPos ) { mpAttrList->AddAttribute( mpNamespaceMap->GetAttrNameByKey( nPos ), mpNamespaceMap->GetNameByKey( nPos ) ); nPos = mpNamespaceMap->GetNextKey( nPos ); } // office:version = ... if( !mbExtended ) { const sal_Char* pVersion = 0; switch( getDefaultVersion() ) { case SvtSaveOptions::ODFVER_LATEST: pVersion = sXML_1_2; break; case SvtSaveOptions::ODFVER_012_EXT_COMPAT: pVersion = sXML_1_2; break; case SvtSaveOptions::ODFVER_012: pVersion = sXML_1_2; break; case SvtSaveOptions::ODFVER_011: pVersion = sXML_1_1; break; case SvtSaveOptions::ODFVER_010: break; default: SAL_WARN("xmloff.core", "xmloff::SvXMLExport::exportDoc(), unexpected odf default version!"); } if( pVersion ) AddAttribute( XML_NAMESPACE_OFFICE, XML_VERSION, OUString::createFromAscii(pVersion) ); } { enum XMLTokenEnum eRootService = XML_TOKEN_INVALID; const SvXMLExportFlags nExportMode = mnExportFlags & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS); lcl_AddGrddl(*this, nExportMode); if( SvXMLExportFlags::META == nExportMode ) { // export only meta eRootService = XML_DOCUMENT_META; } else if ( SvXMLExportFlags::SETTINGS == nExportMode ) { // export only settings eRootService = XML_DOCUMENT_SETTINGS; } else if( SvXMLExportFlags::STYLES == nExportMode ) { // export only styles eRootService = XML_DOCUMENT_STYLES; } else if( SvXMLExportFlags::CONTENT == nExportMode ) { // export only content eRootService = XML_DOCUMENT_CONTENT; } else { // the god'ol one4all element eRootService = XML_DOCUMENT; // office:mimetype = ... (only for stream containing the content) if( eClass != XML_TOKEN_INVALID ) { OUString aTmp( "application/vnd.oasis.opendocument." ); aTmp += GetXMLToken( eClass ); AddAttribute( XML_NAMESPACE_OFFICE, XML_MIMETYPE, aTmp ); } } SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, eRootService, true, true ); // meta information if( mnExportFlags & SvXMLExportFlags::META ) ImplExportMeta(); // settings if( mnExportFlags & SvXMLExportFlags::SETTINGS ) ImplExportSettings(); // scripts if( mnExportFlags & SvXMLExportFlags::SCRIPTS ) _ExportScripts(); // font declerations if( mnExportFlags & SvXMLExportFlags::FONTDECLS ) _ExportFontDecls(); // styles if( mnExportFlags & SvXMLExportFlags::STYLES ) ImplExportStyles( false ); // autostyles if( mnExportFlags & SvXMLExportFlags::AUTOSTYLES ) ImplExportAutoStyles( false ); // masterstyles if( mnExportFlags & SvXMLExportFlags::MASTERSTYLES ) ImplExportMasterStyles( false ); // content if( mnExportFlags & SvXMLExportFlags::CONTENT ) ImplExportContent(); } mxHandler->endDocument(); if( bOwnGraphicResolver ) { Reference< XComponent > xComp( mxGraphicResolver, UNO_QUERY ); xComp->dispose(); } if( bOwnEmbeddedResolver ) { Reference< XComponent > xComp( mxEmbeddedResolver, UNO_QUERY ); xComp->dispose(); } return 0; } void SvXMLExport::ResetNamespaceMap() { delete mpNamespaceMap; mpNamespaceMap = new SvXMLNamespaceMap; } OUString SvXMLExport::GetSourceShellID() const { return mpImpl->maSrcShellID; } OUString SvXMLExport::GetDestinationShellID() const { return mpImpl->maDestShellID; } void SvXMLExport::_ExportMeta() { OUString generator( ::utl::DocInfoHelper::GetGeneratorString() ); Reference< XDocumentPropertiesSupplier > xDocPropsSupplier(mxModel, UNO_QUERY); if (xDocPropsSupplier.is()) { Reference xDocProps( xDocPropsSupplier->getDocumentProperties()); if (!xDocProps.is()) throw; // update generator here xDocProps->setGenerator(generator); SvXMLMetaExport * pMeta = new SvXMLMetaExport(*this, xDocProps); uno::Reference xMeta(pMeta); pMeta->Export(); } else { // office:meta SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_META, true, true ); { // BM: #i60323# export generator even if xInfoProp is empty (which is the // case for charts). The generator does not depend on xInfoProp SvXMLElementExport anElem( *this, XML_NAMESPACE_META, XML_GENERATOR, true, true ); Characters(generator); } } } void SvXMLExport::_ExportScripts() { SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_SCRIPTS, true, true ); // export Basic macros (only for FlatXML) if ( mnExportFlags & SvXMLExportFlags::EMBEDDED ) { OUString aValue( GetNamespaceMap().GetPrefixByKey( XML_NAMESPACE_OOO ) ); aValue += ":Basic"; AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, aValue ); SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_SCRIPT, true, true ); // initialize Basic if ( mxModel.is() ) { Reference< beans::XPropertySet > xPSet( mxModel, UNO_QUERY ); if ( xPSet.is() ) xPSet->getPropertyValue("BasicLibraries"); } Reference < XDocumentHandler > xHdl( new XMLBasicExportFilter( mxHandler ) ); Reference< document::XXMLBasicExporter > xExporter = document::XMLOasisBasicExporter::createWithHandler( m_xContext, xHdl ); Reference< XComponent > xComp( mxModel, UNO_QUERY ); xExporter->setSourceDocument( xComp ); Sequence< PropertyValue > aMediaDesc( 0 ); xExporter->filter( aMediaDesc ); } // export document events Reference< document::XEventsSupplier > xEvents( GetModel(), UNO_QUERY ); GetEventExport().Export( xEvents ); } void SvXMLExport::_ExportFontDecls() { if( mxFontAutoStylePool.is() ) mxFontAutoStylePool->exportXML(); } void SvXMLExport::_ExportStyles( bool ) { uno::Reference< lang::XMultiServiceFactory > xFact( GetModel(), uno::UNO_QUERY ); if( xFact.is()) { // export (fill-)gradient-styles try { uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY ); if( xGradient.is() ) { XMLGradientStyleExport aGradientStyle( *this ); if( xGradient->hasElements() ) { uno::Sequence< OUString > aNamesSeq ( xGradient->getElementNames() ); sal_Int32 nCount = aNamesSeq.getLength(); for( sal_Int32 i=0; igetByName( rStrName ); aGradientStyle.exportXML( rStrName, aValue ); } catch(const container::NoSuchElementException&) { } } } } } catch(const lang::ServiceNotRegisteredException&) { } // export (fill-)hatch-styles try { uno::Reference< container::XNameAccess > xHatch( xFact->createInstance("com.sun.star.drawing.HatchTable"), uno::UNO_QUERY ); if( xHatch.is() ) { XMLHatchStyleExport aHatchStyle( *this ); if( xHatch->hasElements() ) { uno::Sequence< OUString > aNamesSeq ( xHatch->getElementNames() ); sal_Int32 nCount = aNamesSeq.getLength(); for( sal_Int32 i=0; igetByName( rStrName ); aHatchStyle.exportXML( rStrName, aValue ); } catch(const container::NoSuchElementException&) {} } } } } catch(const lang::ServiceNotRegisteredException&) { } // export (fill-)bitmap-styles try { uno::Reference< container::XNameAccess > xBitmap( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY ); if( xBitmap.is() ) { XMLImageStyle aImageStyle; if( xBitmap->hasElements() ) { uno::Sequence< OUString > aNamesSeq ( xBitmap->getElementNames() ); sal_Int32 nCount = aNamesSeq.getLength(); for( sal_Int32 i=0; igetByName( rStrName ); aImageStyle.exportXML( rStrName, aValue, *this ); } catch(const container::NoSuchElementException&) { } } } } } catch(const lang::ServiceNotRegisteredException&) { } // export transparency-gradient -styles try { uno::Reference< container::XNameAccess > xTransGradient( xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"), uno::UNO_QUERY ); if( xTransGradient.is() ) { XMLTransGradientStyleExport aTransGradientstyle( *this ); if( xTransGradient->hasElements() ) { uno::Sequence< OUString > aNamesSeq ( xTransGradient->getElementNames() ); sal_Int32 nCount = aNamesSeq.getLength(); for( sal_Int32 i=0; igetByName( rStrName ); aTransGradientstyle.exportXML( rStrName, aValue ); } catch(const container::NoSuchElementException&) { } } } } } catch(const lang::ServiceNotRegisteredException&) { } // export marker-styles try { uno::Reference< container::XNameAccess > xMarker( xFact->createInstance("com.sun.star.drawing.MarkerTable"), uno::UNO_QUERY ); if( xMarker.is() ) { XMLMarkerStyleExport aMarkerStyle( *this ); if( xMarker->hasElements() ) { uno::Sequence< OUString > aNamesSeq ( xMarker->getElementNames() ); sal_Int32 nCount = aNamesSeq.getLength(); for( sal_Int32 i=0; igetByName( rStrName ); aMarkerStyle.exportXML( rStrName, aValue ); } catch(const container::NoSuchElementException&) { } } } } } catch(const lang::ServiceNotRegisteredException&) { } // export dash-styles try { uno::Reference< container::XNameAccess > xDashes( xFact->createInstance("com.sun.star.drawing.DashTable"), uno::UNO_QUERY ); if( xDashes.is() ) { XMLDashStyleExport aDashStyle( *this ); if( xDashes->hasElements() ) { uno::Sequence< OUString > aNamesSeq ( xDashes->getElementNames() ); sal_Int32 nCount = aNamesSeq.getLength(); for( sal_Int32 i=0; igetByName( rStrName ); aDashStyle.exportXML( rStrName, aValue ); } catch(const container::NoSuchElementException&) { } } } } } catch(const lang::ServiceNotRegisteredException&) { } } } XMLTextParagraphExport* SvXMLExport::CreateTextParagraphExport() { return new XMLTextParagraphExport( *this, *(GetAutoStylePool().get()) ); } XMLShapeExport* SvXMLExport::CreateShapeExport() { return new XMLShapeExport(*this); } SvXMLAutoStylePoolP* SvXMLExport::CreateAutoStylePool() { return new SvXMLAutoStylePoolP(*this); } XMLPageExport* SvXMLExport::CreatePageExport() { return new XMLPageExport( *this ); } SchXMLExportHelper* SvXMLExport::CreateChartExport() { return new SchXMLExportHelper(*this,*GetAutoStylePool().get()); } XMLFontAutoStylePool* SvXMLExport::CreateFontAutoStylePool() { return new XMLFontAutoStylePool( *this ); } xmloff::OFormLayerXMLExport* SvXMLExport::CreateFormExport() { return new xmloff::OFormLayerXMLExport(*this); } void SvXMLExport::GetViewSettingsAndViews(uno::Sequence& rProps) { GetViewSettings(rProps); uno::Reference xViewDataSupplier(GetModel(), uno::UNO_QUERY); if(xViewDataSupplier.is()) { uno::Reference xIndexAccess; xViewDataSupplier->setViewData( xIndexAccess ); // make sure we get a newly created sequence xIndexAccess = xViewDataSupplier->getViewData(); bool bAdd = false; uno::Any aAny; if(xIndexAccess.is() && xIndexAccess->hasElements() ) { sal_Int32 nCount = xIndexAccess->getCount(); for (sal_Int32 i = 0; i < nCount; i++) { aAny = xIndexAccess->getByIndex(i); uno::Sequence aProps; if( aAny >>= aProps ) { if( aProps.getLength() > 0 ) { bAdd = true; break; } } } } if( bAdd ) { sal_Int32 nOldLength(rProps.getLength()); rProps.realloc(nOldLength + 1); beans::PropertyValue aProp; aProp.Name = "Views"; aProp.Value <<= xIndexAccess; rProps[nOldLength] = aProp; } } } void SvXMLExport::GetViewSettings(uno::Sequence&) { } void SvXMLExport::GetConfigurationSettings(uno::Sequence&) { } sal_Int32 SvXMLExport::GetDocumentSpecificSettings( ::std::list< SettingsGroup >& _out_rSettings ) { (void)_out_rSettings; return 0; } void SvXMLExport::addDataStyle(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ ) { if(mpNumExport) mpNumExport->SetUsed(nNumberFormat); } void SvXMLExport::exportDataStyles() { if(mpNumExport) mpNumExport->Export(false); } void SvXMLExport::exportAutoDataStyles() { if(mpNumExport) mpNumExport->Export(true); if (mxFormExport.is()) mxFormExport->exportAutoControlNumberStyles(); } OUString SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ ) const { OUString sTemp; if(mpNumExport) sTemp = mpNumExport->GetStyleName(nNumberFormat); return sTemp; } void SvXMLExport::exportAnnotationMeta(const uno::Reference&) { } sal_Int32 SvXMLExport::dataStyleForceSystemLanguage(sal_Int32 nFormat) const { return ( mpNumExport != NULL ) ? mpNumExport->ForceSystemLanguage( nFormat ) : nFormat; } OUString SvXMLExport::AddEmbeddedGraphicObject( const OUString& rGraphicObjectURL ) { OUString sRet( rGraphicObjectURL ); if( rGraphicObjectURL.startsWith( msGraphicObjectProtocol ) && mxGraphicResolver.is() ) { if( !(getExportFlags() & SvXMLExportFlags::EMBEDDED) ) sRet = mxGraphicResolver->resolveGraphicObjectURL( rGraphicObjectURL ); else sRet.clear(); } else sRet = GetRelativeReference( sRet ); return sRet; } bool SvXMLExport::AddEmbeddedGraphicObjectAsBase64( const OUString& rGraphicObjectURL ) { bool bRet = false; if( (getExportFlags() & SvXMLExportFlags::EMBEDDED) && rGraphicObjectURL.startsWith( msGraphicObjectProtocol ) && mxGraphicResolver.is() ) { Reference< XBinaryStreamResolver > xStmResolver( mxGraphicResolver, UNO_QUERY ); if( xStmResolver.is() ) { Reference< XInputStream > xIn( xStmResolver->getInputStream( rGraphicObjectURL ) ); if( xIn.is() ) { XMLBase64Export aBase64Exp( *this ); bRet = aBase64Exp.exportOfficeBinaryDataElement( xIn ); } } } return bRet; } OUString SvXMLExport::AddEmbeddedObject( const OUString& rEmbeddedObjectURL ) { OUString sRet; if( (rEmbeddedObjectURL.startsWith( msEmbeddedObjectProtocol ) || rEmbeddedObjectURL.startsWith( msGraphicObjectProtocol ) ) && mxEmbeddedResolver.is() ) { sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( rEmbeddedObjectURL ); } else sRet = GetRelativeReference( rEmbeddedObjectURL ); return sRet; } bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString& rEmbeddedObjectURL ) { bool bRet = false; if( (rEmbeddedObjectURL.startsWith( msEmbeddedObjectProtocol ) || rEmbeddedObjectURL.startsWith( msGraphicObjectProtocol ) ) && mxEmbeddedResolver.is() ) { Reference < XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY ); if( xNA.is() ) { Any aAny = xNA->getByName( rEmbeddedObjectURL ); Reference < XInputStream > xIn; aAny >>= xIn; if( xIn.is() ) { XMLBase64Export aBase64Exp( *this ); bRet = aBase64Exp.exportOfficeBinaryDataElement( xIn ); } } } return bRet; } OUString SvXMLExport::EncodeStyleName( const OUString& rName, bool *pEncoded ) const { return GetMM100UnitConverter().encodeStyleName( rName, pEncoded ); } ProgressBarHelper* SvXMLExport::GetProgressBarHelper() { if (!mpProgressBarHelper) { mpProgressBarHelper = new ProgressBarHelper(mxStatusIndicator, true); if (mxExportInfo.is()) { uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); if (xPropertySetInfo.is()) { OUString sProgressRange(XML_PROGRESSRANGE); OUString sProgressMax(XML_PROGRESSMAX); OUString sProgressCurrent(XML_PROGRESSCURRENT); OUString sRepeat(XML_PROGRESSREPEAT); if (xPropertySetInfo->hasPropertyByName(sProgressMax) && xPropertySetInfo->hasPropertyByName(sProgressCurrent) && xPropertySetInfo->hasPropertyByName(sProgressRange)) { uno::Any aAny; sal_Int32 nProgressMax(0); sal_Int32 nProgressCurrent(0); sal_Int32 nProgressRange(0); aAny = mxExportInfo->getPropertyValue(sProgressRange); if (aAny >>= nProgressRange) mpProgressBarHelper->SetRange(nProgressRange); aAny = mxExportInfo->getPropertyValue(sProgressMax); if (aAny >>= nProgressMax) mpProgressBarHelper->SetReference(nProgressMax); aAny = mxExportInfo->getPropertyValue(sProgressCurrent); if (aAny >>= nProgressCurrent) mpProgressBarHelper->SetValue(nProgressCurrent); } if (xPropertySetInfo->hasPropertyByName(sRepeat)) { uno::Any aAny = mxExportInfo->getPropertyValue(sRepeat); if (aAny.getValueType() == cppu::UnoType::get()) mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny)); else { SAL_WARN("xmloff.core", "why is it no boolean?" ); } } } } } return mpProgressBarHelper; } XMLEventExport& SvXMLExport::GetEventExport() { if( NULL == mpEventExport) { // create EventExport on demand mpEventExport = new XMLEventExport(*this, NULL); // and register standard handlers + names OUString sStarBasic("StarBasic"); mpEventExport->AddHandler(sStarBasic, new XMLStarBasicExportHandler()); OUString sScript("Script"); mpEventExport->AddHandler(sScript, new XMLScriptExportHandler()); mpEventExport->AddTranslationTable(aStandardEventTable); } return *mpEventExport; } XMLImageMapExport& SvXMLExport::GetImageMapExport() { // image map export, create on-demand if( NULL == mpImageMapExport ) { mpImageMapExport = new XMLImageMapExport(*this); } return *mpImageMapExport; } namespace { class theSvXMLExportUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvXMLExportUnoTunnelId> {}; } // XUnoTunnel & co const uno::Sequence< sal_Int8 > & SvXMLExport::getUnoTunnelId() throw() { return theSvXMLExportUnoTunnelId::get().getSeq(); } SvXMLExport* SvXMLExport::getImplementation( uno::Reference< uno::XInterface > xInt ) throw() { uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY ); if( xUT.is() ) { return reinterpret_cast( sal::static_int_cast( xUT->getSomething( SvXMLExport::getUnoTunnelId()))); } else return NULL; } // XUnoTunnel sal_Int64 SAL_CALL SvXMLExport::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw( uno::RuntimeException, std::exception ) { if( rId.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) { return sal::static_int_cast(reinterpret_cast(this)); } return 0; } bool SvXMLExport::ExportEmbeddedOwnObject( Reference< XComponent >& rComp ) { OUString sFilterService; Reference < lang::XServiceInfo > xServiceInfo( rComp, UNO_QUERY ); if( xServiceInfo.is() ) { const XMLServiceMapEntry_Impl *pEntry = aServiceMap; while( pEntry->sModelService ) { OUString sModelService( pEntry->sModelService, pEntry->nModelServiceLen, RTL_TEXTENCODING_ASCII_US ); if( xServiceInfo->supportsService( sModelService ) ) { sFilterService = OUString( pEntry->sFilterService, pEntry->nFilterServiceLen, RTL_TEXTENCODING_ASCII_US ); break; } pEntry++; } } SAL_WARN_IF( !sFilterService.getLength(), "xmloff.core", "no export filter for own object" ); if( sFilterService.isEmpty() ) return false; Reference < XDocumentHandler > xHdl = new XMLEmbeddedObjectExportFilter( mxHandler ); Sequence < Any > aArgs( 1 ); aArgs[0] <<= xHdl; Reference< document::XExporter > xExporter( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService, aArgs, m_xContext), UNO_QUERY); SAL_WARN_IF( !xExporter.is(), "xmloff.core", "can't instantiate export filter component for own object" ); if( !xExporter.is() ) return false; xExporter->setSourceDocument( rComp ); Reference xFilter( xExporter, UNO_QUERY ); Sequence < PropertyValue > aMediaDesc( 0 ); return xFilter->filter( aMediaDesc ); } OUString SvXMLExport::GetRelativeReference(const OUString& rValue) { OUString sValue( rValue ); // #i65474# handling of fragment URLs ("#....") is undefined // they are stored 'as is' uno::Reference< uri::XUriReference > xUriRef; if(!sValue.isEmpty() && sValue[0] != '#') { try { xUriRef = mpImpl->mxUriReferenceFactory->parse( rValue ); if( xUriRef.is() && !xUriRef->isAbsolute() ) { //#i61943# relative URLs need special handling INetURLObject aTemp( mpImpl->msPackageURI ); bool bWasAbsolute = false; sValue = aTemp.smartRel2Abs(sValue, bWasAbsolute ).GetMainURL(INetURLObject::DECODE_TO_IURI); } } catch(const uno::Exception&) { } } if( xUriRef.is() )//no conversion for empty values or for fragments { //conversion for matching schemes only if( xUriRef->getScheme() == mpImpl->msPackageURIScheme ) { sValue = INetURLObject::GetRelURL( msOrigFileName, sValue ); } } return sValue; } void SvXMLExport::StartElement(sal_uInt16 nPrefix, enum ::xmloff::token::XMLTokenEnum eName, bool bIgnWSOutside ) { StartElement(_GetNamespaceMap().GetQNameByKey( nPrefix, GetXMLToken(eName) ), bIgnWSOutside); } void SvXMLExport::StartElement(const OUString& rName, bool bIgnWSOutside ) { if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) { try { if( bIgnWSOutside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY)) mxHandler->ignorableWhitespace( msWS ); mxHandler->startElement( rName, GetXAttrList() ); } catch (const SAXInvalidCharacterException& e) { Sequence aPars(1); aPars[0] = rName; SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, NULL ); } catch (const SAXException& e) { Sequence aPars(1); aPars[0] = rName; SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, aPars, e.Message, NULL ); } } ClearAttrList(); ++mpImpl->mDepth; // increment nesting depth counter } void SvXMLExport::Characters(const OUString& rChars) { if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) { try { mxHandler->characters(rChars); } catch (const SAXInvalidCharacterException& e) { Sequence aPars(1); aPars[0] = rChars; SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, NULL ); } catch (const SAXException& e) { Sequence aPars(1); aPars[0] = rChars; SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, aPars, e.Message, NULL ); } } } void SvXMLExport::EndElement(sal_uInt16 nPrefix, enum ::xmloff::token::XMLTokenEnum eName, bool bIgnWSInside ) { EndElement(_GetNamespaceMap().GetQNameByKey( nPrefix, GetXMLToken(eName) ), bIgnWSInside); } void SvXMLExport::EndElement(const OUString& rName, bool bIgnWSInside ) { // decrement nesting depth counter & (maybe) restore namespace map --mpImpl->mDepth; if (!mpImpl->mNamespaceMaps.empty() && (mpImpl->mNamespaceMaps.top().second == mpImpl->mDepth)) { delete mpNamespaceMap; mpNamespaceMap = mpImpl->mNamespaceMaps.top().first; mpImpl->mNamespaceMaps.pop(); } SAL_WARN_IF(!mpImpl->mNamespaceMaps.empty() && (mpImpl->mNamespaceMaps.top().second >= mpImpl->mDepth), "xmloff.core", "SvXMLExport: NamespaceMaps corrupted"); if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) { try { if( bIgnWSInside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY)) mxHandler->ignorableWhitespace( msWS ); mxHandler->endElement( rName ); } catch (const SAXException& e) { Sequence aPars(1); aPars[0] = rName; SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, aPars, e.Message, NULL ); } } } void SvXMLExport::IgnorableWhitespace() { if ((mnExportFlags & SvXMLExportFlags::PRETTY) != SvXMLExportFlags::PRETTY) return; if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) { try { mxHandler->ignorableWhitespace( msWS ); } catch (const SAXException& e) { Sequence aPars(0); SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, aPars, e.Message, NULL ); } } } void SvXMLExport::SetError( sal_Int32 nId, const Sequence& rMsgParams, const OUString& rExceptionMessage, const Reference& rLocator ) { // allow multi-threaded access to the cancel() method static osl::Mutex aMutex; osl::MutexGuard aGuard(aMutex); // maintain error flags if ( ( nId & XMLERROR_FLAG_ERROR ) != 0 ) mnErrorFlags |= SvXMLErrorFlags::ERROR_OCCURRED; if ( ( nId & XMLERROR_FLAG_WARNING ) != 0 ) mnErrorFlags |= SvXMLErrorFlags::WARNING_OCCURRED; if ( ( nId & XMLERROR_FLAG_SEVERE ) != 0 ) mnErrorFlags |= SvXMLErrorFlags::DO_NOTHING; // create error list on demand if ( mpXMLErrors == NULL ) mpXMLErrors = new XMLErrors(); // save error information mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage, rLocator ); } void SvXMLExport::SetError( sal_Int32 nId, const Sequence& rMsgParams) { SetError( nId, rMsgParams, "", NULL ); } void SvXMLExport::DisposingModel() { mxModel.clear(); // Shapes in Writer cannot be named via context menu (#i51726#) meModelType = SvtModuleOptions::EFactory::UNKNOWN_FACTORY; mxEventListener.clear(); } ::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLExport::getInterfaceToIdentifierMapper() { return mpImpl->maInterfaceToIdentifierMapper; } // Written OpenDocument file format doesn't fit to the created text document (#i69627#) bool SvXMLExport::writeOutlineStyleAsNormalListStyle() const { return mpImpl->mbOutlineStyleAsNormalListStyle; } uno::Reference< embed::XStorage > SvXMLExport::GetTargetStorage() { return mpImpl->mxTargetStorage; } /// returns the currently configured default version for ODF export SvtSaveOptions::ODFDefaultVersion SvXMLExport::getDefaultVersion() const { if( mpImpl ) return mpImpl->maSaveOptions.GetODFDefaultVersion(); // fatal error, use current version as default return SvtSaveOptions::ODFVER_012; } SvtSaveOptions::ODFSaneDefaultVersion SvXMLExport::getSaneDefaultVersion() const { if( mpImpl ) return mpImpl->maSaveOptions.GetODFSaneDefaultVersion(); // fatal error, use current version as default return SvtSaveOptions::ODFSVER_012; } OUString SvXMLExport::GetStreamName() const { return mpImpl->mStreamName; } void SvXMLExport::AddAttributeIdLegacy( sal_uInt16 const nLegacyPrefix, OUString const& rValue) { switch (getDefaultVersion()) { case SvtSaveOptions::ODFVER_011: // fall through case SvtSaveOptions::ODFVER_010: break; default: // ODF 1.2: xml:id AddAttribute(XML_NAMESPACE_XML, XML_ID, rValue); } // in ODF 1.1 this was form:id, anim:id, draw:id, or text:id // backward compatibility: in ODF 1.2 write _both_ id attrs AddAttribute(nLegacyPrefix, XML_ID, rValue); // FIXME: this function simply assumes that rValue is unique } void SvXMLExport::AddAttributeXmlId(uno::Reference const & i_xIfc) { // check version >= 1.2 switch (getDefaultVersion()) { case SvtSaveOptions::ODFVER_011: // fall through case SvtSaveOptions::ODFVER_010: return; default: break; } const uno::Reference xMeta(i_xIfc, uno::UNO_QUERY); //FIXME not yet... if ( xMeta.is() ) { const beans::StringPair mdref( xMeta->getMetadataReference() ); if ( !mdref.Second.isEmpty() ) { const OUString streamName( GetStreamName() ); if ( !streamName.isEmpty() ) { if ( streamName.equals(mdref.First) ) { AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second ); } else { SAL_WARN("xmloff.core","SvXMLExport::AddAttributeXmlId: invalid stream name"); } } else { // FIXME: this is ugly // there is no stream name (e.g. XSLT, flat-xml format)! // but how do we ensure uniqueness in this case? // a) just omit styles.xml ids -- they are unlikely anyway... // b) somehow find out whether we are currently exporting styles // or content, and prefix "s" or "c" => unique if ( mdref.First == "content.xml" ) { AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second ); } else { SAL_INFO("xmloff.core", "SvXMLExport::AddAttributeXmlId: no stream name given: dropping styles.xml xml:id"); } } } } } void SvXMLExport::AddAttributesRDFa( uno::Reference const & i_xTextContent) { // check version >= 1.2 switch (getDefaultVersion()) { case SvtSaveOptions::ODFVER_011: // fall through case SvtSaveOptions::ODFVER_010: return; default: break; } const uno::Reference xMeta( i_xTextContent, uno::UNO_QUERY); if (!xMeta.is() || xMeta->getMetadataReference().Second.isEmpty()) { return; // no xml:id => no RDFa } if (!mpImpl->mpRDFaHelper.get()) { mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaExportHelper(*this) ); } mpImpl->mpRDFaHelper->AddRDFa(xMeta); } bool SvXMLExport::exportTextNumberElement() const { return mpImpl->mbExportTextNumberElement; } bool SvXMLExport::SetNullDateOnUnitConverter() { // if the null date has already been set, don't set it again (performance) if (!mpImpl->mbNullDateInitialized) mpImpl->mbNullDateInitialized = GetMM100UnitConverter().setNullDate(GetModel()); return mpImpl->mbNullDateInitialized; } void SvXMLElementExport::StartElement( const sal_uInt16 nPrefixKey, const OUString& rLName, const bool bIgnoreWhitespaceOutside ) { maElementName = mrExport.GetNamespaceMap().GetQNameByKey(nPrefixKey, rLName); mrExport.StartElement(maElementName, bIgnoreWhitespaceOutside); } SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp, sal_uInt16 nPrefixKey, const sal_Char *pLName, bool bIWSOutside, bool bIWSInside ) : mrExport( rExp ) , maElementName() , mbIgnoreWhitespaceInside( bIWSInside ) , mbDoSomething( true ) { const OUString sLName( OUString::createFromAscii( pLName ) ); StartElement( nPrefixKey, sLName, bIWSOutside ); } SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp, sal_uInt16 nPrefixKey, const OUString& rLName, bool bIWSOutside, bool bIWSInside ) : mrExport( rExp ) , maElementName() , mbIgnoreWhitespaceInside( bIWSInside ) , mbDoSomething( true ) { StartElement( nPrefixKey, rLName, bIWSOutside ); } SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp, sal_uInt16 nPrefixKey, enum XMLTokenEnum eLName, bool bIWSOutside, bool bIWSInside ) : mrExport( rExp ) , maElementName() , mbIgnoreWhitespaceInside( bIWSInside ) , mbDoSomething( true ) { StartElement( nPrefixKey, GetXMLToken(eLName), bIWSOutside ); } SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp, bool bDoSth, sal_uInt16 nPrefixKey, enum XMLTokenEnum eLName, bool bIWSOutside, bool bIWSInside ) : mrExport( rExp ) , maElementName() , mbIgnoreWhitespaceInside( bIWSInside ) , mbDoSomething( bDoSth ) { if ( mbDoSomething ) StartElement( nPrefixKey, GetXMLToken( eLName ), bIWSOutside ); } SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp, const OUString& rQName, bool bIWSOutside, bool bIWSInside ) : mrExport( rExp ) , maElementName() , mbIgnoreWhitespaceInside( bIWSInside ) , mbDoSomething( true ) { maElementName = rQName; rExp.StartElement( rQName, bIWSOutside ); } SvXMLElementExport::~SvXMLElementExport() { if ( mbDoSomething ) { mrExport.EndElement( maElementName, mbIgnoreWhitespaceInside ); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */