/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifdef PRECOMPILED
#include "filt_pch.hxx"
#endif
#include "unointerfacetouniqueidentifiermapper.hxx"
#include <osl/mutex.hxx>
#include <rtl/uuid.h>
#include <tools/debug.hxx>
#include <tools/urlobj.hxx>
#include <comphelper/genericpropertyset.hxx>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/document/XBinaryStreamResolver.hpp>
#include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp>
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
#include <com/sun/star/uri/UriReferenceFactory.hpp>
#include <comphelper/processfactory.hxx>
#include <comphelper/configurationhelper.hxx>
#include <xmloff/attrlist.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmluconv.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmlnumfe.hxx>
#include <xmloff/xmlmetae.hxx>
#include <xmloff/XMLSettingsExportContext.hxx>
#include <xmloff/families.hxx>
#include <xmloff/XMLEventExport.hxx>
#include "XMLStarBasicExportHandler.hxx"
#include "XMLScriptExportHandler.hxx"
#include <xmloff/SettingsExportHelper.hxx>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/document/XViewDataSupplier.hpp>
#include <xmloff/GradientStyle.hxx>
#include <xmloff/HatchStyle.hxx>
#include <xmloff/ImageStyle.hxx>
#include <TransGradientStyle.hxx>
#include <xmloff/MarkerStyle.hxx>
#include <xmloff/DashStyle.hxx>
#include <xmloff/XMLFontAutoStylePool.hxx>
#include "XMLImageMapExport.hxx"
#include "XMLBase64Export.hxx"
#include "xmloff/xmlerror.hxx"
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include "xmloff/XMLFilterServiceNames.h"
#include "xmloff/XMLEmbeddedObjectExportFilter.hxx"
#include "XMLBasicExportFilter.hxx"
#include <vos/mutex.hxx>
#include <rtl/logfile.hxx>
#include <cppuhelper/implbase1.hxx>
#include <comphelper/extract.hxx>
#include "PropertySetMerger.hxx"

#include "svl/urihelper.hxx"
#include "xmloff/xformsexport.hxx"

#include <unotools/docinfohelper.hxx>
#include <unotools/bootstrap.hxx>
#include <unotools/configmgr.hxx>
#include <tools/inetdef.hxx>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>

#include <com/sun/star/rdf/XMetadatable.hpp>
#include "RDFaExportHelper.hxx"


using ::rtl::OUString;

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 __READONLY_DATA sXML_1_1[] = "1.1";
sal_Char __READONLY_DATA sXML_1_2[] = "1.2";

const sal_Char *sOpenOfficeOrgProject ="OpenOffice.org_project";

// #i115030#: the XSLT is not finished, and not available via HTTP
const sal_Char s_grddl_xsl[] = "http://FIXME";

#define LOGFILE_AUTHOR "mb93740"

#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"

#define C2U(cChar) OUString( RTL_CONSTASCII_USTRINGPARAM(cChar) )

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 SAL_DLLPRIVATE SettingsExportFacade : public ::xmloff::XMLSettingsExportContext
{
public:
    SettingsExportFacade( SvXMLExport& i_rExport )
        :m_rExport( i_rExport )
    {
    }

    virtual ~SettingsExportFacade()
    {
    }

    virtual void    AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
				                  const ::rtl::OUString& i_rValue );
    virtual void    AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
				                  enum ::xmloff::token::XMLTokenEnum i_eValue );

    virtual void    StartElement( enum ::xmloff::token::XMLTokenEnum i_eName,
                                  const sal_Bool i_bIgnoreWhitespace );
    virtual void    EndElement(   const sal_Bool i_bIgnoreWhitespace );

    virtual void    Characters( const ::rtl::OUString& i_rCharacters );

    virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                    GetServiceFactory() const;
private:
    SvXMLExport&                    m_rExport;
    ::std::stack< ::rtl::OUString > m_aElements;
};

void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::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 sal_Bool i_bIgnoreWhitespace )
{
    const ::rtl::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 sal_Bool i_bIgnoreWhitespace )
{
    const ::rtl::OUString sElementName( m_aElements.top() );
    m_rExport.EndElement( sElementName, i_bIgnoreWhitespace );
    m_aElements.pop();
}

void SettingsExportFacade::Characters( const ::rtl::OUString& i_rCharacters )
{
    m_rExport.GetDocHandler()->characters( i_rCharacters );
}

Reference< XMultiServiceFactory > SettingsExportFacade::GetServiceFactory() const
{
    return m_rExport.getServiceFactory();
}

//==============================================================================

class SvXMLExportEventListener : public cppu::WeakImplHelper1<
							com::sun::star::lang::XEventListener >
{
private:
	SvXMLExport*	pExport;

public:
							SvXMLExportEventListener(SvXMLExport* pExport);
	virtual					~SvXMLExportEventListener();

							// XEventListener
	virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) throw(::com::sun::star::uno::RuntimeException);
};

SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport* pTempExport)
	: pExport(pTempExport)
{
}

SvXMLExportEventListener::~SvXMLExportEventListener()
{
}

// XEventListener
void SAL_CALL SvXMLExportEventListener::disposing( const lang::EventObject& )
	throw(uno::RuntimeException)
{
	if (pExport)
	{
		pExport->DisposingModel();
		pExport = NULL;
	}
}

//==============================================================================

class SvXMLExport_Impl
{
public:
    SvXMLExport_Impl();

    ::comphelper::UnoInterfaceToUniqueIdentifierMapper  maInterfaceToIdentifierMapper;
    uno::Reference< uri::XUriReferenceFactory >         mxUriReferenceFactory;
    rtl::OUString                                       msPackageURI;
    rtl::OUString                                       msPackageURIScheme;
    // --> OD 2006-09-27 #i69627#
    sal_Bool                                            mbOutlineStyleAsNormalListStyle;
    // <--
    // --> PB 2007-07-06 #i146851#
    sal_Bool                                            mbSaveBackwardCompatibleODF;
    // <--

	uno::Reference< embed::XStorage >					mxTargetStorage;

	SvtSaveOptions										maSaveOptions;

    /// relative path of stream in package, e.g. "someobject/content.xml"
    ::rtl::OUString mStreamPath;

    const uno::Reference< uno::XComponentContext > mxComponentContext;

    /// name of stream in package, e.g., "content.xml"
    ::rtl::OUString mStreamName;

    /// 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::auto_ptr< ::xmloff::RDFaExportHelper> mpRDFaHelper;

    // --> OD 2008-11-26 #158694#
    sal_Bool                                            mbExportTextNumberElement;
    // <--
    sal_Bool                                            mbNullDateInitialized;

    void SetSchemeOf( const ::rtl::OUString& rOrigFileName )
    {
        sal_Int32 nSep = rOrigFileName.indexOf(':');
        if( nSep != -1 )
            msPackageURIScheme = rOrigFileName.copy( 0, nSep );
    }
};

SvXMLExport_Impl::SvXMLExport_Impl()
    // --> OD 2006-09-27 #i69627#
    : mbOutlineStyleAsNormalListStyle( false )
    // <--
    // --> PB 2007-07-06 #i146851#
        ,mbSaveBackwardCompatibleODF( sal_True )
    // <--
        ,mxComponentContext( ::comphelper::getProcessComponentContext() )
        ,mStreamName()
        ,mNamespaceMaps()
        ,mDepth(0)
        ,mpRDFaHelper() // lazy
    // --> OD 2008-11-26 #158694#
        ,mbExportTextNumberElement( sal_False )
    // <--
        ,mbNullDateInitialized( sal_False )
{
    OSL_ENSURE(mxComponentContext.is(), "SvXMLExport: no ComponentContext");
    if (!mxComponentContext.is()) throw uno::RuntimeException();
    mxUriReferenceFactory = uri::UriReferenceFactory::create(
        mxComponentContext );
}

//==============================================================================

void SvXMLExport::SetDocHandler( const uno::Reference< xml::sax::XDocumentHandler > &rHandler )
{
	mxHandler = rHandler;
	mxExtHandler = uno::Reference<xml::sax::XExtendedDocumentHandler>( mxHandler, UNO_QUERY );
}

void SvXMLExport::_InitCtor()
{
    // note: it is not necessary to add XML_NP_XML (it is declared implicitly)
	if( (getExportFlags() & ~EXPORT_OASIS) != 0 )
	{
		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() & (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS) ) != 0 )
	{
		mpNamespaceMap->Add( GetXMLToken(XML_NP_FO), GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
	}
	if( (getExportFlags() & (EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS) ) != 0 )
	{
		mpNamespaceMap->Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
	}
	if( (getExportFlags() & EXPORT_SETTINGS) != 0 )
	{
		mpNamespaceMap->Add( GetXMLToken(XML_NP_CONFIG), GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
	}

	if( (getExportFlags() & (EXPORT_META|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
	{
		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() & (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_FONTDECLS) ) != 0 )
	{
		mpNamespaceMap->Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
	}

	// namespaces for documents
	if( (getExportFlags() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
	{
		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);
        }
	}
	if( (getExportFlags() & (EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
	{
		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() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS) ) != 0 )
	{
		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() & EXPORT_CONTENT ) != 0 )
	{
		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_FIELD), GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD );
	}
    // RDFa: needed for content and header/footer styles
    if( (getExportFlags() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
    {
        mpNamespaceMap->Add( GetXMLToken(XML_NP_XHTML),
            GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML );
    }
    // GRDDL: to convert RDFa and meta.xml to RDF
    if( (getExportFlags() & (EXPORT_META|EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
    {
        mpNamespaceMap->Add( GetXMLToken(XML_NP_GRDDL),
            GetXMLToken(XML_N_GRDDL), XML_NAMESPACE_GRDDL );
    }

	mxAttrList = (xml::sax::XAttributeList*)mpAttrList;

	msPicturesPath = OUString( RTL_CONSTASCII_USTRINGPARAM( "#Pictures/" ) );
	msObjectsPath = OUString( RTL_CONSTASCII_USTRINGPARAM( "#./" ) );
	msGraphicObjectProtocol = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
	msEmbeddedObjectProtocol = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.EmbeddedObject:" ) );

	if (mxModel.is() && !mxEventListener.is())
	{
		mxEventListener.set( new SvXMLExportEventListener(this));
		mxModel->addEventListener(mxEventListener);
	}

    // --> OD 2006-03-10 #i51726# - determine model type
    _DetermineModelType();
    // <--

	mbEnableExperimentalOdfExport = getenv("ENABLE_EXPERIMENTAL_ODF_EXPORT") != NULL;

    // --> PB 2007-07-06 #146851# - load mbSaveBackwardCompatibleODF from configuration

	// cl: but only if we do export to current oasis format, old openoffice format *must* always be compatible
	if( (getExportFlags() & EXPORT_OASIS) != 0 )
	{
		sal_Bool bTemp = sal_True;
		if ( ::comphelper::ConfigurationHelper::readDirectKey(
				getServiceFactory(),
				C2U("org.openoffice.Office.Common/"), C2U("Save/Document"), C2U("SaveBackwardCompatibleODF"),
				::comphelper::ConfigurationHelper::E_READONLY ) >>= bTemp )
		{
			mpImpl->mbSaveBackwardCompatibleODF = bTemp;
		}
	}
    // <--
}

// --> OD 2006-03-14 #i51726#
void SvXMLExport::_DetermineModelType()
{
    meModelType = SvtModuleOptions::E_UNKNOWN_FACTORY;

    if ( mxModel.is() )
    {
        meModelType = SvtModuleOptions::ClassifyFactoryByModel( mxModel );
    }
}
// <--

// #110680#
SvXMLExport::SvXMLExport(
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
	MapUnit eDfltUnit, const enum XMLTokenEnum eClass, sal_uInt16 nExportFlags )
:	mpImpl( new SvXMLExport_Impl ),
	// #110680#
	mxServiceFactory(xServiceFactory),
	mpAttrList( new SvXMLAttributeList ),
	mpNamespaceMap( new SvXMLNamespaceMap ),
	// #110680#
	mpUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, eDfltUnit, getServiceFactory() ) ),
	mpNumExport(0L),
	mpProgressBarHelper( NULL ),
	mpEventExport( NULL ),
	mpImageMapExport( NULL ),
	mpXMLErrors( NULL ),
	mbExtended( sal_False ),
	meClass( eClass ),
	mnExportFlags( nExportFlags ),
	mnErrorFlags( ERROR_NO ),
	msWS( GetXMLToken(XML_WS) ),
	mbSaveLinkedSections(sal_True)
{
	DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
	_InitCtor();
}

// #110680#
SvXMLExport::SvXMLExport(
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
	const OUString &rFileName,
	const uno::Reference< xml::sax::XDocumentHandler > & rHandler,
	MapUnit eDfltUnit	)
:	mpImpl( new SvXMLExport_Impl ),
	// #110680#
	mxServiceFactory(xServiceFactory),
	mxHandler( rHandler ),
	mxExtHandler( rHandler, uno::UNO_QUERY ),
	mpAttrList( new SvXMLAttributeList ),
	msOrigFileName( rFileName ),
	mpNamespaceMap( new SvXMLNamespaceMap ),
	// #110680#
	mpUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, eDfltUnit, getServiceFactory() ) ),
	mpNumExport(0L),
	mpProgressBarHelper( NULL ),
	mpEventExport( NULL ),
	mpImageMapExport( NULL ),
	mpXMLErrors( NULL ),
	mbExtended( sal_False ),
	meClass( XML_TOKEN_INVALID ),
	mnExportFlags( 0 ),
	mnErrorFlags( ERROR_NO ),
	msWS( GetXMLToken(XML_WS) ),
	mbSaveLinkedSections(sal_True)
{
    mpImpl->SetSchemeOf( msOrigFileName );
    DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
	_InitCtor();

	if (mxNumberFormatsSupplier.is())
		mpNumExport = new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier);
}

// #110680#
SvXMLExport::SvXMLExport(
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
	const OUString &rFileName,
	const uno::Reference< xml::sax::XDocumentHandler > & rHandler,
	const Reference< XModel >& rModel,
	sal_Int16 eDfltUnit	)
:	mpImpl( new SvXMLExport_Impl ),
	// #110680#
	mxServiceFactory(xServiceFactory),
	mxModel( rModel ),
	mxHandler( rHandler ),
	mxExtHandler( rHandler, uno::UNO_QUERY ),
	mxNumberFormatsSupplier (rModel, uno::UNO_QUERY),
	mpAttrList( new SvXMLAttributeList ),
	msOrigFileName( rFileName ),
	mpNamespaceMap( new SvXMLNamespaceMap ),
	// #110680#
	// pUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, SvXMLUnitConverter::GetMapUnit(eDfltUnit) ) ),
	mpUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, SvXMLUnitConverter::GetMapUnit(eDfltUnit), getServiceFactory() ) ),
	mpNumExport(0L),
	mpProgressBarHelper( NULL ),
	mpEventExport( NULL ),
	mpImageMapExport( NULL ),
	mpXMLErrors( NULL ),
	mbExtended( sal_False ),
	meClass( XML_TOKEN_INVALID ),
	mnExportFlags( 0 ),
	mnErrorFlags( ERROR_NO ),
	msWS( GetXMLToken(XML_WS) ),
	mbSaveLinkedSections(sal_True)
{
    mpImpl->SetSchemeOf( msOrigFileName );
	DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
	_InitCtor();

	if (mxNumberFormatsSupplier.is())
		mpNumExport = new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier);
}

// #110680#
SvXMLExport::SvXMLExport(
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
	const OUString &rFileName,
	const uno::Reference< xml::sax::XDocumentHandler > & rHandler,
	const Reference< XModel >& rModel,
	const Reference< document::XGraphicObjectResolver >& rEmbeddedGraphicObjects,
	sal_Int16 eDfltUnit	)
:	mpImpl( new SvXMLExport_Impl ),
	// #110680#
	mxServiceFactory(xServiceFactory),
	mxModel( rModel ),
	mxHandler( rHandler ),
	mxExtHandler( rHandler, uno::UNO_QUERY ),
	mxNumberFormatsSupplier (rModel, uno::UNO_QUERY),
	mxGraphicResolver( rEmbeddedGraphicObjects ),
	mpAttrList( new SvXMLAttributeList ),
	msOrigFileName( rFileName ),
	mpNamespaceMap( new SvXMLNamespaceMap ),
	// #110680#
	mpUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, SvXMLUnitConverter::GetMapUnit(eDfltUnit), getServiceFactory() ) ),
	mpNumExport(0L),
	mpProgressBarHelper( NULL ),
	mpEventExport( NULL ),
	mpImageMapExport( NULL ),
	mpXMLErrors( NULL ),
	mbExtended( sal_False ),
	meClass( XML_TOKEN_INVALID ),
	mnExportFlags( 0 ),
	mnErrorFlags( ERROR_NO ),
	msWS( GetXMLToken(XML_WS) ),
	mbSaveLinkedSections(sal_True)
{
    mpImpl->SetSchemeOf( msOrigFileName );
	DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
	_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(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSMAX));
					OUString sProgressCurrent(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSCURRENT));
                    OUString sRepeat(RTL_CONSTASCII_USTRINGPARAM(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, cppu::bool2any(mpProgressBarHelper->GetRepeat()));
				}
				if (mpNumExport && (mnExportFlags & (EXPORT_AUTOSTYLES | EXPORT_STYLES)))
				{
					OUString sWrittenNumberFormats(RTL_CONSTASCII_USTRINGPARAM(XML_WRITTENNUMBERSTYLES));
					if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats))
					{
						uno::Sequence<sal_Int32> aWasUsed;
						mpNumExport->GetWasUsed(aWasUsed);
						uno::Any aAny;
						aAny <<= aWasUsed;
						mxExportInfo->setPropertyValue(sWrittenNumberFormats, aAny);
					}
				}
			}
		}
		delete mpProgressBarHelper;
		delete mpNumExport;
	}

	xmloff::token::ResetTokens();

	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)
{
	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 = mxNumberFormatsSupplier.query( mxModel );
		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(RTL_CONSTASCII_USTRINGPARAM(XML_USEPRETTYPRINTING));
			if (xPropertySetInfo->hasPropertyByName(sUsePrettyPrinting))
			{
				uno::Any aAny = mxExportInfo->getPropertyValue(sUsePrettyPrinting);
				if (::cppu::any2bool(aAny))
					mnExportFlags |= EXPORT_PRETTY;
				else
					mnExportFlags &= ~EXPORT_PRETTY;
			}

            if (mpNumExport && (mnExportFlags & (EXPORT_AUTOSTYLES | EXPORT_STYLES)))
			{
				OUString sWrittenNumberFormats(RTL_CONSTASCII_USTRINGPARAM(XML_WRITTENNUMBERSTYLES));
				if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats))
				{
					uno::Any aAny = mxExportInfo->getPropertyValue(sWrittenNumberFormats);
					uno::Sequence<sal_Int32> aWasUsed;
					if(aAny >>= aWasUsed)
						mpNumExport->SetWasUsed(aWasUsed);
				}
			}
		}
	}

    // --> PB 2007-07-06 #i146851#
    if ( mpImpl->mbSaveBackwardCompatibleODF )
        mnExportFlags |= EXPORT_SAVEBACKWARDCOMPATIBLE;
    else
        mnExportFlags &= ~EXPORT_SAVEBACKWARDCOMPATIBLE;
    // <--

	// namespaces for user defined attributes
	Reference< XMultiServiceFactory > xFactory( mxModel,	UNO_QUERY );
	if( xFactory.is() )
	{
		try
		{
			Reference < XInterface > xIfc =
				xFactory->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM(
											"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, XML_NAMESPACE_UNKNOWN );
					}
				}
			}
		}
		catch( com::sun::star::uno::Exception& )
		{
		}
	}

    // --> OD 2006-03-10 #i51726# - determine model type
    _DetermineModelType();
    // <--
}

// XInitialize
void SAL_CALL SvXMLExport::initialize( const uno::Sequence< uno::Any >& aArguments )
	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
{
    // #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<XInterface> xValue;
        *pAny >>= xValue;

        // status indicator
        uno::Reference<task::XStatusIndicator> xTmpStatus( xValue, UNO_QUERY );
        if ( xTmpStatus.is() )
			mxStatusIndicator = xTmpStatus;

        // graphic resolver
        uno::Reference<document::XGraphicObjectResolver> xTmpGraphic(
            xValue, UNO_QUERY );
        if ( xTmpGraphic.is() )
            mxGraphicResolver = xTmpGraphic;

        // object resolver
        uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
            xValue, UNO_QUERY );
        if ( xTmpObjectResolver.is() )
            mxEmbeddedResolver = xTmpObjectResolver;

        // document handler
        uno::Reference<xml::sax::XDocumentHandler> 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<beans::XPropertySet> xTmpPropertySet(
            xValue, UNO_QUERY );
        if( xTmpPropertySet.is() )
			mxExportInfo = xTmpPropertySet;
	}

	if( mxExportInfo.is() )
	{
		uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
			mxExportInfo->getPropertySetInfo();
		OUString sPropName(
				RTL_CONSTASCII_USTRINGPARAM("BaseURI" ) );
		if( xPropertySetInfo->hasPropertyByName(sPropName) )
		{
			uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
			aAny >>= msOrigFileName;
            mpImpl->msPackageURI = msOrigFileName;
            mpImpl->SetSchemeOf( msOrigFileName );
		}
		OUString sRelPath;
		sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("StreamRelPath" ) );
		if( xPropertySetInfo->hasPropertyByName(sPropName) )
		{
			uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
			aAny >>= sRelPath;
		}
		OUString sName;
		sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("StreamName" ) );
		if( xPropertySetInfo->hasPropertyByName(sPropName) )
		{
			uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
			aAny >>= sName;
		}
		if( msOrigFileName.getLength() && sName.getLength() )
		{
			INetURLObject aBaseURL( msOrigFileName );
			if( sRelPath.getLength() )
				aBaseURL.insertName( sRelPath );
			aBaseURL.insertName( sName );
			msOrigFileName = aBaseURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
		}
        mpImpl->mStreamName = sName; // Note: may be empty (XSLT)

        // --> OD 2006-09-26 #i69627#
        const ::rtl::OUString sOutlineStyleAsNormalListStyle(
                RTL_CONSTASCII_USTRINGPARAM("OutlineStyleAsNormalListStyle") );
        if( xPropertySetInfo->hasPropertyByName( sOutlineStyleAsNormalListStyle ) )
        {
            uno::Any aAny = mxExportInfo->getPropertyValue( sOutlineStyleAsNormalListStyle );
            aAny >>= (mpImpl->mbOutlineStyleAsNormalListStyle);
        }
        // <--

		OUString sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") );
		if( xPropertySetInfo->hasPropertyByName( sTargetStorage ) )
            mxExportInfo->getPropertyValue( sTargetStorage ) >>= mpImpl->mxTargetStorage;

        // --> OD 2008-11-26 #158694#
        const ::rtl::OUString sExportTextNumberElement(
                RTL_CONSTASCII_USTRINGPARAM("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)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogContext, "xmloff", LOGFILE_AUTHOR,
                                "SvXMLExport::filter" );

    // check for xHandler first... should have been supplied in initialize
    if( !mxHandler.is() )
        return sal_False;

	try
	{
		const sal_uInt32 nTest =
			EXPORT_META|EXPORT_STYLES|EXPORT_CONTENT|EXPORT_SETTINGS;
		if( (mnExportFlags & nTest) == nTest && !msOrigFileName.getLength() )
		{
			// evaluate descriptor only for flat files and if a base URI
			// has not been provided already
			const sal_Int32 nPropCount = aDescriptor.getLength();
			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.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FileName" ) ) )
				{
					if( !(rValue >>= msOrigFileName ) )
						return sal_False;
				}
				else if (rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterName" ) ) )
				{
					if( !(rValue >>= msFilterName ) )
						return sal_False;
				}
			}
		}

#ifdef TIMELOG
        if (GetModel().is())
        {
            // print a trace message with the URL
            ByteString aUrl( (String) GetModel()->getURL(),
                             RTL_TEXTENCODING_ASCII_US );
            RTL_LOGFILE_CONTEXT_TRACE1( aLogContext, "%s", aUrl.GetBuffer() );

            // we also want a trace message with the document class
            ByteString aClass( (String)GetXMLToken(meClass),
                               RTL_TEXTENCODING_ASCII_US );
            RTL_LOGFILE_CONTEXT_TRACE1( aLogContext, "class=\"%s\"",
                                        aClass.GetBuffer() );
        }
#endif

		exportDoc( meClass );
	}
	catch( uno::Exception e )
	{
		// We must catch exceptions, because according to the
		// API definition export must not throw one!
        Sequence<OUString> aSeq(0);
        SetError( XMLERROR_FLAG_ERROR | XMLERROR_FLAG_SEVERE | XMLERROR_API,
                  aSeq, e.Message, NULL );
	}

    // return true only if no error occured
    return (GetErrorFlags() & (ERROR_DO_NOTHING|ERROR_ERROR_OCCURED)) == 0;
}

void SAL_CALL SvXMLExport::cancel() throw(uno::RuntimeException)
{
    // stop export
    Sequence<OUString> aEmptySeq;
    SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
}

::rtl::OUString SAL_CALL SvXMLExport::getName(  )
    throw (::com::sun::star::uno::RuntimeException)
{
    return msFilterName;
}

void SAL_CALL SvXMLExport::setName( const ::rtl::OUString& )
    throw (::com::sun::star::uno::RuntimeException)
{
    // do nothing, because it is not possible to set the FilterName
}


// XServiceInfo
OUString SAL_CALL SvXMLExport::getImplementationName(  ) throw(uno::RuntimeException)
{
	OUString aStr;
	return aStr;
}

sal_Bool SAL_CALL SvXMLExport::supportsService( const OUString& rServiceName ) throw(uno::RuntimeException)
{
    return
        rServiceName.equalsAsciiL(
            "com.sun.star.document.ExportFilter",
            sizeof("com.sun.star.document.ExportFilter")-1 ) ||
        rServiceName.equalsAsciiL(
            "com.sun.star.xml.XMLExportFilter",
            sizeof("com.sun.star.xml.XMLExportFilter")-1);
}

uno::Sequence< OUString > SAL_CALL SvXMLExport::getSupportedServiceNames(  )
	throw(uno::RuntimeException)
{
    uno::Sequence<OUString> aSeq(2);
    aSeq[0] = OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.ExportFilter"));
    aSeq[1] = OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter"));
    return aSeq;
}

///////////////////////////////////////////////////////////////////////

::rtl::OUString
SvXMLExport::EnsureNamespace(::rtl::OUString const & i_rNamespace,
    ::rtl::OUString const & i_rPreferredPrefix)
{
    ::rtl::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 );
        ::rtl::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( sal_Unicode(':') );
        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 ::rtl::OUString& rQName,
                                const ::rtl::OUString& rValue )
{
      mpAttrList->AddAttribute(
        rQName,
        rValue );
}

void SvXMLExport::AddAttribute( const ::rtl::OUString& rQName,
                                enum ::xmloff::token::XMLTokenEnum eValue )
{
      mpAttrList->AddAttribute(
        rQName,
        GetXMLToken(eValue) );
}

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()
{
	DBG_ASSERT( !mpAttrList->getLength(),
				"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<beans::PropertyValue> 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,
								sal_True, sal_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( sal_Bool )
{
	CheckAttrList();

//	AddAttribute( XML_NAMESPACE_NONE, XML_ID, XML_STYLES_ID );
	{
		// <style:styles>
		SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_STYLES,
								sal_True, sal_True );

		_ExportStyles( sal_False );
	}

    // transfer style names (+ families) TO other components (if appropriate)
    if( ( ( mnExportFlags & EXPORT_CONTENT ) == 0 ) && mxExportInfo.is() )
    {
        static OUString sStyleNames( RTL_CONSTASCII_USTRINGPARAM("StyleNames") );
        static OUString sStyleFamilies( RTL_CONSTASCII_USTRINGPARAM("StyleFamilies") );
        uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
        if ( xPropertySetInfo->hasPropertyByName( sStyleNames ) && xPropertySetInfo->hasPropertyByName( sStyleFamilies ) )
        {
            Sequence<sal_Int32> aStyleFamilies;
            Sequence<OUString> aStyleNames;
            mxAutoStylePool->GetRegisteredNames( aStyleFamilies, aStyleNames );
            mxExportInfo->setPropertyValue( sStyleNames, makeAny( aStyleNames ) );
            mxExportInfo->setPropertyValue( sStyleFamilies,
                                           makeAny( aStyleFamilies ) );
        }
    }
}

void SvXMLExport::ImplExportAutoStyles( sal_Bool )
{
    // transfer style names (+ families) FROM other components (if appropriate)
    OUString sStyleNames( RTL_CONSTASCII_USTRINGPARAM("StyleNames") );
    OUString sStyleFamilies( RTL_CONSTASCII_USTRINGPARAM("StyleFamilies") );
    if( ( ( mnExportFlags & EXPORT_STYLES ) == 0 )
        && mxExportInfo.is()
        && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleNames )
        && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleFamilies ) )
    {
        Sequence<sal_Int32> aStyleFamilies;
        mxExportInfo->getPropertyValue( sStyleFamilies ) >>= aStyleFamilies;
        Sequence<OUString> aStyleNames;
        mxExportInfo->getPropertyValue( sStyleNames ) >>= aStyleNames;
        mxAutoStylePool->RegisterNames( aStyleFamilies, aStyleNames );
    }

//	AddAttributeASCII( XML_NAMESPACE_NONE, XML_ID, XML_AUTO_STYLES_ID );
	{
		// <style:automatic-styles>
		SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE,
								  XML_AUTOMATIC_STYLES, sal_True, sal_True );

#if 0
		AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
		AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, XML_STYLES_HREF );
		AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
		AddAttribute( XML_NAMESPACE_XLINK, XML_ROLE,
				   	  pNamespaceMap->GetQNameByKey( XML_NAMESPACE_OFFICE,
                                               GetXMLToken(XML_STYLESHEET)) );
		{
			// <style:use-styles>
			SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE,
									  XML_USE_STYLES, sal_True, sal_True );
		}
#endif
		_ExportAutoStyles();
	}
}

void SvXMLExport::ImplExportMasterStyles( sal_Bool )
{
	{
		// <style:master-styles>
		SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_MASTER_STYLES,
								sal_True, sal_True );

		_ExportMasterStyles();
	}

#if 0
	AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
	AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, XML_AUTO_STYLES_HREF );
	AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
	AddAttribute( XML_NAMESPACE_XLINK, XML_ROLE,
				  pNamespaceMap->GetQNameByKey( XML_NAMESPACE_OFFICE,
                                                GetXMLToken(XML_STYLESHEET) ) );
	{
		// <style:use-styles>
		SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE,
								  XML_USE_STYLES, sal_True, sal_True );
	}
#endif
}

void SvXMLExport::ImplExportContent()
{
	CheckAttrList();

	CheckAttrList();

	{
		SvXMLElementExport aElemrnt( *this, XML_NAMESPACE_OFFICE, XML_BODY,
								  sal_True, sal_True );
		{
			XMLTokenEnum eClass = meClass;
			if( XML_TEXT_GLOBAL == eClass )
			{
				AddAttribute( XML_NAMESPACE_TEXT, XML_GLOBAL,
                      GetXMLToken( XML_TRUE ) );
				eClass = XML_TEXT;
			}
		    // <office:body ...>
		    SetBodyAttributes();
			SvXMLElementExport aElem( *this, meClass != XML_TOKEN_INVALID,
									  XML_NAMESPACE_OFFICE, eClass,
								  	  sal_True, sal_True );

			_ExportContent();
		}
	}
}

void SvXMLExport::SetBodyAttributes()
{
}

static void
lcl_AddGrddl(SvXMLExport & rExport, const sal_Int32 /*nExportMode*/)
{
    // check version >= 1.2
    switch (rExport.getDefaultVersion()) {
        case SvtSaveOptions::ODFVER_011: // fall thru
        case SvtSaveOptions::ODFVER_010: return;
        default: break;
    }

    // #i115030#: disabled
#if 0
    if (EXPORT_SETTINGS != nExportMode) // meta, content, styles
    {
        rExport.AddAttribute( XML_NAMESPACE_GRDDL, XML_TRANSFORMATION,
            OUString::createFromAscii(s_grddl_xsl) );
    }
#endif
}

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(
							OUString(RTL_CONSTASCII_USTRINGPARAM(
								"com.sun.star.document.ExportGraphicObjectResolver"))));
					bOwnGraphicResolver = mxGraphicResolver.is();
				}

				if( !mxEmbeddedResolver.is() )
				{
					mxEmbeddedResolver = Reference< XEmbeddedObjectResolver >::query(
						xFactory->createInstance(
							OUString(RTL_CONSTASCII_USTRINGPARAM(
								"com.sun.star.document.ExportEmbeddedObjectResolver"))));
					bOwnEmbeddedResolver = mxEmbeddedResolver.is();
				}
			}
			catch( com::sun::star::uno::Exception& )
			{
			}
		}
	}
	if( (getExportFlags() & EXPORT_OASIS) == 0 )
	{
		Reference< lang::XMultiServiceFactory > xFactory = getServiceFactory();
		if( xFactory.is() )
		{
			try
			{
				::comphelper::PropertyMapEntry aInfoMap[] =
				{
					{ "Class", sizeof("Class")-1, 0,
						&::getCppuType((::rtl::OUString*)0),
			  			PropertyAttribute::MAYBEVOID, 0},
					{ NULL, 0, 0, NULL, 0, 0 }
				};
				Reference< XPropertySet > xConvPropSet(
					::comphelper::GenericPropertySet_CreateInstance(
							new ::comphelper::PropertySetInfo( aInfoMap ) ) );

				Any aAny;
				aAny <<= GetXMLToken( eClass );
				xConvPropSet->setPropertyValue(
						OUString(RTL_CONSTASCII_USTRINGPARAM("Class")), aAny );

				Reference< XPropertySet > xPropSet =
					mxExportInfo.is()
                    ?  PropertySetMerger_CreateInstance( mxExportInfo,
                                                         xConvPropSet )
                    : xConvPropSet;

                Sequence<Any> aArgs( 3 );
				aArgs[0] <<= mxHandler;
				aArgs[1] <<= xPropSet;
				aArgs[2] <<= mxModel;

				// get filter component
				Reference< xml::sax::XDocumentHandler > xTmpDocHandler(
					xFactory->createInstanceWithArguments(
					OUString::createFromAscii("com.sun.star.comp.Oasis2OOoTransformer"),
								aArgs), UNO_QUERY);
				OSL_ENSURE( xTmpDocHandler.is(),
					"can't instantiate OASIS transformer component" );
				if( xTmpDocHandler.is() )
				{
					mxHandler = xTmpDocHandler;
					mxExtHandler = uno::Reference<xml::sax::XExtendedDocumentHandler>( mxHandler, UNO_QUERY );
				}
			}
			catch( com::sun::star::uno::Exception& )
			{
			}
		}
	}


	mxHandler->startDocument();

	// <?xml version="1.0" encoding="UTF-8"?>
//	xHandler->processingInstruction( S2U( sXML_xml ), S2U( sXML_xml_pi ) );

	// <office:document ...>
	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: pVersion = sXML_1_2; break;
        case SvtSaveOptions::ODFVER_011: pVersion = sXML_1_1; break;
        case SvtSaveOptions::ODFVER_010: break;

        default:
            DBG_ERROR("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 sal_Int32 nExportMode = mnExportFlags & (EXPORT_META|EXPORT_STYLES|EXPORT_CONTENT|EXPORT_SETTINGS);

        lcl_AddGrddl(*this, nExportMode);

		if( EXPORT_META == nExportMode )
		{
			// export only meta
			eRootService = XML_DOCUMENT_META;
		}
		else if ( EXPORT_SETTINGS == nExportMode )
		{
			// export only settings
			eRootService = XML_DOCUMENT_SETTINGS;
		}
		else if( EXPORT_STYLES == nExportMode )
		{
			// export only styles
			eRootService = XML_DOCUMENT_STYLES;
		}
		else if( EXPORT_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( RTL_CONSTASCII_USTRINGPARAM("application/vnd.oasis.opendocument.") );
				aTmp += GetXMLToken( eClass );
				AddAttribute( XML_NAMESPACE_OFFICE, XML_MIMETYPE, aTmp );
			}
		}

//		if( (getExportFlags() & EXPORT_NODOCTYPE) == 0 &&
//			xExtHandler.is() )
//		{
//			OUStringBuffer aDocType(
//               GetXMLToken(XML_XML_DOCTYPE_PREFIX).getLength() +
//				GetXMLToken(XML_XML_DOCTYPE_SUFFIX).getLength() + 30 );
//
//			aDocType.append( GetXMLToken(XML_XML_DOCTYPE_PREFIX) );
//			aDocType.append( GetNamespaceMap().GetQNameByKey(
//						   XML_NAMESPACE_OFFICE, GetXMLToken(eRootService) ) );
//			aDocType.append( GetXMLToken(XML_XML_DOCTYPE_SUFFIX) );
//			xExtHandler->unknown( aDocType.makeStringAndClear() );
//		}

		SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, eRootService, sal_True, sal_True );

		// meta information
		if( mnExportFlags & EXPORT_META )
			ImplExportMeta();

		// settings
		if( mnExportFlags & EXPORT_SETTINGS )
			ImplExportSettings();

		// scripts
		if( mnExportFlags & EXPORT_SCRIPTS )
			_ExportScripts();

		// font declerations
		if( mnExportFlags & EXPORT_FONTDECLS )
			_ExportFontDecls();

		// styles
		if( mnExportFlags & EXPORT_STYLES )
			ImplExportStyles( sal_False );

		// autostyles
		if( mnExportFlags & EXPORT_AUTOSTYLES )
			ImplExportAutoStyles( sal_False );

		// masterstyles
		if( mnExportFlags & EXPORT_MASTERSTYLES )
			ImplExportMasterStyles( sal_False );

		// contnt
		if( mnExportFlags & EXPORT_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;
}

void SvXMLExport::_ExportMeta()
{
    OUString generator( ::utl::DocInfoHelper::GetGeneratorString() );
    Reference< XDocumentPropertiesSupplier > xDocPropsSupplier(mxModel,
        UNO_QUERY);
    if (xDocPropsSupplier.is()) {
        Reference<XDocumentProperties> xDocProps(
            xDocPropsSupplier->getDocumentProperties());
        if (!xDocProps.is()) throw;
        // update generator here
        xDocProps->setGenerator(generator);
        SvXMLMetaExport * pMeta = new SvXMLMetaExport(*this, xDocProps);
        uno::Reference<xml::sax::XDocumentHandler> xMeta(pMeta);
        pMeta->Export();
    } else {
        // office:meta
		SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_META,
								sal_True, sal_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,
                                      sal_True, sal_True );
            Characters(generator);
        }
    }
}

void SvXMLExport::_ExportScripts()
{
    SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_SCRIPTS, sal_True, sal_True );

    // export Basic macros (only for FlatXML)
    if ( mnExportFlags & EXPORT_EMBEDDED )
    {
        ::rtl::OUString aValue( GetNamespaceMap().GetPrefixByKey( XML_NAMESPACE_OOO ) );
        aValue += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":Basic" ) );
        AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, aValue );

        SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_SCRIPT, sal_True, sal_True );

        // initialize Basic
        if ( mxModel.is() )
        {
            Reference< beans::XPropertySet > xPSet( mxModel, UNO_QUERY );
            if ( xPSet.is() )
	            xPSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) );
        }

	    Reference< document::XExporter > xExporter;
	    Reference< lang::XMultiServiceFactory > xMSF( getServiceFactory() );
        if ( xMSF.is() )
        {
            Reference < XDocumentHandler > xHdl( new XMLBasicExportFilter( mxHandler ) );
	        Sequence < Any > aArgs( 1 );
	        aArgs[0] <<= xHdl;
            xExporter.set( xMSF->createInstanceWithArguments(
                OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.XMLOasisBasicExporter" ) ), aArgs ),
                UNO_QUERY );
        }

        OSL_ENSURE( xExporter.is(),
            "SvXMLExport::_ExportScripts: can't instantiate export filter component for Basic macros" );

        if ( xExporter.is() )
        {
            Reference< XComponent > xComp( mxModel, UNO_QUERY );
            xExporter->setSourceDocument( xComp );
            Reference< XFilter > xFilter( xExporter, UNO_QUERY );
            if ( xFilter.is() )
            {
                Sequence < PropertyValue > aMediaDesc( 0 );
                xFilter->filter( aMediaDesc );
            }
        }
    }

	// export document events
	Reference< document::XEventsSupplier > xEvents( GetModel(), UNO_QUERY );
	GetEventExport().Export( xEvents, sal_True );
}

void SvXMLExport::_ExportFontDecls()
{
	if( mxFontAutoStylePool.is() )
		mxFontAutoStylePool->exportXML();
}

void SvXMLExport::_ExportStyles( sal_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( OUString(RTL_CONSTASCII_USTRINGPARAM("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; i<nCount; i++ )
					{
						const OUString& rStrName = aNamesSeq[ i ];

						try
						{
							uno::Any aValue = xGradient->getByName( rStrName );

							aGradientStyle.exportXML( rStrName, aValue );
						}
						catch( container::NoSuchElementException& )
						{}
					}
				}
			}
		}
		catch( lang::ServiceNotRegisteredException& )
		{}

		// export (fill-)hatch-styles
		try
		{
			uno::Reference< container::XNameAccess > xHatch( xFact->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("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; i<nCount; i++ )
					{
						const OUString& rStrName = aNamesSeq[ i ];

						try
						{
							uno::Any aValue = xHatch->getByName( rStrName );

							aHatchStyle.exportXML( rStrName, aValue );
						}
						catch( container::NoSuchElementException& )
						{}
					}
				}
			}
		}
		catch( lang::ServiceNotRegisteredException& )
		{}

		// export (fill-)bitmap-styles
		try
		{
			uno::Reference< container::XNameAccess > xBitmap( xFact->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("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; i<nCount; i++ )
					{
						const OUString& rStrName = aNamesSeq[ i ];

						try
						{
							uno::Any aValue = xBitmap->getByName( rStrName );

							aImageStyle.exportXML( rStrName, aValue, *this );
						}
						catch( container::NoSuchElementException& )
						{}
					}
				}
			}
		}
		catch( lang::ServiceNotRegisteredException& )
		{}

		// export transparency-gradient -styles
		try
		{
			uno::Reference< container::XNameAccess > xTransGradient( xFact->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("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; i<nCount; i++ )
					{
						const OUString& rStrName = aNamesSeq[ i ];

						try
						{
							uno::Any aValue = xTransGradient->getByName( rStrName );

							aTransGradientstyle.exportXML( rStrName, aValue );
						}
						catch( container::NoSuchElementException& )
						{}
					}
				}
			}
		}
		catch( lang::ServiceNotRegisteredException& )
		{}

		// export marker-styles
		try
		{
			uno::Reference< container::XNameAccess > xMarker( xFact->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("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; i<nCount; i++ )
					{
						const OUString& rStrName = aNamesSeq[ i ];

						try
						{
							uno::Any aValue = xMarker->getByName( rStrName );

							aMarkerStyle.exportXML( rStrName, aValue );
						}
						catch( container::NoSuchElementException& )
						{}
					}
				}
			}
		}
		catch( lang::ServiceNotRegisteredException& )
		{}

		// export dash-styles
		try
		{
			uno::Reference< container::XNameAccess > xDashes( xFact->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("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; i<nCount; i++ )
					{
						const OUString& rStrName = aNamesSeq[ i ];

						try
						{
							uno::Any aValue = xDashes->getByName( rStrName );

							aDashStyle.exportXML( rStrName, aValue );
						}
						catch( container::NoSuchElementException& )
						{}
					}
				}
			}
		}
		catch( 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<beans::PropertyValue>& rProps)
{
	GetViewSettings(rProps);
	uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
	if(xViewDataSupplier.is())
	{
		uno::Reference<container::XIndexAccess> xIndexAccess;
		xViewDataSupplier->setViewData( xIndexAccess ); // make sure we get a newly created sequence
		xIndexAccess = xViewDataSupplier->getViewData();
		sal_Bool bAdd = sal_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<beans::PropertyValue> aProps;
				if( aAny >>= aProps )
				{
					if( aProps.getLength() > 0 )
					{
						bAdd = sal_True;
						break;
					}
				}
			}
		}

		if( bAdd )
		{
			sal_Int32 nOldLength(rProps.getLength());
			rProps.realloc(nOldLength + 1);
			beans::PropertyValue aProp;
			aProp.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Views"));
			aProp.Value <<= xIndexAccess;
			rProps[nOldLength] = aProp;
		}
	}
}

void SvXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>&)
{
}

void SvXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>&)
{
}

sal_Int32 SvXMLExport::GetDocumentSpecificSettings( ::std::list< SettingsGroup >& _out_rSettings )
{
    (void)_out_rSettings;
    return 0;
}

void SvXMLExport::addDataStyle(const sal_Int32 nNumberFormat, sal_Bool /*bTimeFormat*/ )
{
	if(mpNumExport)
		mpNumExport->SetUsed(nNumberFormat);
}

void SvXMLExport::exportDataStyles()
{
	if(mpNumExport)
		mpNumExport->Export(sal_False);
}

void SvXMLExport::exportAutoDataStyles()
{
	if(mpNumExport)
		mpNumExport->Export(sal_True);

	if (mxFormExport.is())
		mxFormExport->exportAutoControlNumberStyles();
}

OUString SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, sal_Bool /*bTimeFormat*/ ) const
{
	OUString sTemp;
	if(mpNumExport)
		sTemp = mpNumExport->GetStyleName(nNumberFormat);
	return sTemp;
}

void SvXMLExport::exportAnnotationMeta(const uno::Reference<drawing::XShape>&)
{
}

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( 0 == rGraphicObjectURL.compareTo( msGraphicObjectProtocol,
                                          msGraphicObjectProtocol.getLength() ) &&
        mxGraphicResolver.is() )
	{
		if( (getExportFlags() & EXPORT_EMBEDDED) == 0 )
			sRet = mxGraphicResolver->resolveGraphicObjectURL( rGraphicObjectURL );
		else
			sRet = OUString();
	}
	else
		sRet = GetRelativeReference( sRet );

	return sRet;
}

sal_Bool SvXMLExport::AddEmbeddedGraphicObjectAsBase64( const OUString& rGraphicObjectURL )
{
    sal_Bool bRet = sal_False;

	if( (getExportFlags() & EXPORT_EMBEDDED) != 0 &&
		0 == rGraphicObjectURL.compareTo( msGraphicObjectProtocol,
                                          msGraphicObjectProtocol.getLength() ) &&
		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( (0 == rEmbeddedObjectURL.compareTo( msEmbeddedObjectProtocol,
				msEmbeddedObjectProtocol.getLength() ) ||
		 0 == rEmbeddedObjectURL.compareTo( msGraphicObjectProtocol,
				msGraphicObjectProtocol.getLength() ) ) &&
		mxEmbeddedResolver.is() )
	{
		sRet =
			mxEmbeddedResolver->resolveEmbeddedObjectURL( rEmbeddedObjectURL );
	}
	else
		sRet = GetRelativeReference( rEmbeddedObjectURL );

	return sRet;
}

sal_Bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString& rEmbeddedObjectURL )
{
	sal_Bool bRet = sal_False;
	if( (0 == rEmbeddedObjectURL.compareTo( msEmbeddedObjectProtocol,
				msEmbeddedObjectProtocol.getLength() ) ||
		 0 == rEmbeddedObjectURL.compareTo( msGraphicObjectProtocol,
				msGraphicObjectProtocol.getLength() ) ) &&
		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,
	    sal_Bool *pEncoded ) const
{
	return GetMM100UnitConverter().encodeStyleName( rName, pEncoded );
}

ProgressBarHelper*	SvXMLExport::GetProgressBarHelper()
{
	if (!mpProgressBarHelper)
	{
		mpProgressBarHelper = new ProgressBarHelper(mxStatusIndicator, sal_True);

		if (mxExportInfo.is())
		{
			uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
			if (xPropertySetInfo.is())
			{
				OUString sProgressRange(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSRANGE));
				OUString sProgressMax(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSMAX));
				OUString sProgressCurrent(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSCURRENT));
                OUString sRepeat(RTL_CONSTASCII_USTRINGPARAM(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() == getBooleanCppuType())
                        mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
                    else {
                        DBG_ERRORFILE("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(RTL_CONSTASCII_USTRINGPARAM("StarBasic"));
		mpEventExport->AddHandler(sStarBasic, new XMLStarBasicExportHandler());
		OUString sScript(RTL_CONSTASCII_USTRINGPARAM("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;
}

// XUnoTunnel & co
const uno::Sequence< sal_Int8 > & SvXMLExport::getUnoTunnelId() throw()
{
	static uno::Sequence< sal_Int8 > * pSeq = 0;
	if( !pSeq )
	{
		Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
		if( !pSeq )
		{
			static uno::Sequence< sal_Int8 > aSeq( 16 );
			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
			pSeq = &aSeq;
		}
	}
	return *pSeq;
}

SvXMLExport* SvXMLExport::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
{
	uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
	if( xUT.is() )
	{
		return
			reinterpret_cast<SvXMLExport*>(
				sal::static_int_cast<sal_IntPtr>(
					xUT->getSomething( SvXMLExport::getUnoTunnelId())));
	}
	else
		return NULL;
}

// XUnoTunnel
sal_Int64 SAL_CALL SvXMLExport::getSomething( const uno::Sequence< sal_Int8 >& rId )
	throw( uno::RuntimeException )
{
	if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
														 rId.getConstArray(), 16 ) )
	{
		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
	}
	return 0;
}

sal_Bool SvXMLExport::ExportEmbeddedOwnObject( Reference< XComponent >& rComp )
{
	OUString sFilterService;
    bool bIsChart = false;

    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 );
                bIsChart = sModelService.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( XML_MODEL_SERVICE_CHART ));
                break;
			}
			pEntry++;
		}
	}

	OSL_ENSURE( sFilterService.getLength(), "no export filter for own object" );

	if( !sFilterService.getLength() )
		return sal_False;

	Reference < XDocumentHandler > xHdl =
		new XMLEmbeddedObjectExportFilter( mxHandler );

    Sequence < Any > aArgs( 1 );
    // #144135# the filters for embedded objects in flat format are always
    // instantiated as Oasis filters and transformed afterwards. Therefore, all
    // special handling that is done if the exportFlags do not contain
    // EXPORT_OASIS must be changed to properties being passed in the info
    // propertyset

	if( ! (getExportFlags() & EXPORT_OASIS) &&
        bIsChart )
    {
        static ::comphelper::PropertyMapEntry aInfoMap[] =
        {
            { RTL_CONSTASCII_STRINGPARAM("ExportTableNumberList"), 0, &::getBooleanCppuType(), PropertyAttribute::MAYBEVOID, 0},
            { NULL, 0, 0, NULL, 0, 0 }
        };
        Reference< XPropertySet > xInfoProp(
            ::comphelper::GenericPropertySet_CreateInstance(
                new ::comphelper::PropertySetInfo( aInfoMap )));

        if( bIsChart )
            xInfoProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("ExportTableNumberList")), makeAny( true ));

        aArgs.realloc( 2 );
        aArgs[1] <<= xInfoProp;
    }
	aArgs[0] <<= xHdl;

	// #110680#
	// Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory();
	Reference< lang::XMultiServiceFactory > xServiceFactory = getServiceFactory();

	Reference< document::XExporter > xExporter(
		xServiceFactory->createInstanceWithArguments( sFilterService, aArgs),
											   UNO_QUERY);
	OSL_ENSURE( xExporter.is(),
				"can't instantiate export filter component for own object" );
	if( !xExporter.is() )
		return sal_False;

	xExporter->setSourceDocument( rComp );

	Reference<XFilter> 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.getLength() && sValue.getStr()[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( uno::Exception& )
        {
        }
    }
    OUString sRet = sValue;
    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, 
                INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI, RTL_TEXTENCODING_UTF8, INetURLObject::FSYS_DETECT);
        }
    }
    return sValue;
}

void SvXMLExport::StartElement(sal_uInt16 nPrefix,
                        enum ::xmloff::token::XMLTokenEnum eName,
					    sal_Bool bIgnWSOutside )
{
	StartElement(_GetNamespaceMap().GetQNameByKey( nPrefix,
        GetXMLToken(eName) ), bIgnWSOutside);
}

void SvXMLExport::StartElement(const OUString& rName,
					    sal_Bool bIgnWSOutside )
{
	if ((mnErrorFlags & ERROR_DO_NOTHING) != ERROR_DO_NOTHING)
	{
		try
		{
			if( bIgnWSOutside && ((mnExportFlags & EXPORT_PRETTY) == EXPORT_PRETTY))
				mxHandler->ignorableWhitespace( msWS );
			mxHandler->startElement( rName, GetXAttrList() );
		}
		catch ( SAXInvalidCharacterException& e )
		{
            Sequence<OUString> aPars(1);
            aPars[0] = rName;
			SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, NULL );
		}
		catch ( SAXException& e )
		{
            Sequence<OUString> 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 ::rtl::OUString& rChars)
{
	if ((mnErrorFlags & ERROR_DO_NOTHING) != ERROR_DO_NOTHING)
	{
		try
		{
			mxHandler->characters(rChars);
		}
		catch ( SAXInvalidCharacterException& e )
		{
            Sequence<OUString> aPars(1);
            aPars[0] = rChars;
			SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, NULL );
		}
		catch ( SAXException& e )
		{
            Sequence<OUString> 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,
						sal_Bool bIgnWSInside )
{
	EndElement(_GetNamespaceMap().GetQNameByKey( nPrefix, GetXMLToken(eName) ),
        bIgnWSInside);
}

void SvXMLExport::EndElement(const OUString& rName,
						sal_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();
    }
    OSL_ENSURE(mpImpl->mNamespaceMaps.empty() ||
        (mpImpl->mNamespaceMaps.top().second < mpImpl->mDepth),
        "SvXMLExport: NamespaceMaps corrupted");

	if ((mnErrorFlags & ERROR_DO_NOTHING) != ERROR_DO_NOTHING)
	{
		try
		{
			if( bIgnWSInside && ((mnExportFlags & EXPORT_PRETTY) == EXPORT_PRETTY))
				mxHandler->ignorableWhitespace( msWS );
			mxHandler->endElement( rName );
		}
		catch ( SAXException& e )
		{
            Sequence<OUString> aPars(1);
            aPars[0] = rName;
            SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
                      aPars, e.Message, NULL );
		}
	}
}

void SvXMLExport::IgnorableWhitespace()
{
	if ((mnExportFlags & EXPORT_PRETTY) != EXPORT_PRETTY)
		return;

	if ((mnErrorFlags & ERROR_DO_NOTHING) != ERROR_DO_NOTHING)
	{
		try
		{
			mxHandler->ignorableWhitespace( msWS );
		}
		catch ( SAXException& e )
		{
            Sequence<OUString> aPars(0);
            SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
                      aPars, e.Message, NULL );
		}
	}
}


void SvXMLExport::SetError(
    sal_Int32 nId,
    const Sequence<OUString>& rMsgParams,
    const OUString& rExceptionMessage,
    const Reference<XLocator>& rLocator )
{
    // allow multi-threaded access to the cancel() method
    static ::vos::OMutex aMutex;
    ::vos::OGuard aGuard(aMutex);

    // maintain error flags
    if ( ( nId & XMLERROR_FLAG_ERROR ) != 0 )
        mnErrorFlags |= ERROR_ERROR_OCCURED;
    if ( ( nId & XMLERROR_FLAG_WARNING ) != 0 )
        mnErrorFlags |= ERROR_WARNING_OCCURED;
    if ( ( nId & XMLERROR_FLAG_SEVERE ) != 0 )
        mnErrorFlags |= ERROR_DO_NOTHING;

    // create error lsit 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<OUString>& rMsgParams)
{
    OUString sEmpty;
    SetError( nId, rMsgParams, sEmpty, NULL );
}


XMLErrors* SvXMLExport::GetErrors()
{
	return mpXMLErrors;
}

void SvXMLExport::DisposingModel()
{
	mxModel.clear();
    // --> OD 2006-03-13 #i51726#
    meModelType = SvtModuleOptions::E_UNKNOWN_FACTORY;;
    // <--
	mxEventListener.clear();
}

// #110680#
::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > SvXMLExport::getServiceFactory()
{
	// #110680#
	return mxServiceFactory;
}

uno::Reference< uno::XComponentContext >
SvXMLExport::GetComponentContext() const
{
    return mpImpl->mxComponentContext;
}

::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLExport::getInterfaceToIdentifierMapper()
{
	return mpImpl->maInterfaceToIdentifierMapper;
}

// --> OD 2006-09-27 #i69627#
sal_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;
}

::rtl::OUString SvXMLExport::GetStreamName() const
{
    return mpImpl->mStreamName;
}

void
SvXMLExport::AddAttributeIdLegacy(
        sal_uInt16 const nLegacyPrefix, ::rtl::OUString const& rValue)
{
    switch (getDefaultVersion()) {
        case SvtSaveOptions::ODFVER_011: // fall thru
        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<uno::XInterface> const & i_xIfc)
{
    // check version >= 1.2
    switch (getDefaultVersion()) {
        case SvtSaveOptions::ODFVER_011: // fall thru
        case SvtSaveOptions::ODFVER_010: return;
        default: break;
    }
    const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
        uno::UNO_QUERY);
//FIXME not yet...
//    OSL_ENSURE(xMeta.is(), "xml:id: not XMetadatable");
    if ( xMeta.is() )
    {
        const beans::StringPair mdref( xMeta->getMetadataReference() );
        if ( !mdref.Second.equalsAscii("") )
        {
            const ::rtl::OUString streamName( GetStreamName() );
            if ( streamName.getLength() )
            {
                if ( streamName.equals(mdref.First) )
                {
                    AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second );
                }
                else
                {
                    OSL_ENSURE(false, "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.equalsAscii("content.xml") )
                {
                    AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second );
                }
                else
                {
                    OSL_TRACE("SvXMLExport::AddAttributeXmlId: "
                        "no stream name given: dropping styles.xml xml:id");
                }
            }
        }
    }
}

void
SvXMLExport::AddAttributesRDFa(
    uno::Reference<text::XTextContent> const & i_xTextContent)
{
    // check version >= 1.2
    switch (getDefaultVersion()) {
        case SvtSaveOptions::ODFVER_011: // fall thru
        case SvtSaveOptions::ODFVER_010: return;
        default: break;
    }

    const uno::Reference<rdf::XMetadatable> xMeta(
        i_xTextContent, uno::UNO_QUERY);
    if (!xMeta.is() || !xMeta->getMetadataReference().Second.getLength())
    {
        return; // no xml:id => no RDFa
    }

    if (!mpImpl->mpRDFaHelper.get())
    {
        mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaExportHelper(*this) );
    }
    mpImpl->mpRDFaHelper->AddRDFa(xMeta);
}

// --> OD 2008-11-26 #158694#
sal_Bool SvXMLExport::exportTextNumberElement() const
{
    return mpImpl->mbExportTextNumberElement;
}
// <--

sal_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( SvXMLExport& rExp,
									   sal_uInt16 nPrefixKey,
									   const OUString& rLName,
									   sal_Bool bIWSOutside )
{
    aName = rExp.GetNamespaceMap().GetQNameByKey(nPrefixKey, rLName);
    rExp.StartElement(aName, bIWSOutside);
}

SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp,
										sal_uInt16 nPrefixKey,
										const sal_Char *pLName,
										sal_Bool bIWSOutside,
										sal_Bool bIWSInside ) :
	rExport( rExp ),
	bIgnWS( bIWSInside ),
	bDoSomething( sal_True )
{
	OUString sLName( OUString::createFromAscii(pLName) );
	StartElement( rExp, nPrefixKey, sLName, bIWSOutside );
}

SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp,
										sal_uInt16 nPrefixKey,
										const OUString& rLName,
										sal_Bool bIWSOutside,
										sal_Bool bIWSInside ) :
	rExport( rExp ),
	bIgnWS( bIWSInside ),
	bDoSomething( sal_True )
{
	StartElement( rExp, nPrefixKey, rLName, bIWSOutside );
}

SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp,
										sal_uInt16 nPrefixKey,
										enum XMLTokenEnum eLName,
										sal_Bool bIWSOutside,
										sal_Bool bIWSInside ) :
	rExport( rExp ),
	bIgnWS( bIWSInside ),
	bDoSomething( sal_True )
{
	StartElement( rExp, nPrefixKey, GetXMLToken(eLName), bIWSOutside );
}

SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp,
										sal_Bool bDoSth,
										sal_uInt16 nPrefixKey,
										const sal_Char *pLName,
										sal_Bool bIWSOutside,
										sal_Bool bIWSInside ) :
	rExport( rExp ),
	bIgnWS( bIWSInside ),
	bDoSomething( bDoSth )
{
	if( bDoSomething )
	{
		OUString sLName( OUString::createFromAscii(pLName) );
		StartElement( rExp, nPrefixKey, sLName, bIWSOutside );
	}
}

SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp,
										sal_Bool bDoSth,
										sal_uInt16 nPrefixKey,
										const OUString& rLName,
										sal_Bool bIWSOutside,
										sal_Bool bIWSInside ) :
	rExport( rExp ),
	bIgnWS( bIWSInside ),
	bDoSomething( bDoSth )
{
	if( bDoSomething )
		StartElement( rExp, nPrefixKey, rLName, bIWSOutside );
}

SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp,
										sal_Bool bDoSth,
										sal_uInt16 nPrefixKey,
										enum XMLTokenEnum eLName,
										sal_Bool bIWSOutside,
										sal_Bool bIWSInside ) :
	rExport( rExp ),
	bIgnWS( bIWSInside ),
	bDoSomething( bDoSth )
{
	if( bDoSomething )
		StartElement( rExport, nPrefixKey, GetXMLToken(eLName), bIWSOutside );
}

SvXMLElementExport::SvXMLElementExport( SvXMLExport& rExp,
                                        const OUString& rQName,
                                        sal_Bool bIWSOutside,
                                        sal_Bool bIWSInside ) :
    rExport( rExp ),
    bIgnWS( bIWSInside ),
    bDoSomething( sal_True )
{
    aName = rQName;
    rExp.StartElement( rQName, bIWSOutside );
}

SvXMLElementExport::~SvXMLElementExport()
{
	if( bDoSomething )
	{
        rExport.EndElement( aName, bIgnWS );
	}
}

