/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include "unointerfacetouniqueidentifiermapper.hxx"
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlmetae.hxx>
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#include <com/sun/star/presentation/XPresentationSupplier.hpp>
#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
#include <com/sun/star/geometry/RealPoint2D.hpp>
#include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
#include <com/sun/star/office/XAnnotationAccess.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/uno/Any.hxx>
#include "sdxmlexp_impl.hxx"
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
#include <com/sun/star/presentation/XHandoutMasterSupplier.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/view/PaperOrientation.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/style/XStyle.hpp>

#include <com/sun/star/form/XFormsSupplier2.hpp>
#include <com/sun/star/presentation/XPresentationPage.hpp>
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <rtl/ustrbuf.hxx>
#include <tools/gen.hxx>
#include <tools/debug.hxx>
#include <xmloff/xmlaustp.hxx>
#include <xmloff/families.hxx>
#include <xmloff/styleexp.hxx>
#include "sdpropls.hxx"
#include <xmloff/xmlexppr.hxx>
#include <com/sun/star/beans/XPropertyState.hpp>
#include "xexptran.hxx"

#ifndef _CPPUHELPER_IMPLBASE1_HXX
#include <cppuhelper/implbase1.hxx>
#endif
#include <comphelper/extract.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include "PropertySetMerger.hxx"
#include "layerexp.hxx"


#include "xmloff/VisAreaExport.hxx"
#include "XMLNumberStylesExport.hxx"
#include <tools/list.hxx>
#include <tools/string.hxx>

#include "animationexport.hxx"

#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::office;
using namespace ::com::sun::star::presentation;
using namespace ::com::sun::star::geometry;
using namespace ::com::sun::star::text;
using namespace ::xmloff::token;


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

class ImpXMLEXPPageMasterInfo
{
	sal_Int32					mnBorderBottom;
	sal_Int32					mnBorderLeft;
	sal_Int32					mnBorderRight;
	sal_Int32					mnBorderTop;
	sal_Int32					mnWidth;
	sal_Int32					mnHeight;
	view::PaperOrientation		meOrientation;
	OUString					msName;
	OUString					msMasterPageName;

public:
	ImpXMLEXPPageMasterInfo(const SdXMLExport& rExp, const Reference<XDrawPage>& xPage);
	sal_Bool operator==(const ImpXMLEXPPageMasterInfo& rInfo) const;
	void SetName(const OUString& rStr);

	const OUString& GetName() const { return msName; }
	const OUString& GetMasterPageName() const { return msMasterPageName; }

	sal_Int32 GetBorderBottom() const { return mnBorderBottom; }
	sal_Int32 GetBorderLeft() const { return mnBorderLeft; }
	sal_Int32 GetBorderRight() const { return mnBorderRight; }
	sal_Int32 GetBorderTop() const { return mnBorderTop; }
	sal_Int32 GetWidth() const { return mnWidth; }
	sal_Int32 GetHeight() const { return mnHeight; }
	view::PaperOrientation GetOrientation() const { return meOrientation; }
};

ImpXMLEXPPageMasterInfo::ImpXMLEXPPageMasterInfo(
	const SdXMLExport& rExp,
	const Reference<XDrawPage>& xPage)
:	mnBorderBottom(0),
	mnBorderLeft(0),
	mnBorderRight(0),
	mnBorderTop(0),
	mnWidth(0),
	mnHeight(0),
	meOrientation(rExp.IsDraw() ? view::PaperOrientation_PORTRAIT : view::PaperOrientation_LANDSCAPE)
{
	Reference <beans::XPropertySet> xPropSet(xPage, UNO_QUERY);
	if(xPropSet.is())
	{
		Any aAny;

		Reference< beans::XPropertySetInfo > xPropsInfo( xPropSet->getPropertySetInfo() );
		if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("BorderBottom") )))
		{
			aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("BorderBottom")));
			aAny >>= mnBorderBottom;

			aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("BorderLeft")));
			aAny >>= mnBorderLeft;

			aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("BorderRight")));
			aAny >>= mnBorderRight;

			aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("BorderTop")));
			aAny >>= mnBorderTop;
		}

		if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("Width") )))
		{
			aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Width")));
			aAny >>= mnWidth;

			aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Height")));
			aAny >>= mnHeight;
		}

		if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("Orientation") )))
		{
			aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Orientation")));
			aAny >>= meOrientation;
		}
	}

	Reference <container::XNamed> xMasterNamed(xPage, UNO_QUERY);
	if(xMasterNamed.is())
	{
		msMasterPageName = xMasterNamed->getName();
	}
}

sal_Bool ImpXMLEXPPageMasterInfo::operator==(const ImpXMLEXPPageMasterInfo& rInfo) const
{
	return ((mnBorderBottom == rInfo.mnBorderBottom)
		&& (mnBorderLeft == rInfo.mnBorderLeft)
		&& (mnBorderRight == rInfo.mnBorderRight)
		&& (mnBorderTop == rInfo.mnBorderTop)
		&& (mnWidth == rInfo.mnWidth)
		&& (mnHeight == rInfo.mnHeight)
		&& (meOrientation == rInfo.meOrientation));
}

void ImpXMLEXPPageMasterInfo::SetName(const OUString& rStr)
{
	msName = rStr;
}

DECLARE_LIST(ImpXMLEXPPageMasterList, ImpXMLEXPPageMasterInfo*)

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

#define	IMP_AUTOLAYOUT_INFO_MAX			(35L)

class ImpXMLAutoLayoutInfo
{
	sal_uInt16					mnType;
	ImpXMLEXPPageMasterInfo*	mpPageMasterInfo;
	OUString					msLayoutName;
	Rectangle					maTitleRect;
	Rectangle					maPresRect;
	sal_Int32					mnGapX;
	sal_Int32					mnGapY;

public:
	ImpXMLAutoLayoutInfo(sal_uInt16 nTyp, ImpXMLEXPPageMasterInfo* pInf);

	sal_Bool operator==(const ImpXMLAutoLayoutInfo& rInfo) const;

	sal_uInt16 GetLayoutType() const { return mnType; }
	sal_Int32 GetGapX() const { return mnGapX; }
	sal_Int32 GetGapY() const { return mnGapY; }

	const OUString& GetLayoutName() const { return msLayoutName; }
	void SetLayoutName(const OUString& rNew) { msLayoutName = rNew; }

	const Rectangle& GetTitleRectangle() const { return maTitleRect; }
	const Rectangle& GetPresRectangle() const { return maPresRect; }

	static sal_Bool IsCreateNecessary(sal_uInt16 nTyp);
};

sal_Bool ImpXMLAutoLayoutInfo::IsCreateNecessary(sal_uInt16 nTyp)
{
	if(nTyp == 5 /* AUTOLAYOUT_ORG */
		|| nTyp == 20 /* AUTOLAYOUT_NONE */
		|| nTyp >= IMP_AUTOLAYOUT_INFO_MAX)
		return sal_False;
	return sal_True;
}

sal_Bool ImpXMLAutoLayoutInfo::operator==(const ImpXMLAutoLayoutInfo& rInfo) const
{
	return ((mnType == rInfo.mnType
		&& mpPageMasterInfo == rInfo.mpPageMasterInfo));
}

ImpXMLAutoLayoutInfo::ImpXMLAutoLayoutInfo(sal_uInt16 nTyp, ImpXMLEXPPageMasterInfo* pInf)
:	mnType(nTyp),
	mpPageMasterInfo(pInf)
{
	// create full info (initialze with typical values)
	Point aPagePos(0,0);
	Size aPageSize(28000, 21000);
	Size aPageInnerSize(28000, 21000);

	if(mpPageMasterInfo)
	{
		aPagePos = Point(mpPageMasterInfo->GetBorderLeft(), mpPageMasterInfo->GetBorderTop());
		aPageSize = Size(mpPageMasterInfo->GetWidth(), mpPageMasterInfo->GetHeight());
		aPageInnerSize = aPageSize;
		aPageInnerSize.Width() -= mpPageMasterInfo->GetBorderLeft() + mpPageMasterInfo->GetBorderRight();
		aPageInnerSize.Height() -= mpPageMasterInfo->GetBorderTop() + mpPageMasterInfo->GetBorderBottom();
	}

	// title rectangle aligning
	Point aTitlePos(aPagePos);
	Size aTitleSize(aPageInnerSize);

	if(mnType == 21 /* AUTOLAYOUT_NOTES */)
	{
		aTitleSize.Height() = (long) (aTitleSize.Height() / 2.5);
		Point aPos = aTitlePos;
		aPos.Y() += long( aTitleSize.Height() * 0.083 );
		Size aPartArea = aTitleSize;
		Size aSize;

		// tatsaechliche Seitengroesse in das Handout-Rechteck skalieren
		double fH = (double) aPartArea.Width()  / aPageSize.Width();
		double fV = (double) aPartArea.Height() / aPageSize.Height();

		if ( fH > fV )
			fH = fV;
		aSize.Width()  = (long) (fH * aPageSize.Width());
		aSize.Height() = (long) (fH * aPageSize.Height());

		aPos.X() += (aPartArea.Width() - aSize.Width()) / 2;
		aPos.Y() += (aPartArea.Height()- aSize.Height())/ 2;

		aTitlePos = aPos;
		aTitleSize = aSize;
	}
	else if(mnType == 27 || mnType == 28)
	{
		// AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART or
		// AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE
		Point aClassicTPos(
			aTitlePos.X() + long( aTitleSize.Width() * 0.0735 ),
			aTitlePos.Y() + long( aTitleSize.Height() * 0.083 ));
		Size aClassicTSize(
			long( aTitleSize.Width() * 0.854 ),
			long( aTitleSize.Height() * 0.167 ));
		Point aLPos(aPagePos);
		Size aLSize(aPageInnerSize);
		Point aClassicLPos(
			aLPos.X() + long( aLSize.Width() * 0.0735 ),
			aLPos.Y() + long( aLSize.Height() * 0.472 ));
		Size aClassicLSize(
			long( aLSize.Width() * 0.854 ),
			long( aLSize.Height() * 0.444 ));

		aTitlePos.X() = (aClassicTPos.X() + aClassicTSize.Width()) - aClassicTSize.Height();
		aTitlePos.Y() = aClassicTPos.Y();
		aTitleSize.Width() = aClassicTSize.Height();
		aTitleSize.Height() = (aClassicLPos.Y() + aClassicLSize.Height()) - aClassicTPos.Y();
	}
	else
	{
		aTitlePos.X() += long( aTitleSize.Width() * 0.0735 );
		aTitlePos.Y() += long( aTitleSize.Height() * 0.083 );
		aTitleSize.Width() = long( aTitleSize.Width() * 0.854 );
		aTitleSize.Height() = long( aTitleSize.Height() * 0.167 );
	}

	maTitleRect.SetPos(aTitlePos);
	maTitleRect.SetSize(aTitleSize);

	// layout rectangle aligning
	Point aLayoutPos(aPagePos);
	Size aLayoutSize(aPageInnerSize);

	if(mnType == 21 /* AUTOLAYOUT_NOTES */)
	{
		aLayoutPos.X() += long( aLayoutSize.Width() * 0.0735 );
		aLayoutPos.Y() += long( aLayoutSize.Height() * 0.472 );
		aLayoutSize.Width() = long( aLayoutSize.Width() * 0.854 );
		aLayoutSize.Height() = long( aLayoutSize.Height() * 0.444 );
	}
	else if((mnType >= 22 && mnType <= 26) || (mnType == 31)) // AUTOLAYOUT_HANDOUT
	{
		// keep info for inner area in maPresRect, put info for gap size
		// to maTitleRect position
		mnGapX = (aPageSize.Width() - aPageInnerSize.Width()) / 2;
		mnGapY = (aPageSize.Height() - aPageInnerSize.Height()) / 2;

		if(!mnGapX)
			mnGapX = aPageSize.Width() / 10;

		if(!mnGapY)
			mnGapY = aPageSize.Height() / 10;

		if(mnGapX < aPageInnerSize.Width() / 10)
			mnGapX = aPageInnerSize.Width() / 10;

		if(mnGapY < aPageInnerSize.Height() / 10)
			mnGapY = aPageInnerSize.Height() / 10;
	}
	else if(mnType == 27 || mnType == 28)
	{
		// AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART or
		// AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE
		Point aClassicTPos(
			aTitlePos.X() + long( aTitleSize.Width() * 0.0735 ),
			aTitlePos.Y() + long( aTitleSize.Height() * 0.083 ));
		Size aClassicTSize(
			long( aTitleSize.Width() * 0.854 ),
			long( aTitleSize.Height() * 0.167 ));
		Point aClassicLPos(
			aLayoutPos.X() + long( aLayoutSize.Width() * 0.0735 ),
			aLayoutPos.Y() + long( aLayoutSize.Height() * 0.472 ));
		Size aClassicLSize(
			long( aLayoutSize.Width() * 0.854 ),
			long( aLayoutSize.Height() * 0.444 ));

		aLayoutPos.X() = aClassicLPos.X();
		aLayoutPos.Y() = aClassicTPos.Y();
		aLayoutSize.Width() = (aClassicLPos.X() + aClassicLSize.Width())
			- (aClassicTSize.Height() + (aClassicLPos.Y() - (aClassicTPos.Y() + aClassicTSize.Height())));
		aLayoutSize.Height() = (aClassicLPos.Y() + aClassicLSize.Height()) - aClassicTPos.Y();
	}
    else if( mnType == 32 )
    {
        // AUTOLAYOUT_ONLY_TEXT
        aLayoutPos = aTitlePos;
        aLayoutSize.Width() = aTitleSize.Width();
        aLayoutSize.Height() = long( aLayoutSize.Height() * 0.825 );
    }
	else
	{
		aLayoutPos.X() += long( aLayoutSize.Width() * 0.0735 );
		aLayoutPos.Y() += long( aLayoutSize.Height() * 0.278 );
		aLayoutSize.Width() = long( aLayoutSize.Width() * 0.854 );
		aLayoutSize.Height() = long( aLayoutSize.Height() * 0.630 );
	}

	maPresRect.SetPos(aLayoutPos);
	maPresRect.SetSize(aLayoutSize);
}

DECLARE_LIST(ImpXMLAutoLayoutInfoList, ImpXMLAutoLayoutInfo*)

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

// #110680#
SdXMLExport::SdXMLExport( 
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
	sal_Bool bIsDraw, sal_uInt16 nExportFlags )
:	SvXMLExport( xServiceFactory, MAP_CM, bIsDraw ? XML_DRAWING : XML_PRESENTATION, nExportFlags ),
	mnDocMasterPageCount(0L),
	mnDocDrawPageCount(0L),
	mnShapeStyleInfoIndex(0L),
	mnObjectCount(0L),
	mpPageMasterInfoList(new ImpXMLEXPPageMasterList(1, 4, 4)),
	mpPageMasterUsageList(new ImpXMLEXPPageMasterList(1, 4, 4)),
	mpNotesPageMasterUsageList(new ImpXMLEXPPageMasterList(1, 4, 4)),
	mpHandoutPageMaster(NULL),
	mpAutoLayoutInfoList(new ImpXMLAutoLayoutInfoList(1, 4, 4)),
	mpSdPropHdlFactory(0L),
	mpPropertySetMapper(0L),
	mpPresPagePropsMapper(0L),
	mbIsDraw(bIsDraw),
	mbFamilyGraphicUsed(sal_False),
	mbFamilyPresentationUsed(sal_False),
	msZIndex( GetXMLToken(XML_ZINDEX) ),
	msEmptyPres( RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ),
	msModel( RTL_CONSTASCII_USTRINGPARAM("Model") ),
	msStartShape( RTL_CONSTASCII_USTRINGPARAM("StartShape") ),
	msEndShape( RTL_CONSTASCII_USTRINGPARAM("EndShape") ),
	msPageLayoutNames( RTL_CONSTASCII_USTRINGPARAM("PageLayoutNames") )
{


}

// XExporter
void SAL_CALL SdXMLExport::setSourceDocument( const Reference< lang::XComponent >& xDoc )
	throw(lang::IllegalArgumentException, uno::RuntimeException)
{
	SvXMLExport::setSourceDocument( xDoc );

	const OUString aEmpty;

	// prepare factory parts
	mpSdPropHdlFactory = new XMLSdPropHdlFactory( GetModel(), *this );
	if(mpSdPropHdlFactory)
	{
		// set lock to avoid deletion
		mpSdPropHdlFactory->acquire();

		// build one ref
		const UniReference< XMLPropertyHandlerFactory > aFactoryRef = mpSdPropHdlFactory;

		// construct PropertySetMapper
		UniReference < XMLPropertySetMapper > xMapper =	new XMLShapePropertySetMapper( aFactoryRef);

		mpPropertySetMapper = new XMLShapeExportPropertyMapper( xMapper, (XMLTextListAutoStylePool*)&GetTextParagraphExport()->GetListAutoStylePool(), *this );
		// set lock to avoid deletion
		mpPropertySetMapper->acquire();

		// chain text attributes
		mpPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));

		// construct PresPagePropsMapper
		xMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLSDPresPageProps, aFactoryRef);

		mpPresPagePropsMapper = new XMLPageExportPropertyMapper( xMapper, *this  );
		if(mpPresPagePropsMapper)
		{
			// set lock to avoid deletion
			mpPresPagePropsMapper->acquire();
		}
	}

	// add family name
  	GetAutoStylePool()->AddFamily(
		XML_STYLE_FAMILY_SD_GRAPHICS_ID,
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)),
  		GetPropertySetMapper(),
  		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX)));
	GetAutoStylePool()->AddFamily(
		XML_STYLE_FAMILY_SD_PRESENTATION_ID,
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_PRESENTATION_NAME)),
  		GetPropertySetMapper(),
  		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_PRESENTATION_PREFIX)));
	GetAutoStylePool()->AddFamily(
		XML_STYLE_FAMILY_SD_DRAWINGPAGE_ID,
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME)),
  		GetPresPagePropsMapper(),
  		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_DRAWINGPAGE_PREFIX)));
	// prepare access to styles
	Reference< style::XStyleFamiliesSupplier > xFamSup( GetModel(), UNO_QUERY );
	if(xFamSup.is())
	{
		mxDocStyleFamilies = xFamSup->getStyleFamilies();
	}

	// prepare access to master pages
	Reference < drawing::XMasterPagesSupplier > xMasterPagesSupplier(GetModel(), UNO_QUERY);
	if(xMasterPagesSupplier.is())
	{
		mxDocMasterPages = mxDocMasterPages.query( xMasterPagesSupplier->getMasterPages() );
		if(mxDocMasterPages.is())
		{
			mnDocMasterPageCount = mxDocMasterPages->getCount();
			maMasterPagesStyleNames.insert( maMasterPagesStyleNames.begin(), mnDocMasterPageCount, aEmpty );
		}
	}

	// prepare access to draw pages
	Reference <XDrawPagesSupplier> xDrawPagesSupplier(GetModel(), UNO_QUERY);
	if(xDrawPagesSupplier.is())
	{
		mxDocDrawPages = mxDocDrawPages.query( xDrawPagesSupplier->getDrawPages() );
		if(mxDocDrawPages.is())
		{
			mnDocDrawPageCount = mxDocDrawPages->getCount();
			maDrawPagesStyleNames.insert( maDrawPagesStyleNames.begin(), mnDocDrawPageCount, aEmpty );
			maDrawNotesPagesStyleNames.insert( maDrawNotesPagesStyleNames.begin(), mnDocDrawPageCount, aEmpty );
			if( !mbIsDraw )
				maDrawPagesAutoLayoutNames.realloc( mnDocDrawPageCount + 1 );

			HeaderFooterPageSettingsImpl aEmptySettings;
			maDrawPagesHeaderFooterSettings.insert( maDrawPagesHeaderFooterSettings.begin(), mnDocDrawPageCount, aEmptySettings );
			maDrawNotesPagesHeaderFooterSettings.insert( maDrawNotesPagesHeaderFooterSettings.begin(), mnDocDrawPageCount, aEmptySettings );
		}
	}

	// #82003# count all draw objects for use with progress bar.
	// #88245# init mnObjectCount once, use counter itself as flag. It
	// is initialized to 0.
	if(!mnObjectCount)
	{
		if( IsImpress() )
		{
 			// #91587# add handout master count
			Reference<presentation::XHandoutMasterSupplier> xHandoutSupp(GetModel(), UNO_QUERY);
			if(xHandoutSupp.is())
			{
				Reference<XDrawPage> xHandoutPage(xHandoutSupp->getHandoutMasterPage());
				if(xHandoutPage.is())
				{
					Reference<drawing::XShapes> xShapes(xHandoutPage, UNO_QUERY);
					if(xShapes.is() && xShapes->getCount())
					{
						mnObjectCount += ImpRecursiveObjectCount(xShapes);
					}
				}
			}
		}

		if(mxDocMasterPages.is())
		{
			for(sal_Int32 a(0); a < mnDocMasterPageCount; a++)
			{
				Any aAny(mxDocMasterPages->getByIndex(a));
				Reference< drawing::XShapes > xMasterPage;

				if((aAny >>= xMasterPage) && xMasterPage.is())
				{
					mnObjectCount += ImpRecursiveObjectCount(xMasterPage);
				}

				if( IsImpress() )
				{
					// #91587# take notes pages from master pages into account
					Reference<presentation::XPresentationPage> xPresPage;
					if((aAny >>= xPresPage) && xPresPage.is())
					{
						Reference<XDrawPage> xNotesPage(xPresPage->getNotesPage());
						if(xNotesPage.is())
						{
							Reference<drawing::XShapes> xShapes(xNotesPage, UNO_QUERY);
							if(xShapes.is() && xShapes->getCount())
							{
								mnObjectCount += ImpRecursiveObjectCount(xShapes);
							}
						}
					}
				}
			}
		}

		if(mxDocDrawPages.is())
		{
			for(sal_Int32 a(0); a < mnDocDrawPageCount; a++)
			{
				Any aAny(mxDocDrawPages->getByIndex(a));
				Reference< drawing::XShapes > xPage;

				if((aAny >>= xPage) && xPage.is())
				{
					mnObjectCount += ImpRecursiveObjectCount(xPage);
				}

				if( IsImpress() )
				{
					// #91587# take notes pages from draw pages into account
					Reference<presentation::XPresentationPage> xPresPage;
					if((aAny >>= xPresPage) && xPresPage.is())
					{
						Reference<XDrawPage> xNotesPage(xPresPage->getNotesPage());
						if(xNotesPage.is())
						{
							Reference<drawing::XShapes> xShapes(xNotesPage, UNO_QUERY);
							if(xShapes.is() && xShapes->getCount())
							{
								mnObjectCount += ImpRecursiveObjectCount(xShapes);
							}
						}
					}
				}
			}
		}

		// #82003# init progress bar
		GetProgressBarHelper()->SetReference(mnObjectCount);
	}

	// add namespaces
	_GetNamespaceMap().Add(
		GetXMLToken(XML_NP_PRESENTATION),
        GetXMLToken(XML_N_PRESENTATION), 
		XML_NAMESPACE_PRESENTATION);

	_GetNamespaceMap().Add(
		GetXMLToken(XML_NP_SMIL),
        GetXMLToken(XML_N_SMIL_COMPAT), 
		XML_NAMESPACE_SMIL);

	_GetNamespaceMap().Add(
		GetXMLToken(XML_NP_ANIMATION),
        GetXMLToken(XML_N_ANIMATION), 
		XML_NAMESPACE_ANIMATION);

    if( getDefaultVersion() > SvtSaveOptions::ODFVER_012 )
    {
	    _GetNamespaceMap().Add(
		    GetXMLToken(XML_NP_OFFICE_EXT),
            GetXMLToken(XML_N_OFFICE_EXT), 
		    XML_NAMESPACE_OFFICE_EXT);

	    _GetNamespaceMap().Add(
		    GetXMLToken(XML_NP_DRAW_EXT),
            GetXMLToken(XML_N_DRAW_EXT), 
		    XML_NAMESPACE_DRAW_EXT);
	}

	GetShapeExport()->enableLayerExport();

	// #88546# enable progress bar increments
	GetShapeExport()->enableHandleProgressBar();
}

//////////////////////////////////////////////////////////////////////////////
// #82003# helper function for recursive object count
sal_uInt32 SdXMLExport::ImpRecursiveObjectCount(Reference< drawing::XShapes > xShapes)
{
	sal_uInt32 nRetval(0L);

	if(xShapes.is())
	{
		sal_Int32 nCount = xShapes->getCount();

		for(sal_Int32 a(0L); a < nCount; a++)
		{
			Any aAny(xShapes->getByIndex(a));
			Reference< drawing::XShapes > xGroup;

			if((aAny >>= xGroup) && xGroup.is())
			{
				// #93180# count group objects, too.
				nRetval += 1 + ImpRecursiveObjectCount(xGroup);
			}
			else
			{
				nRetval++;
			}
		}
	}

	return nRetval;
}

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

__EXPORT SdXMLExport::~SdXMLExport()
{
	// cleanup factory, decrease refcount. Should lead to destruction.
	if(mpSdPropHdlFactory)
	{
		mpSdPropHdlFactory->release();
		mpSdPropHdlFactory = 0L;
	}

	// cleanup mapper, decrease refcount. Should lead to destruction.
	if(mpPropertySetMapper)
	{
		mpPropertySetMapper->release();
		mpPropertySetMapper = 0L;
	}

	// cleanup presPage mapper, decrease refcount. Should lead to destruction.
	if(mpPresPagePropsMapper)
	{
		mpPresPagePropsMapper->release();
		mpPresPagePropsMapper = 0L;
	}

	// clear evtl. temporary page master infos
	if(mpPageMasterInfoList)
	{
		while(mpPageMasterInfoList->Count())
			delete mpPageMasterInfoList->Remove(mpPageMasterInfoList->Count() - 1L);
		delete mpPageMasterInfoList;
		mpPageMasterInfoList = 0L;
	}
	if(mpPageMasterUsageList)
	{
		delete mpPageMasterUsageList;
		mpPageMasterUsageList = 0L;
	}
	if(mpNotesPageMasterUsageList)
	{
		delete mpNotesPageMasterUsageList;
		mpNotesPageMasterUsageList = 0L;
	}

	// clear auto-layout infos
	if(mpAutoLayoutInfoList)
	{
		while(mpAutoLayoutInfoList->Count())
			delete mpAutoLayoutInfoList->Remove(mpAutoLayoutInfoList->Count() - 1L);
		delete mpAutoLayoutInfoList;
		mpAutoLayoutInfoList = 0L;
	}

// #82003# status indicator stop is called exclusively 
// from SdXMLFilter::Export() now.
//
// stop progress view
//	if(GetStatusIndicator().is())
//	{
//		GetStatusIndicator()->end();
//		GetStatusIndicator()->reset();
//	}
}

//////////////////////////////////////////////////////////////////////////////
// to get default values in XPropertySet use this wrapper class

class ImpDefaultMapper : public ::cppu::WeakAggImplHelper1< beans::XPropertySet >
{
	Reference< beans::XPropertyState >		mxState;
	Reference< beans::XPropertySet >		mxSet;

public:
	ImpDefaultMapper( Reference< beans::XPropertyState >& rxState );

	// Methods
	virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(uno::RuntimeException);
	virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException);
	virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);

	// empty implementations
	virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< beans::XPropertyChangeListener >& xListener ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
	virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< beans::XPropertyChangeListener >& aListener ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
	virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< beans::XVetoableChangeListener >& aListener ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
	virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< beans::XVetoableChangeListener >& aListener ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
};

ImpDefaultMapper::ImpDefaultMapper( Reference< beans::XPropertyState >& rxState )
:	mxState( rxState ),
	mxSet( rxState, UNO_QUERY )
{
}

Reference< beans::XPropertySetInfo > SAL_CALL ImpDefaultMapper::getPropertySetInfo() throw(uno::RuntimeException)
{
	return mxSet->getPropertySetInfo();
}

void SAL_CALL ImpDefaultMapper::setPropertyValue( const OUString& aPropertyName, const Any& /*aValue*/ ) throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
{
	mxState->setPropertyToDefault( aPropertyName /*, aValue */ );
}

Any SAL_CALL ImpDefaultMapper::getPropertyValue( const OUString& PropertyName ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
	return mxState->getPropertyDefault(  PropertyName  );
}

// empty implementations
void SAL_CALL ImpDefaultMapper::addPropertyChangeListener( const OUString&, const Reference< beans::XPropertyChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
void SAL_CALL ImpDefaultMapper::removePropertyChangeListener( const OUString&, const Reference< beans::XPropertyChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
void SAL_CALL ImpDefaultMapper::addVetoableChangeListener( const OUString&, const Reference< beans::XVetoableChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
void SAL_CALL ImpDefaultMapper::removeVetoableChangeListener( const OUString&, const Reference< beans::XVetoableChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}

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

/* moved to shapeexport.cxx
void SdXMLExport::ImpWriteObjGraphicStyleInfos()
{
	XMLStyleExport aStEx(*this, OUString(), GetAutoStylePool().get());
	const UniReference< SvXMLExportPropertyMapper > aMapperRef( GetPropertySetMapper() );

	// write graphic family default style
	Reference< lang::XMultiServiceFactory > xFact( GetModel(), UNO_QUERY );
	if( xFact.is() )
	{
		try
		{
			Reference< beans::XPropertySet > xDefaults( xFact->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Defaults") ) ), UNO_QUERY );
			if( xDefaults.is() )
			{
				aStEx.exportDefaultStyle( xDefaults, OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), aMapperRef );

				// write graphic family styles
				aStEx.exportStyleFamily(XML_STYLE_FAMILY_SD_GRAPHICS_NAME, OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), aMapperRef, sal_False, XML_STYLE_FAMILY_SD_GRAPHICS_ID);
			}
		}
		catch( lang::ServiceNotRegisteredException& )
		{
		}
	}
}
*/
//////////////////////////////////////////////////////////////////////////////

void SdXMLExport::ImpPrepAutoLayoutInfos()
{
	if(IsImpress())
	{
		OUString aStr;

		Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
		if( xHandoutSupp.is() )
		{
			Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
			if( xHandoutPage.is() )
			{
				if(ImpPrepAutoLayoutInfo(xHandoutPage, aStr))
					maDrawPagesAutoLayoutNames[0] = aStr;
			}
		}

		// prepare name creation
        for (sal_Int32 nCnt = 0; nCnt < mnDocDrawPageCount; nCnt++)
		{
			Any aAny(mxDocDrawPages->getByIndex(nCnt));
			Reference<XDrawPage> xDrawPage;

			if((aAny >>= xDrawPage) && xDrawPage.is())
			{
				if(ImpPrepAutoLayoutInfo(xDrawPage, aStr))
					maDrawPagesAutoLayoutNames[nCnt+1] = aStr;
			}
		}
	}
}

sal_Bool SdXMLExport::ImpPrepAutoLayoutInfo(const Reference<XDrawPage>& xPage, OUString& rName)
{
	rName = OUString();
	sal_Bool bRetval(sal_False);

	Reference <beans::XPropertySet> xPropSet(xPage, UNO_QUERY);
	if(xPropSet.is())
	{
		sal_uInt16 nType = sal_uInt16();
		Any aAny;

		aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Layout")));
		if(aAny >>= nType)
		{
			if(ImpXMLAutoLayoutInfo::IsCreateNecessary(nType))
			{
				ImpXMLEXPPageMasterInfo* pInfo = 0L;

				// get master-page info
				Reference < drawing::XMasterPageTarget > xMasterPageInt(xPage, UNO_QUERY);
				if(xMasterPageInt.is())
				{
					Reference<XDrawPage> xUsedMasterPage(xMasterPageInt->getMasterPage());
					if(xUsedMasterPage.is())
					{
						Reference < container::XNamed > xMasterNamed(xUsedMasterPage, UNO_QUERY);
						if(xMasterNamed.is())
						{
							OUString sMasterPageName = xMasterNamed->getName();
							pInfo = ImpGetPageMasterInfoByName(sMasterPageName);
						}
					}
				}

				// create entry and look for existence
				ImpXMLAutoLayoutInfo* pNew = new ImpXMLAutoLayoutInfo(nType, pInfo);
				sal_Bool bDidExist(sal_False);

				for(sal_uInt32 nCnt = 0L; !bDidExist && nCnt < mpAutoLayoutInfoList->Count(); nCnt++)
				{
					if(*mpAutoLayoutInfoList->GetObject(nCnt) == *pNew)
					{
						delete pNew;
						pNew = mpAutoLayoutInfoList->GetObject(nCnt);
						bDidExist = sal_True;
					}
				}

				if(!bDidExist)
				{
					mpAutoLayoutInfoList->Insert(pNew, LIST_APPEND);
					OUString sNewName = OUString(RTL_CONSTASCII_USTRINGPARAM("AL"));
					sNewName += OUString::valueOf(sal_Int32(mpAutoLayoutInfoList->Count() - 1));
					sNewName += OUString(RTL_CONSTASCII_USTRINGPARAM("T"));
					sNewName += OUString::valueOf(sal_Int32(nType));
					pNew->SetLayoutName(sNewName);
				}

				rName = pNew->GetLayoutName();
				bRetval = sal_True;
			}
		}
	}

	return bRetval;
}

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

void SdXMLExport::ImpWriteAutoLayoutInfos()
{
	if(mpAutoLayoutInfoList->Count())
	{
		for(sal_uInt32 nCnt = 0L; nCnt < mpAutoLayoutInfoList->Count(); nCnt++)
		{
			ImpXMLAutoLayoutInfo* pInfo = mpAutoLayoutInfoList->GetObject(nCnt);
			if(pInfo)
			{
				// prepare presentation-page layout attributes, style-name
				AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, pInfo->GetLayoutName());

				// write draw-style attributes
				SvXMLElementExport aDSE(*this, XML_NAMESPACE_STYLE, XML_PRESENTATION_PAGE_LAYOUT, sal_True, sal_True);

				// write presentation placeholders
				switch(pInfo->GetLayoutType())
				{
					case 0 : // AUTOLAYOUT_TITLE
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderSubtitle, pInfo->GetPresRectangle());
						break;
					}
					case 1 : // AUTOLAYOUT_ENUM
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, pInfo->GetPresRectangle());
						break;
					}
					case 2 : // AUTOLAYOUT_CHART
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, pInfo->GetPresRectangle());
						break;
					}
					case 3 : // AUTOLAYOUT_2TEXT
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
						break;
					}
					case 4 : // AUTOLAYOUT_TEXTCHART
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aRight);
						break;
					}
					case 6 : // AUTOLAYOUT_TEXTCLIP
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aRight);
						break;
					}
					case 7 : // AUTOLAYOUT_CHARTTEXT
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
						break;
					}
					case 8 : // AUTOLAYOUT_TAB
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTable, pInfo->GetPresRectangle());
						break;
					}
					case 9 : // AUTOLAYOUT_CLIPTEXT
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
						break;
					}
					case 10 : // AUTOLAYOUT_TEXTOBJ
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRight);
						break;
					}
					case 11 : // AUTOLAYOUT_OBJ
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, pInfo->GetPresRectangle());
						break;
					}
					case 12 : // AUTOLAYOUT_TEXT2OBJ
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRightTop(aLeft);
						aRightTop.Left() = long(aRightTop.Left() + aRightTop.GetWidth() * 1.05);
						aRightTop.setHeight(long(aRightTop.GetHeight() * 0.477));
						Rectangle aRightBottom(aRightTop);
						aRightBottom.Top() = long(aRightBottom.Top() + aRightBottom.GetHeight() * 1.095);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRightTop);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRightBottom);
						break;
					}
					case 13 : // AUTOLAYOUT_OBJTEXT
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
						break;
					}
					case 14 : // AUTOLAYOUT_OBJOVERTEXT
					{
						Rectangle aTop(pInfo->GetPresRectangle());
						aTop.setHeight(long(aTop.GetHeight() * 0.477));
						Rectangle aBottom(aTop);
						aBottom.Top() = long(aBottom.Top() + aBottom.GetHeight() * 1.095);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTop);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aBottom);
						break;
					}
					case 15 : // AUTOLAYOUT_2OBJTEXT
					{
						Rectangle aLeftTop(pInfo->GetPresRectangle());
						aLeftTop.setWidth(long(aLeftTop.GetWidth() * 0.488));
						Rectangle aRight(aLeftTop);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);
						aLeftTop.setHeight(long(aLeftTop.GetHeight() * 0.477));
						Rectangle aLeftBottom(aLeftTop);
						aLeftBottom.Top() = long(aLeftBottom.Top() + aLeftBottom.GetHeight() * 1.095);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeftTop);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeftBottom);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
						break;
					}
					case 16 : // AUTOLAYOUT_2OBJOVERTEXT
					{
						Rectangle aTopLeft(pInfo->GetPresRectangle());
						aTopLeft.setHeight(long(aTopLeft.GetHeight() * 0.477));
						Rectangle aBottom(aTopLeft);
						aBottom.Top() = long(aBottom.Top() + aBottom.GetHeight() * 1.095);
						aTopLeft.setWidth(long(aTopLeft.GetWidth() * 0.488));
						Rectangle aTopRight(aTopLeft);
						aTopRight.Left() = long(aTopRight.Left() + aTopRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopRight);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aBottom);
						break;
					}
					case 17 : // AUTOLAYOUT_TEXTOVEROBJ
					{
						Rectangle aTop(pInfo->GetPresRectangle());
						aTop.setHeight(long(aTop.GetHeight() * 0.477));
						Rectangle aBottom(aTop);
						aBottom.Top() = long(aBottom.Top() + aBottom.GetHeight() * 1.095);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aTop);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottom);
						break;
					}
					case 18 : // AUTOLAYOUT_4OBJ
					{
						Rectangle aTopLeft(pInfo->GetPresRectangle());
						aTopLeft.setHeight(long(aTopLeft.GetHeight() * 0.477));
						aTopLeft.setWidth(long(aTopLeft.GetWidth() * 0.488));
						Rectangle aBottomLeft(aTopLeft);
						aBottomLeft.Top() = long(aBottomLeft.Top() + aBottomLeft.GetHeight() * 1.095);
						Rectangle aTopRight(aTopLeft);
						aTopRight.Left() = long(aTopRight.Left() + aTopRight.GetWidth() * 1.05);
						Rectangle aBottomRight(aTopRight);
						aBottomRight.Top() = long(aBottomRight.Top() + aBottomRight.GetHeight() * 1.095);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopRight);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottomLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottomRight);
						break;
					}
					case 19 : // AUTOLAYOUT_ONLY_TITLE
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						break;
					}
					case 21 : // AUTOLAYOUT_NOTES
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderPage, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderNotes, pInfo->GetPresRectangle());
						break;
					}
					case 22 : // AUTOLAYOUT_HANDOUT1
					case 23 : // AUTOLAYOUT_HANDOUT2
					case 24 : // AUTOLAYOUT_HANDOUT3
					case 25 : // AUTOLAYOUT_HANDOUT4
					case 26 : // AUTOLAYOUT_HANDOUT6
					case 31 : // AUTOLAYOUT_HANDOUT9
					{
						sal_Int32 nColCnt, nRowCnt;
						sal_Int32 nGapX = pInfo->GetGapX();
						sal_Int32 nGapY = pInfo->GetGapY();

						switch(pInfo->GetLayoutType())
						{
							case 22 : nColCnt = 1; nRowCnt = 1; break;
							case 23 : nColCnt = 1; nRowCnt = 2; break;
							case 24 : nColCnt = 1; nRowCnt = 3; break;
							case 25 : nColCnt = 2; nRowCnt = 2; break;
							case 26 : nColCnt = 3; nRowCnt = 2; break;
							case 31 : nColCnt = 3; nRowCnt = 3; break;
							default:  nColCnt = 0; nRowCnt = 0; break;  // FIXME - What is correct values?
						}

						Size aPartSize(pInfo->GetTitleRectangle().GetSize());
						Point aPartPos(pInfo->GetTitleRectangle().TopLeft());

						if(aPartSize.Width() > aPartSize.Height())
						{
							sal_Int32 nZwi(nColCnt);
							nColCnt = nRowCnt;
							nRowCnt = nZwi;
						}

						aPartSize.Width() = (aPartSize.Width() - ((nColCnt - 1) * nGapX)) / nColCnt;
						aPartSize.Height() = (aPartSize.Height() - ((nRowCnt - 1) * nGapY)) / nRowCnt;

						Point aTmpPos(aPartPos);

                        for (sal_Int32 a = 0; a < nRowCnt; a++)
						{
							aTmpPos.X() = aPartPos.X();

                            for (sal_Int32 b = 0; b < nColCnt; b++)
							{
								Rectangle aTmpRect(aTmpPos, aPartSize);

								ImpWriteAutoLayoutPlaceholder(XmlPlaceholderHandout, aTmpRect);
								aTmpPos.X() += aPartSize.Width() + nGapX;
							}

							aTmpPos.Y() += aPartSize.Height() + nGapY;
						}
						break;
					}
					case 27 : // AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART
					{
						Rectangle aTop(pInfo->GetPresRectangle());
						aTop.setHeight(long(aTop.GetHeight() * 0.488));
						Rectangle aBottom(aTop);
						aBottom.Top() = long(aBottom.Top() + aBottom.GetHeight() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, aTop);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aBottom);
						break;
					}
					case 28 : // AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, pInfo->GetPresRectangle());
						break;
					}
					case 29 : // AUTOLAYOUT_TITLE_VERTICAL_OUTLINE
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, pInfo->GetPresRectangle());
						break;
					}
					case 30 : // AUTOLAYOUT_TITLE_VERTICAL_OUTLINE_CLIPART
					{
						Rectangle aLeft(pInfo->GetPresRectangle());
						aLeft.setWidth(long(aLeft.GetWidth() * 0.488));
						Rectangle aRight(aLeft);
						aRight.Left() = long(aRight.Left() + aRight.GetWidth() * 1.05);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, aRight);
						break;
					}
					case 32 : // AUTOLAYOUT_TITLE
					{
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderSubtitle, pInfo->GetPresRectangle());
						break;
					}

                    case 33 : // AUTOLAYOUT_4CLIPART
					{
						Rectangle aTopLeft(pInfo->GetPresRectangle());
						aTopLeft.setHeight(long(aTopLeft.GetHeight() * 0.477));
						aTopLeft.setWidth(long(aTopLeft.GetWidth() * 0.488));
						Rectangle aBottomLeft(aTopLeft);
						aBottomLeft.Top() = long(aBottomLeft.Top() + aBottomLeft.GetHeight() * 1.095);
						Rectangle aTopRight(aTopLeft);
						aTopRight.Left() = long(aTopRight.Left() + aTopRight.GetWidth() * 1.05);
						Rectangle aBottomRight(aTopRight);
						aBottomRight.Top() = long(aBottomRight.Top() + aBottomRight.GetHeight() * 1.095);

						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopRight);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomRight);
						break;
					}

                    case 34 : // AUTOLAYOUT_6CLIPART
					{
						Rectangle aTopLeft(pInfo->GetPresRectangle());
						aTopLeft.setHeight(long(aTopLeft.GetHeight() * 0.477));
						aTopLeft.setWidth(long(aTopLeft.GetWidth() * 0.322));	
						Rectangle aTopCenter(aTopLeft);
						aTopCenter.Left() = long(aTopCenter.Left() + aTopCenter.GetWidth() * 1.05);
						Rectangle aTopRight(aTopLeft);
						aTopRight.Left() = long(aTopRight.Left() + aTopRight.GetWidth() * 2 * 1.05);
					
						Rectangle aBottomLeft(aTopLeft);
						aBottomLeft.Top() = long(aBottomLeft.Top() + aBottomLeft.GetHeight() * 1.095);
						Rectangle aBottomCenter(aTopCenter);
						aBottomCenter.Top() = long(aBottomCenter.Top() + aBottomCenter.GetHeight() * 1.095);
						Rectangle aBottomRight(aTopRight);
						aBottomRight.Top() = long(aBottomRight.Top() + aBottomRight.GetHeight() * 1.095);
												
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopCenter);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopRight);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomLeft);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomCenter);
						ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomRight);
						break;
					}
					default:
					{
						DBG_ERROR("XMLEXP: unknown autolayout export");
						break;
					}
				}
			}
		}
	}
}

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

void SdXMLExport::ImpWriteAutoLayoutPlaceholder(XmlPlaceholder ePl, const Rectangle& rRect)
{
	OUString aStr;
	OUStringBuffer sStringBuffer;

	// prepare presentation-placeholder attributes, presentation:object
	switch(ePl)
	{
		case XmlPlaceholderTitle: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("title")); break;
		case XmlPlaceholderOutline: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("outline")); break;
		case XmlPlaceholderSubtitle: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("subtitle")); break;
		case XmlPlaceholderText: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("text")); break;
		case XmlPlaceholderGraphic: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("graphic")); break;
		case XmlPlaceholderObject: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("object")); break;
		case XmlPlaceholderChart: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("chart")); break;
		case XmlPlaceholderOrgchart: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("orgchart")); break;
		case XmlPlaceholderTable: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("table")); break;
		case XmlPlaceholderPage: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("page")); break;
		case XmlPlaceholderNotes: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("notes")); break;
		case XmlPlaceholderHandout: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("handout")); break;
		case XmlPlaceholderVerticalTitle: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("vertical_title")); break;
		case XmlPlaceholderVerticalOutline: aStr = OUString(RTL_CONSTASCII_USTRINGPARAM("vertical_outline")); break;
	}

	AddAttribute(XML_NAMESPACE_PRESENTATION, XML_OBJECT, aStr);

	// svg:x,y,width,height
	GetMM100UnitConverter().convertMeasure(sStringBuffer, rRect.Left());
	aStr = sStringBuffer.makeStringAndClear();
	AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr);

	GetMM100UnitConverter().convertMeasure(sStringBuffer, rRect.Top());
	aStr = sStringBuffer.makeStringAndClear();
	AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr);

	GetMM100UnitConverter().convertMeasure(sStringBuffer, rRect.GetWidth());
	aStr = sStringBuffer.makeStringAndClear();
	AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr);

	GetMM100UnitConverter().convertMeasure(sStringBuffer, rRect.GetHeight());
	aStr = sStringBuffer.makeStringAndClear();
	AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr);

	// write presentation-placeholder
	SvXMLElementExport aPPL(*this, XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, sal_True, sal_True);
}

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

ImpXMLEXPPageMasterInfo* SdXMLExport::ImpGetOrCreatePageMasterInfo( Reference< XDrawPage > xMasterPage )
{
	bool bDoesExist = false;

	ImpXMLEXPPageMasterInfo* pNewInfo = new ImpXMLEXPPageMasterInfo(*this, xMasterPage);

	// compare with prev page-master infos
	for(sal_uInt32 a = 0; !bDoesExist && a < mpPageMasterInfoList->Count(); a++)
	{
		if(mpPageMasterInfoList->GetObject(a)
			&& *mpPageMasterInfoList->GetObject(a) == *pNewInfo)
		{
			delete pNewInfo;
			pNewInfo = mpPageMasterInfoList->GetObject(a);
			bDoesExist = true;
		}
	}
	// add entry when not found same page-master infos
	if(!bDoesExist)
		mpPageMasterInfoList->Insert(pNewInfo, LIST_APPEND);

	return pNewInfo;
}

void SdXMLExport::ImpPrepPageMasterInfos()
{
	if( IsImpress() )
	{
		// create page master info for handout master page

		Reference< XHandoutMasterSupplier > xHMS( GetModel(), UNO_QUERY );
		if( xHMS.is() )
		{
			Reference< XDrawPage > xMasterPage( xHMS->getHandoutMasterPage() );
			if( xMasterPage.is() )
				mpHandoutPageMaster = ImpGetOrCreatePageMasterInfo(xMasterPage);
		}
	}

	// create page master infos for master pages
	if(mnDocMasterPageCount)
	{
		// look for needed page-masters, create these
        for (sal_Int32 nMPageId = 0; nMPageId < mnDocMasterPageCount; nMPageId++)
		{
			Reference< XDrawPage > xMasterPage( mxDocMasterPages->getByIndex(nMPageId), UNO_QUERY );
			ImpXMLEXPPageMasterInfo* pNewInfo = 0L;

			if(xMasterPage.is())
				pNewInfo = ImpGetOrCreatePageMasterInfo(xMasterPage);

			mpPageMasterUsageList->Insert(pNewInfo, LIST_APPEND);

			// look for page master of handout page
			if(IsImpress())
			{
				pNewInfo = NULL;
				Reference< presentation::XPresentationPage > xPresPage(xMasterPage, UNO_QUERY);
				if(xPresPage.is())
				{
					Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
					if(xNotesPage.is())
					{
						pNewInfo = ImpGetOrCreatePageMasterInfo(xNotesPage);
					}
				}
				mpNotesPageMasterUsageList->Insert( pNewInfo, LIST_APPEND );
			}
		}
	}
}

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

void SdXMLExport::ImpWritePageMasterInfos()
{
	// write created page-masters, create names for these
	for(sal_uInt32 nCnt = 0L; nCnt < mpPageMasterInfoList->Count(); nCnt++)
	{
		ImpXMLEXPPageMasterInfo* pInfo = mpPageMasterInfoList->GetObject(nCnt);
		if(pInfo)
		{
			// create name
			OUString sNewName = OUString(RTL_CONSTASCII_USTRINGPARAM("PM"));

			sNewName += OUString::valueOf((sal_Int32)nCnt);
			pInfo->SetName(sNewName);

			// prepare page-master attributes
			OUString sString;
			OUStringBuffer sStringBuffer;

			sString = sNewName;
			AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sString);

			// write page-layout
			SvXMLElementExport aPME(*this, XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT, sal_True, sal_True);

			// prepare style:properties inside page-master
			GetMM100UnitConverter().convertMeasure(sStringBuffer, pInfo->GetBorderTop());
			sString = sStringBuffer.makeStringAndClear();
			AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_TOP, sString);

			GetMM100UnitConverter().convertMeasure(sStringBuffer, pInfo->GetBorderBottom());
			sString = sStringBuffer.makeStringAndClear();
			AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_BOTTOM, sString);

			GetMM100UnitConverter().convertMeasure(sStringBuffer, pInfo->GetBorderLeft());
			sString = sStringBuffer.makeStringAndClear();
			AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_LEFT, sString);

			GetMM100UnitConverter().convertMeasure(sStringBuffer, pInfo->GetBorderRight());
			sString = sStringBuffer.makeStringAndClear();
			AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_RIGHT, sString);

			GetMM100UnitConverter().convertMeasure(sStringBuffer, pInfo->GetWidth());
			sString = sStringBuffer.makeStringAndClear();
			AddAttribute(XML_NAMESPACE_FO, XML_PAGE_WIDTH, sString);

			GetMM100UnitConverter().convertMeasure(sStringBuffer, pInfo->GetHeight());
			sString = sStringBuffer.makeStringAndClear();
			AddAttribute(XML_NAMESPACE_FO, XML_PAGE_HEIGHT, sString);

			if(pInfo->GetOrientation() == view::PaperOrientation_PORTRAIT)
				AddAttribute(XML_NAMESPACE_STYLE, XML_PRINT_ORIENTATION, XML_PORTRAIT);
			else
				AddAttribute(XML_NAMESPACE_STYLE, XML_PRINT_ORIENTATION, XML_LANDSCAPE);

			// write style:properties
			SvXMLElementExport aPMF(*this, XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_PROPERTIES, sal_True, sal_True);
		}
	}
}

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

ImpXMLEXPPageMasterInfo* SdXMLExport::ImpGetPageMasterInfoByName(const OUString& rName)
{
	if(rName.getLength() && mpPageMasterInfoList->Count())
	{
		for(sal_uInt32 nCnt = 0L; nCnt < mpPageMasterInfoList->Count(); nCnt++)
		{
			ImpXMLEXPPageMasterInfo* pInfo = mpPageMasterInfoList->GetObject(nCnt);
			if(pInfo)
			{
				if(pInfo->GetMasterPageName().getLength() && rName.equals(pInfo->GetMasterPageName()))
				{
					return pInfo;
				}
			}
		}
	}
	return 0L;
}

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

void SdXMLExport::ImpPrepDrawPageInfos()
{
	// create draw:style-name entries for page export
	// containing presentation page attributes AND background attributes
	// fixed family for page-styles is "drawing-page" (XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME)

	sal_Int32 nCnt;
	for(nCnt = 0; nCnt < mnDocDrawPageCount; nCnt++)
	{
		Reference<XDrawPage> xDrawPage;
		mxDocDrawPages->getByIndex(nCnt) >>= xDrawPage;
		maDrawPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xDrawPage );

		Reference< presentation::XPresentationPage > xPresPage(xDrawPage, UNO_QUERY);
		if(xPresPage.is())
		{
			maDrawNotesPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xPresPage->getNotesPage(), false );

			maDrawPagesHeaderFooterSettings[nCnt] = ImpPrepDrawPageHeaderFooterDecls( xDrawPage );
			maDrawNotesPagesHeaderFooterSettings[nCnt] = ImpPrepDrawPageHeaderFooterDecls( xPresPage->getNotesPage() );
		}
	}
}

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

static OUString findOrAppendImpl( std::vector< OUString >& rVector, const OUString& rText, const sal_Char* pPrefix )
{
	// search rVector if there is already a string that equals rText
	std::vector< OUString >::iterator aIter;
	sal_Int32 nIndex;
	for( nIndex = 1, aIter = rVector.begin(); aIter != rVector.end(); aIter++, nIndex++ )
	{
		if( (*aIter) == rText )
			break;
	}

	// if nothing is found, append the string at the end of rVector
	if( aIter == rVector.end() )
		rVector.push_back( rText );

	// create a reference string with pPrefix and the index of the
	// found or created rText
	OUString aStr( OUString::createFromAscii( pPrefix ) );
	aStr += OUString::valueOf( nIndex );
	return aStr;
}

static OUString findOrAppendImpl( std::vector< DateTimeDeclImpl >& rVector, const OUString& rText, sal_Bool bFixed, sal_Int32 nFormat, const sal_Char* pPrefix )
{
	// search rVector if there is already a DateTimeDeclImpl with rText,bFixed and nFormat
	std::vector< DateTimeDeclImpl >::iterator aIter;
	sal_Int32 nIndex;
	for( nIndex = 1, aIter = rVector.begin(); aIter != rVector.end(); aIter++, nIndex++ )
	{
		const DateTimeDeclImpl& rDecl = (*aIter);
		if( (rDecl.mbFixed == bFixed ) &&
			(!bFixed || rDecl.maStrText == rText) &&
			(bFixed || (rDecl.mnFormat == nFormat) ) )
			break;
	}

	// if nothing is found, append a new DateTimeDeclImpl
	if( aIter == rVector.end() )
	{
		DateTimeDeclImpl aDecl;
		aDecl.maStrText = rText;
		aDecl.mbFixed = bFixed;
		aDecl.mnFormat = nFormat;
		rVector.push_back( aDecl );
	}

	// create a reference string with pPrefix and the index of the
	// found or created DateTimeDeclImpl
	OUString aStr( OUString::createFromAscii( pPrefix ) );
	aStr += OUString::valueOf( nIndex );
	return aStr;

}

static const sal_Char* gpStrHeaderTextPrefix = "hdr";
static const sal_Char* gpStrFooterTextPrefix = "ftr";
static const sal_Char* gpStrDateTimeTextPrefix = "dtd";

HeaderFooterPageSettingsImpl SdXMLExport::ImpPrepDrawPageHeaderFooterDecls( const Reference<XDrawPage>& xDrawPage )
{
	HeaderFooterPageSettingsImpl aSettings;

	if( xDrawPage.is() ) try
	{	
		Reference< XPropertySet > xSet( xDrawPage, UNO_QUERY_THROW );
		Reference< XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );

		OUString aStrText;

		const OUString aStrHeaderTextProp( RTL_CONSTASCII_USTRINGPARAM( "HeaderText" ) );
		if( xInfo->hasPropertyByName( aStrHeaderTextProp ) )
		{
			xSet->getPropertyValue( aStrHeaderTextProp  ) >>= aStrText;
			if( aStrText.getLength() )
				aSettings.maStrHeaderDeclName = findOrAppendImpl( maHeaderDeclsVector, aStrText, gpStrHeaderTextPrefix );
		}

		const OUString aStrFooterTextProp( RTL_CONSTASCII_USTRINGPARAM( "FooterText" ) );
		if( xInfo->hasPropertyByName( aStrFooterTextProp ) )
		{
			xSet->getPropertyValue( aStrFooterTextProp ) >>= aStrText;
			if( aStrText.getLength() )
				aSettings.maStrFooterDeclName = findOrAppendImpl( maFooterDeclsVector, aStrText, gpStrFooterTextPrefix );
		}

		const OUString aStrDateTimeTextProp( RTL_CONSTASCII_USTRINGPARAM( "DateTimeText" ) );
		if( xInfo->hasPropertyByName( aStrDateTimeTextProp ) )
		{
			sal_Bool bFixed = false;
			sal_Int32 nFormat = 0;
			xSet->getPropertyValue( aStrDateTimeTextProp ) >>= aStrText;
			xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDateTimeFixed" ) ) ) >>= bFixed;
			xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DateTimeFormat" ) ) ) >>= nFormat;

			if( !bFixed || aStrText.getLength() )
			{
				aSettings.maStrDateTimeDeclName = findOrAppendImpl( maDateTimeDeclsVector, aStrText, bFixed, nFormat, gpStrDateTimeTextPrefix );
				if( !bFixed )
					addDataStyle( nFormat );
			}
		}
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR( "SdXMLExport::ImpPrepDrawPageHeaderFooterDecls(), unexpected exception cought!" );
	}

	return aSettings;
}

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

void SdXMLExport::ImpWriteHeaderFooterDecls()
{
	OUStringBuffer sBuffer;

	if( !maHeaderDeclsVector.empty() )
	{
		// export header decls
		const OUString aPrefix( OUString::createFromAscii( gpStrHeaderTextPrefix ) );
		std::vector< OUString >::iterator aIter;
		sal_Int32 nIndex;
		for( nIndex = 1, aIter = maHeaderDeclsVector.begin(); aIter != maHeaderDeclsVector.end(); aIter++, nIndex++ )
		{
			sBuffer.append( aPrefix );
			sBuffer.append( nIndex );
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());

			SvXMLElementExport aElem(*this, XML_NAMESPACE_PRESENTATION, XML_HEADER_DECL, sal_True, sal_True);
			Characters((*aIter));
		}
	}

	if( !maFooterDeclsVector.empty() )
	{
		// export footer decls
		const OUString aPrefix( OUString::createFromAscii( gpStrFooterTextPrefix ) );
		std::vector< OUString >::iterator aIter;
		sal_Int32 nIndex;
		for( nIndex = 1, aIter = maFooterDeclsVector.begin(); aIter != maFooterDeclsVector.end(); aIter++, nIndex++ )
		{
			sBuffer.append( aPrefix );
			sBuffer.append( nIndex );
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());

			SvXMLElementExport aElem(*this, XML_NAMESPACE_PRESENTATION, XML_FOOTER_DECL, sal_False, sal_False);
			Characters((*aIter));
		}
	}

	if( !maDateTimeDeclsVector.empty() )
	{
		// export footer decls
		const OUString aPrefix( OUString::createFromAscii( gpStrDateTimeTextPrefix ) );
		std::vector< DateTimeDeclImpl >::iterator aIter;
		sal_Int32 nIndex;
		for( nIndex = 1, aIter = maDateTimeDeclsVector.begin(); aIter != maDateTimeDeclsVector.end(); aIter++, nIndex++ )
		{
			const DateTimeDeclImpl& rDecl = (*aIter);

			sBuffer.append( aPrefix );
			sBuffer.append( nIndex );
			AddAttribute( XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());

			AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SOURCE, rDecl.mbFixed ? XML_FIXED : XML_CURRENT_DATE );
			
			if( !rDecl.mbFixed )
				AddAttribute( XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, getDataStyleName( rDecl.mnFormat ) );

			SvXMLElementExport aElem(*this, XML_NAMESPACE_PRESENTATION, XML_DATE_TIME_DECL, sal_False, sal_False);
			if( rDecl.mbFixed )
				Characters(rDecl.maStrText);
		}
	}
}

void SdXMLExport::ImplExportHeaderFooterDeclAttributes( const HeaderFooterPageSettingsImpl& aSettings )
{
	if( aSettings.maStrHeaderDeclName.getLength() )
		AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_HEADER_NAME, aSettings.maStrHeaderDeclName );

	if( aSettings.maStrFooterDeclName.getLength() )
		AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_FOOTER_NAME, aSettings.maStrFooterDeclName );

	if( aSettings.maStrDateTimeDeclName.getLength() )
		AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_DATE_TIME_NAME, aSettings.maStrDateTimeDeclName );
}

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

OUString SdXMLExport::ImpCreatePresPageStyleName( Reference<XDrawPage> xDrawPage, bool bExportBackground /* = true */ )
{
	// create name
	OUString sStyleName;

	// create style for this page and add to auto style pool

	Reference< beans::XPropertySet > xPropSet1(xDrawPage, UNO_QUERY);
	if(xPropSet1.is())
	{
		Reference< beans::XPropertySet > xPropSet;

		if( bExportBackground )
		{
			// since the background items are in a different propertyset
			// which itself is a property of the pages property set
			// we now merge these two propertysets if possible to simulate
			// a single propertyset with all draw page properties
			const OUString aBackground(RTL_CONSTASCII_USTRINGPARAM("Background"));
			Reference< beans::XPropertySet > xPropSet2;
			Reference< beans::XPropertySetInfo > xInfo( xPropSet1->getPropertySetInfo() );
			if( xInfo.is() && xInfo->hasPropertyByName( aBackground ) )
			{
				Any aAny( xPropSet1->getPropertyValue( aBackground ) );
				aAny >>= xPropSet2;
			}

			if( xPropSet2.is() )
				xPropSet = PropertySetMerger_CreateInstance( xPropSet1, xPropSet2 );
			else
				xPropSet = xPropSet1;
		}
		else
		{
			xPropSet = xPropSet1;
		}

		const UniReference< SvXMLExportPropertyMapper > aMapperRef( GetPresPagePropsMapper() );

		std::vector< XMLPropertyState > xPropStates( aMapperRef->Filter( xPropSet ) );

		if( !xPropStates.empty() )
		{
			// there are filtered properties -> hard attributes
			// try to find this style in AutoStylePool
			sStyleName = GetAutoStylePool()->Find(XML_STYLE_FAMILY_SD_DRAWINGPAGE_ID, sStyleName, xPropStates);

			if(!sStyleName.getLength())
			{
				// Style did not exist, add it to AutoStalePool
				sStyleName = GetAutoStylePool()->Add(XML_STYLE_FAMILY_SD_DRAWINGPAGE_ID, sStyleName, xPropStates);
			}
		}
	}

	return sStyleName;
}

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

void SdXMLExport::ImpPrepMasterPageInfos()
{
	// create draw:style-name entries for master page export
	// containing only background attributes
	// fixed family for page-styles is "drawing-page" (XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME)

	sal_Int32 nCnt;
	for( nCnt = 0; nCnt < mnDocMasterPageCount; nCnt++)
	{
		Reference<XDrawPage> xDrawPage;
		mxDocMasterPages->getByIndex(nCnt) >>= xDrawPage;
		maMasterPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xDrawPage );
	}

	if( IsImpress() )
	{
		Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
		if( xHandoutSupp.is() )
		{		
			Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
			if( xHandoutPage.is() )
			{
				maHandoutPageHeaderFooterSettings = ImpPrepDrawPageHeaderFooterDecls( xHandoutPage );
				maHandoutMasterStyleName = ImpCreatePresPageStyleName( xHandoutPage, false );
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////////
void SdXMLExport::ImpWritePresentationStyles()
{
	if(IsImpress())
	{
        for (sal_Int32 nCnt = 0; nCnt < mnDocMasterPageCount; nCnt++)
		{
			Any aAny(mxDocMasterPages->getByIndex(nCnt));
			Reference<container::XNamed> xNamed;

			if(aAny >>= xNamed)
			{
				// write presentation styles (ONLY if presentation)
				if(IsImpress() && mxDocStyleFamilies.is() && xNamed.is())
				{
					XMLStyleExport aStEx(*this, OUString(), GetAutoStylePool().get());
					const UniReference< SvXMLExportPropertyMapper > aMapperRef( GetPropertySetMapper() );

					OUString aPrefix( xNamed->getName() );

					aPrefix += OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
					aStEx.exportStyleFamily(xNamed->getName(),
						OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_PRESENTATION_NAME)),
                        aMapperRef, sal_False,
						XML_STYLE_FAMILY_SD_PRESENTATION_ID, &aPrefix);
				}
			}
		}
	}
}

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

void SdXMLExport::SetProgress(sal_Int32 nProg)
{
	// set progress view
	if(GetStatusIndicator().is())
		GetStatusIndicator()->setValue(nProg);
}

//////////////////////////////////////////////////////////////////////////////
// #82003#

void SdXMLExport::_ExportMeta()
{
    uno::Sequence<beans::NamedValue> stats(1);
    stats[0] = beans::NamedValue(::rtl::OUString::createFromAscii("ObjectCount"),
                uno::makeAny(mnObjectCount));

    // update document statistics at the model
    uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
        uno::UNO_QUERY_THROW);
    uno::Reference<document::XDocumentProperties> xDocProps(
        xPropSup->getDocumentProperties());
    if (xDocProps.is()) {
        xDocProps->setDocumentStatistics(stats);
    }

	// call parent
	SvXMLExport::_ExportMeta();
}

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

void SdXMLExport::_ExportContent()
{
	// export <pres:header-decl>, <pres:footer-decl> and <pres:date-time-decl> elements
	ImpWriteHeaderFooterDecls();

	// page export
	for(sal_Int32 nPageInd(0); nPageInd < mnDocDrawPageCount; nPageInd++)
	{
		uno::Reference<drawing::XDrawPage> xDrawPage( mxDocDrawPages->getByIndex(nPageInd), uno::UNO_QUERY );

		SetProgress(((nPageInd + 1) * 100) / mnDocDrawPageCount);

		if(xDrawPage.is())
		{
			// prepare page attributes, name of page
			Reference < container::XNamed > xNamed(xDrawPage, UNO_QUERY);
			if(xNamed.is())
				AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, xNamed->getName());

			// draw:style-name (presentation page attributes AND background attributes)
			if( maDrawPagesStyleNames[nPageInd].getLength() )
				AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, 
						maDrawPagesStyleNames[nPageInd]);

			// draw:master-page-name
			Reference < drawing::XMasterPageTarget > xMasterPageInt(xDrawPage, UNO_QUERY);
			if(xMasterPageInt.is())
			{
				Reference<XDrawPage> xUsedMasterPage(xMasterPageInt->getMasterPage());
				if(xUsedMasterPage.is())
				{
					Reference < container::XNamed > xMasterNamed(xUsedMasterPage, UNO_QUERY);
					if(xMasterNamed.is())
					{
						AddAttribute(XML_NAMESPACE_DRAW, XML_MASTER_PAGE_NAME, 
							EncodeStyleName( xMasterNamed->getName()) );
					}
				}
			}

			// presentation:page-layout-name
			if( IsImpress() && maDrawPagesAutoLayoutNames[nPageInd+1].getLength())
			{
				AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PRESENTATION_PAGE_LAYOUT_NAME, maDrawPagesAutoLayoutNames[nPageInd+1] );
			}

			Reference< beans::XPropertySet > xProps( xDrawPage, UNO_QUERY );
			if( xProps.is() )
			{
				try
				{
					OUString aBookmarkURL;
					xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "BookmarkURL" ) ) ) >>= aBookmarkURL;

					if( aBookmarkURL.getLength() )
					{
						sal_Int32 nIndex = aBookmarkURL.lastIndexOf( (sal_Unicode)'#' );
						if( nIndex != -1 )
						{
							OUString aFileName( aBookmarkURL.copy( 0, nIndex ) );
							OUString aBookmarkName( aBookmarkURL.copy( nIndex+1 ) );

							aBookmarkURL = GetRelativeReference( aFileName );
							aBookmarkURL += String( '#' );
							aBookmarkURL += aBookmarkName;
						}

						AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, aBookmarkURL);
						AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
						AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_REPLACE );
						AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
					}
				}
				catch( Exception& )
				{
					DBG_ERROR(" no \"BookmarkURL\" property at page?" );
				}
			}

			if( IsImpress() )
				ImplExportHeaderFooterDeclAttributes( maDrawPagesHeaderFooterSettings[nPageInd] );


			OUString sNavigationOrder( getNavigationOrder( xDrawPage ) );
			if( sNavigationOrder.getLength() != 0 )
				AddAttribute ( XML_NAMESPACE_DRAW, XML_NAV_ORDER, sNavigationOrder );

			UniReference< xmloff::AnimationsExporter >	xAnimationsExporter;
			uno::Reference< ::com::sun::star::animations::XAnimationNodeSupplier > xAnimNodeSupplier;

			// prepare animation export
			if(IsImpress())
			{
				if( getExportFlags() & EXPORT_OASIS )
				{
					// export new animations for oasis format
					xAnimNodeSupplier.set( xDrawPage, UNO_QUERY );

					// prepare animations exporter if impress
					if(xAnimNodeSupplier.is())
					{
						xAnimationsExporter = new xmloff::AnimationsExporter( *this, xProps );
						xAnimationsExporter->prepare( xAnimNodeSupplier->getAnimationNode() );
					}
				}
				else
				{
					// export old animations for ooo format
					UniReference< XMLAnimationsExporter > xAnimExport = new XMLAnimationsExporter( GetShapeExport().get() );
					GetShapeExport()->setAnimationsExporter( xAnimExport );
				}
			}

			// write draw:id
	        const OUString aPageId = getInterfaceToIdentifierMapper().getIdentifier( xDrawPage );
			if( aPageId.getLength() != 0 )
            {
                AddAttributeIdLegacy(XML_NAMESPACE_DRAW, aPageId);
            }

			// write page
			SvXMLElementExport aDPG(*this, XML_NAMESPACE_DRAW, XML_PAGE, sal_True, sal_True);

			// write optional office:forms
			exportFormsElement( xDrawPage );

			// write graphic objects on this page (if any)
			Reference< drawing::XShapes > xExportShapes(xDrawPage, UNO_QUERY);
			if(xExportShapes.is() && xExportShapes->getCount())
				GetShapeExport()->exportShapes( xExportShapes );

			// write animations and presentation notes (ONLY if presentation)
			if(IsImpress())
			{
				if(xAnimNodeSupplier.is())
				{
					xAnimationsExporter->exportAnimations( xAnimNodeSupplier->getAnimationNode() );
				}
				else
				{
					// animations
					UniReference< XMLAnimationsExporter > xAnimExport( GetShapeExport()->getAnimationsExporter() );
					if( xAnimExport.is() )
						xAnimExport->exportAnimations( *this );

					xAnimExport = NULL;
					GetShapeExport()->setAnimationsExporter( xAnimExport );
				}

				// presentations
				Reference< presentation::XPresentationPage > xPresPage(xDrawPage, UNO_QUERY);
				if(xPresPage.is())
				{
					Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
					if(xNotesPage.is())
					{
						Reference< drawing::XShapes > xShapes(xNotesPage, UNO_QUERY);
						if(xShapes.is())
						{
							if( maDrawNotesPagesStyleNames[nPageInd].getLength() )
								AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, maDrawNotesPagesStyleNames[nPageInd]);

							ImplExportHeaderFooterDeclAttributes( maDrawNotesPagesHeaderFooterSettings[nPageInd] );

							// write presentation notes
							SvXMLElementExport aPSY(*this, XML_NAMESPACE_PRESENTATION, XML_NOTES, sal_True, sal_True);

							// write optional office:forms
							exportFormsElement( xNotesPage );

							// write shapes per se
							GetShapeExport()->exportShapes( xShapes );
						}
					}
				}
			}

			exportAnnotations( xDrawPage );
		}
	}

	if( IsImpress() )
		exportPresentationSettings();
}

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

void SdXMLExport::exportPresentationSettings()
{
	try
	{
		Reference< XPresentationSupplier > xPresSupplier( GetModel(), UNO_QUERY );
		if( !xPresSupplier.is() )
			return;

		Reference< XPropertySet > xPresProps( xPresSupplier->getPresentation(), UNO_QUERY );
		if( !xPresProps.is() )
			return;

		sal_Bool bHasAttr = sal_False;

		sal_Bool bTemp = false;

		// export range
		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsShowAll" ) ) ) >>= bTemp;
		if( !bTemp )
		{
			OUString aFirstPage;
			xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "FirstPage" ) ) ) >>= aFirstPage;
			if( aFirstPage.getLength() )
			{
				AddAttribute(XML_NAMESPACE_PRESENTATION, XML_START_PAGE, aFirstPage );
				bHasAttr = sal_True;
			}
			else
			{
				OUString aCustomShow;
				xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CustomShow" ) ) ) >>= aCustomShow;
				if( aCustomShow.getLength() )
				{
					AddAttribute(XML_NAMESPACE_PRESENTATION, XML_SHOW, aCustomShow );
					bHasAttr = sal_True;
				}
			}
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsEndless" ) ) ) >>= bTemp;
		if( bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_ENDLESS, XML_TRUE );
			bHasAttr = sal_True;

			sal_Int32 nPause = 0;
			xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Pause" ) ) ) >>= nPause;

			util::DateTime aTime( 0, (sal_uInt16)nPause, 0, 0, 0, 0, 0 );

			OUStringBuffer aOut;
			SvXMLUnitConverter::convertTime( aOut, aTime );
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PAUSE, aOut.makeStringAndClear() );
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowAnimations" ) ) ) >>= bTemp;
		if( !bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_ANIMATIONS, XML_DISABLED );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsAlwaysOnTop" ) ) ) >>= bTemp;
		if( bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_STAY_ON_TOP, XML_TRUE );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsAutomatic" ) ) ) >>= bTemp;
		if( bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_FORCE_MANUAL, XML_TRUE );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFullScreen" ) ) ) >>= bTemp;
		if( !bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_FULL_SCREEN, XML_FALSE );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsMouseVisible" ) ) ) >>= bTemp;
		if( !bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_MOUSE_VISIBLE, XML_FALSE );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "StartWithNavigator" ) ) ) >>= bTemp;
		if( bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_START_WITH_NAVIGATOR, XML_TRUE );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "UsePen" ) ) ) >>= bTemp;
		if( bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_MOUSE_AS_PEN, XML_TRUE );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsTransitionOnClick" ) ) ) >>= bTemp;
		if( !bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_TRANSITION_ON_CLICK, XML_DISABLED );
			bHasAttr = sal_True;
		}

		xPresProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "IsShowLogo" ) ) ) >>= bTemp;
		if( bTemp )
		{
			AddAttribute(XML_NAMESPACE_PRESENTATION, XML_SHOW_LOGO, XML_TRUE );
			bHasAttr = sal_True;
		}

		Reference< container::XNameContainer > xShows;
		Sequence< OUString > aShowNames;
		const OUString* pShowNames = NULL;
		sal_Int32 nShowCount = 0;

		Reference< XCustomPresentationSupplier > xSup( GetModel(), UNO_QUERY );
		if( xSup.is() )
		{
			xShows = xSup->getCustomPresentations();
			if( xShows.is() )
			{
				aShowNames = xShows->getElementNames();
				pShowNames = aShowNames.getArray();
				nShowCount = aShowNames.getLength();
			}
		}

		if( bHasAttr || nShowCount != 0 )
		{
			SvXMLElementExport aSettings(*this, XML_NAMESPACE_PRESENTATION, XML_SETTINGS, sal_True, sal_True);

			if( nShowCount == 0 )
				return;

			Reference< XIndexContainer > xShow;
			Reference< XNamed > xPageName;

			OUStringBuffer sTmp;

			for( sal_Int32 nIndex = 0; nIndex < nShowCount; nIndex++, pShowNames++ )
			{
				AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, *pShowNames );

				xShows->getByName( *pShowNames ) >>= xShow;
				DBG_ASSERT( xShow.is(), "invalid custom show!" );
				if( !xShow.is() )
					continue;

				const sal_Int32 nPageCount = xShow->getCount();
				for( sal_Int32 nPage = 0; nPage < nPageCount; nPage++ )
				{
					xShow->getByIndex( nPage ) >>= xPageName;

					if( !xPageName.is() )
						continue;

					if( sTmp.getLength() != 0 )
						sTmp.append( sal_Unicode( ',' ) );
					sTmp.append( xPageName->getName() );

				}

				if( sTmp.getLength() )
					AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PAGES, sTmp.makeStringAndClear() );

				SvXMLElementExport aShows(*this, XML_NAMESPACE_PRESENTATION, XML_SHOW, sal_True, sal_True);
			}
		}
	}
	catch( uno::Exception )
	{
		DBG_ERROR( "uno::Exception while exporting <presentation:settings>" );
	}
}

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

void SdXMLExport::_ExportStyles(sal_Bool bUsed)
{
	GetPropertySetMapper()->SetAutoStyles( sal_False );

	// export fill styles
	SvXMLExport::_ExportStyles( bUsed );

	// write draw:style-name for object graphic-styles
	GetShapeExport()->ExportGraphicDefaults();

	// do not export in ODF 1.1 or older
	if( getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
		GetShapeExport()->GetShapeTableExport()->exportTableStyles();

	// write presentation styles
	ImpWritePresentationStyles();

	// prepare draw:auto-layout-name for page export
	ImpPrepAutoLayoutInfos();

	// write draw:auto-layout-name for page export
	ImpWriteAutoLayoutInfos();

	Reference< beans::XPropertySet > xInfoSet( getExportInfo() );
	if( xInfoSet.is() )
	{
		Reference< beans::XPropertySetInfo > xInfoSetInfo( xInfoSet->getPropertySetInfo() );

		Any aAny;

		if( xInfoSetInfo->hasPropertyByName( msPageLayoutNames ) )
		{
			aAny <<= maDrawPagesAutoLayoutNames;
			xInfoSet->setPropertyValue( msPageLayoutNames, aAny );
		}
	}
}

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

void SdXMLExport::_ExportAutoStyles()
{
	Reference< beans::XPropertySet > xInfoSet( getExportInfo() );
	if( xInfoSet.is() )
	{
		Reference< beans::XPropertySetInfo > xInfoSetInfo( xInfoSet->getPropertySetInfo() );

		if( xInfoSetInfo->hasPropertyByName( msPageLayoutNames ) )
		{
			xInfoSet->getPropertyValue( msPageLayoutNames ) >>= maDrawPagesAutoLayoutNames;
		}
	}

	GetPropertySetMapper()->SetAutoStyles( sal_True );

	if( getExportFlags() & EXPORT_STYLES )
	{
		// #80012# PageMaster export moved from _ExportStyles
		// prepare page-master infos
		ImpPrepPageMasterInfos();

		// write page-master infos
		ImpWritePageMasterInfos();

		// prepare draw:style-name for master page export
		ImpPrepMasterPageInfos();
	}

	if( getExportFlags() & EXPORT_CONTENT )
	{
		// prepare draw:style-name for page export
		ImpPrepDrawPageInfos();
	}

	// export draw-page styles
	GetAutoStylePool()->exportXML(
		XML_STYLE_FAMILY_SD_DRAWINGPAGE_ID
		, GetDocHandler(),
		GetMM100UnitConverter(),
		GetNamespaceMap()
        );

	if( getExportFlags() & EXPORT_STYLES )
	{
		// create auto style infos for shapes on master handout page
		if( IsImpress() )
		{
			Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
			if( xHandoutSupp.is() )
			{
				Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
				if( xHandoutPage.is() )
				{
					Reference< drawing::XShapes > xShapes(xHandoutPage, UNO_QUERY);
					if(xShapes.is() && xShapes->getCount())
						GetShapeExport()->collectShapesAutoStyles( xShapes );
				}
			}
		}

		// create auto style infos for objects on master pages
		for(sal_Int32 nMPageId(0L); nMPageId < mnDocMasterPageCount; nMPageId++)
		{
			Reference< XDrawPage > xMasterPage(mxDocMasterPages->getByIndex(nMPageId), UNO_QUERY );

			if( xMasterPage.is() )
			{
				// collect layer information
				GetFormExport()->examineForms( xMasterPage );

				// get MasterPage Name
				OUString aMasterPageNamePrefix;
				Reference < container::XNamed > xNamed(xMasterPage, UNO_QUERY);
				if(xNamed.is())
				{
					aMasterPageNamePrefix = xNamed->getName();
				}
				if(aMasterPageNamePrefix.getLength())
				{
					aMasterPageNamePrefix += OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
				}
				GetShapeExport()->setPresentationStylePrefix( aMasterPageNamePrefix );

				Reference< drawing::XShapes > xMasterShapes(xMasterPage, UNO_QUERY);
				if(xMasterShapes.is() && xMasterShapes->getCount())
					GetShapeExport()->collectShapesAutoStyles( xMasterShapes );

				if(IsImpress())
				{
					Reference< presentation::XPresentationPage > xPresPage(xMasterPage, UNO_QUERY);
					if(xPresPage.is())
					{
						Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
						if(xNotesPage.is())
						{
							// collect layer information
							GetFormExport()->examineForms( xNotesPage );

							Reference< drawing::XShapes > xShapes(xNotesPage, UNO_QUERY);
							if(xShapes.is() && xShapes->getCount())
								GetShapeExport()->collectShapesAutoStyles( xShapes );
						}
					}
				}
				collectAnnotationAutoStyles(xMasterPage);
			}
		}
	}

	if( getExportFlags() & EXPORT_CONTENT )
	{
		// prepare animations exporter if impress
		if(IsImpress() && ((getExportFlags() & EXPORT_OASIS) == 0) )
		{
			UniReference< XMLAnimationsExporter > xAnimExport = new XMLAnimationsExporter( GetShapeExport().get() );
			GetShapeExport()->setAnimationsExporter( xAnimExport );
		}

		// create auto style infos for objects on pages
		for(sal_Int32 nPageInd(0); nPageInd < mnDocDrawPageCount; nPageInd++)
		{
			Reference<XDrawPage> xDrawPage( mxDocDrawPages->getByIndex(nPageInd), UNO_QUERY );
			if( xDrawPage.is() )
			{
				// collect layer information
				GetFormExport()->examineForms( xDrawPage );

				// get MasterPage Name
				OUString aMasterPageNamePrefix;
				Reference < drawing::XMasterPageTarget > xMasterPageInt(xDrawPage, UNO_QUERY);
				if(xMasterPageInt.is())
				{
					Reference<XDrawPage> xUsedMasterPage(xMasterPageInt->getMasterPage());
					if(xUsedMasterPage.is())
					{
						Reference < container::XNamed > xMasterNamed(xUsedMasterPage, UNO_QUERY);
						if(xMasterNamed.is())
						{
							aMasterPageNamePrefix = xMasterNamed->getName();
						}
					}
				}
				if(aMasterPageNamePrefix.getLength())
				{
					aMasterPageNamePrefix += OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
				}

				GetShapeExport()->setPresentationStylePrefix( aMasterPageNamePrefix );

				// prepare object infos
				Reference< drawing::XShapes > xDrawShapes(xDrawPage, UNO_QUERY);
				if(xDrawShapes.is() && xDrawShapes->getCount())
					GetShapeExport()->collectShapesAutoStyles( xDrawShapes );

				// prepare presentation notes page object infos (ONLY if presentation)
				if(IsImpress())
				{
					Reference< presentation::XPresentationPage > xPresPage(xDrawPage, UNO_QUERY);
					if(xPresPage.is())
					{
						Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
						if(xNotesPage.is())
						{
							// collect layer information
							GetFormExport()->examineForms( xNotesPage );

							Reference< drawing::XShapes > xShapes(xNotesPage, UNO_QUERY);
							if(xShapes.is() && xShapes->getCount())
								GetShapeExport()->collectShapesAutoStyles( xShapes );
						}
					}
				}

				collectAnnotationAutoStyles( xDrawPage );
			}
		}
		if(IsImpress())
		{
			UniReference< XMLAnimationsExporter > xAnimExport;
			GetShapeExport()->setAnimationsExporter( xAnimExport );
		}
	}

	exportAutoDataStyles();

	GetShapeExport()->exportAutoStyles();

	sal_uInt16 nContentAutostyles = EXPORT_CONTENT | EXPORT_AUTOSTYLES;
	if ( ( getExportFlags() & nContentAutostyles ) == nContentAutostyles )
		GetFormExport()->exportAutoStyles( );

	// ...for text
	GetTextParagraphExport()->exportTextAutoStyles();
}

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

void SdXMLExport::_ExportMasterStyles()
{
	// export layer
	SdXMLayerExporter::exportLayer( *this );

	// export handout master page if impress
	if( IsImpress() )
	{
		Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
		if( xHandoutSupp.is() )
		{
			Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
			if( xHandoutPage.is() )
			{
				// presentation:page-layout-name
				if( IsImpress() && maDrawPagesAutoLayoutNames[0].getLength())
				{
					AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PRESENTATION_PAGE_LAYOUT_NAME, EncodeStyleName( maDrawPagesAutoLayoutNames[0] ));
				}

				ImpXMLEXPPageMasterInfo* pInfo = mpHandoutPageMaster;
				if(pInfo)
				{
					OUString sString = pInfo->GetName();
					AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, sString );
				}

				// draw:style-name
				if( maHandoutMasterStyleName.getLength() )
					AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, maHandoutMasterStyleName);

				ImplExportHeaderFooterDeclAttributes( maHandoutPageHeaderFooterSettings );

				// write masterpage
				SvXMLElementExport aMPG(*this, XML_NAMESPACE_STYLE, XML_HANDOUT_MASTER, sal_True, sal_True);

				// write graphic objects on this master page (if any)
				Reference< drawing::XShapes > xShapes(xHandoutPage, UNO_QUERY);
				if(xShapes.is() && xShapes->getCount())
					GetShapeExport()->exportShapes( xShapes );
			}
		}
	}

	// export MasterPages in master-styles section
    for (sal_Int32 nMPageId = 0; nMPageId < mnDocMasterPageCount; nMPageId++)
	{
		Reference< XDrawPage > xMasterPage( mxDocMasterPages->getByIndex(nMPageId), UNO_QUERY );
		if(xMasterPage.is())
		{
			// prepare masterpage attributes
			OUString sMasterPageName;
			Reference < container::XNamed > xNamed(xMasterPage, UNO_QUERY);
			if(xNamed.is())
			{
				sal_Bool bEncoded = sal_False;
				sMasterPageName = xNamed->getName();
				AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, 
					EncodeStyleName( sMasterPageName, &bEncoded ));
				if( bEncoded )
                	AddAttribute( 
						XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
						sMasterPageName );
			}

			ImpXMLEXPPageMasterInfo* pInfo = mpPageMasterUsageList->GetObject(nMPageId);
			if(pInfo)
			{
				OUString sString = pInfo->GetName();
				AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, sString );
			}

			// draw:style-name (background attributes)
			if( maMasterPagesStyleNames[nMPageId].getLength() )
				AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, 
						maMasterPagesStyleNames[nMPageId]);

			// write masterpage
			SvXMLElementExport aMPG(*this, XML_NAMESPACE_STYLE, XML_MASTER_PAGE, sal_True, sal_True);

			// write optional office:forms
			exportFormsElement( xMasterPage );

			// write graphic objects on this master page (if any)
			Reference< drawing::XShapes > xMasterShapes(xMasterPage, UNO_QUERY);
			if(xMasterShapes.is() && xMasterShapes->getCount())
				GetShapeExport()->exportShapes( xMasterShapes );

			// write presentation notes (ONLY if presentation)
			if(IsImpress())
			{
				Reference< presentation::XPresentationPage > xPresPage(xMasterPage, UNO_QUERY);
				if(xPresPage.is())
				{
					Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
					if(xNotesPage.is())
					{
						Reference< drawing::XShapes > xShapes(xNotesPage, UNO_QUERY);
						if(xShapes.is())
						{
							ImpXMLEXPPageMasterInfo* pMasterInfo = mpNotesPageMasterUsageList->GetObject(nMPageId);
							if(pMasterInfo)
							{
								OUString sString = pMasterInfo->GetName();
								AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, sString);
							}

							// write presentation notes
							SvXMLElementExport aPSY(*this, XML_NAMESPACE_PRESENTATION, XML_NOTES, sal_True, sal_True);

							// write optional office:forms
							exportFormsElement( xNotesPage );

							// write shapes per se
							GetShapeExport()->exportShapes( xShapes );
						}
					}
				}
			}
			exportAnnotations( xMasterPage );			
		}
	}
}

void SdXMLExport::exportFormsElement( Reference< XDrawPage > xDrawPage )
{
	if( xDrawPage.is() )
	{
		Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, UNO_QUERY );
		if ( xFormsSupplier.is() && xFormsSupplier->hasForms() )
		{
			// write masterpage
			::xmloff::OOfficeFormsExport aForms(*this);
			GetFormExport()->exportForms( xDrawPage );
		}

		if(! GetFormExport()->seekPage( xDrawPage ) )
		{
			DBG_ERROR( "OFormLayerXMLExport::seekPage failed!" );
		}
	}
}

void SdXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
{
	rProps.realloc(4);	
	beans::PropertyValue* pProps = rProps.getArray();
	if(pProps)
	{
//		SvXMLElementExport aViewSettingsElem(*this, XML_NAMESPACE_DRAW, XML_VIEW_SETTINGS, sal_True, sal_True);

		Reference< beans::XPropertySet > xPropSet( GetModel(), UNO_QUERY );
		if( !xPropSet.is() )
			return;

		awt::Rectangle aVisArea;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) ) ) >>= aVisArea;
/*
		sal_Int16 nMapUnit;
		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MapUnit" ) ) ) >>= nMapUnit;
*/

		sal_uInt16 i = 0;
		pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaTop"));
		pProps[i++].Value <<= aVisArea.Y;
		pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaLeft"));
		pProps[i++].Value <<= aVisArea.X;
		pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaWidth"));
		pProps[i++].Value <<= aVisArea.Width;
		pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaHeight"));
		pProps[i++].Value <<= aVisArea.Height;
	}
}

void SdXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps)
{
	Reference< lang::XMultiServiceFactory > xFac( GetModel(), UNO_QUERY );
	if( xFac.is() )
	{
		Reference< beans::XPropertySet > xProps( xFac->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.Settings" ) ) ), UNO_QUERY );
		if( xProps.is() )
			SvXMLUnitConverter::convertPropertySet( rProps, xProps );
	}
}

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

void SdXMLExport::addDataStyle(const sal_Int32 nNumberFormat, sal_Bool bTimeFormat )
{
	sal_Int32 nFormat = nNumberFormat;
	if( (nNumberFormat > 1) && (nNumberFormat <= 0x0f) )
		nFormat -= 2;

	if( bTimeFormat )
	{
		if( maUsedTimeStyles.count( nFormat ) == 0 )
			maUsedTimeStyles.insert( nFormat );
	}
	else
	{
		if( maUsedDateStyles.count( nFormat ) == 0 )
			maUsedDateStyles.insert( nFormat );
	}
}

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

void SdXMLExport::exportDataStyles()
{
	// there are no data styles to export in draw/impress yet
}

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

void SdXMLExport::exportAutoDataStyles()
{
	SdXMLFormatMap::iterator aIter( maUsedDateStyles.begin() );
	SdXMLFormatMap::iterator aEnd( maUsedDateStyles.end() );

	while( aIter != aEnd )
		SdXMLNumberStylesExporter::exportDateStyle( *this, (*aIter++) );

	aIter = maUsedTimeStyles.begin();
	aEnd = maUsedTimeStyles.end();
	while( aIter != aEnd )
		SdXMLNumberStylesExporter::exportTimeStyle( *this, (*aIter++) );

	if(HasFormExport())
		GetFormExport()->exportAutoControlNumberStyles();
}

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

OUString SdXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, sal_Bool bTimeFormat ) const
{
	if( bTimeFormat )
	{
		return SdXMLNumberStylesExporter::getTimeStyleName( nNumberFormat );
	}
	else
	{
		return SdXMLNumberStylesExporter::getDateStyleName( nNumberFormat );
	}
}

OUString SdXMLExport::getNavigationOrder( const Reference< XDrawPage >& xDrawPage )
{
	OUStringBuffer sNavOrder;
	try
	{
		Reference< XPropertySet > xSet( xDrawPage, UNO_QUERY_THROW );
		Reference< XIndexAccess > xNavOrder( xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "NavigationOrder" ) ) ), UNO_QUERY_THROW );

		Reference< XIndexAccess > xZOrderAccess( xDrawPage, UNO_QUERY );
		
		// only export navigation order if it is different from the z-order
		if( (xNavOrder.get() != xZOrderAccess.get()) && (xNavOrder->getCount() == xDrawPage->getCount())  )
		{
			sal_Int32 nIndex;
			const sal_Int32 nCount = xNavOrder->getCount();
			for( nIndex = 0; nIndex < nCount; ++nIndex )
			{
				OUString sId( getInterfaceToIdentifierMapper().registerReference( Reference< XInterface >( xNavOrder->getByIndex( nIndex ), UNO_QUERY ) ) );
				if( sId.getLength() != 0 )
				{
					if( sNavOrder.getLength() != 0 )
						sNavOrder.append( (sal_Unicode)' ' );
					sNavOrder.append( sId );
				}
			}
		}
	}
	catch( Exception& )
	{
	}
	return sNavOrder.makeStringAndClear();
}

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

void SdXMLExport::collectAnnotationAutoStyles( const Reference<XDrawPage>& xDrawPage )
{
    Reference< XAnnotationAccess > xAnnotationAccess( xDrawPage, UNO_QUERY );
    if( xAnnotationAccess.is() ) try
    {
        Reference< XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
        if( xAnnotationEnumeration.is() )
        {
            while( xAnnotationEnumeration->hasMoreElements() )
            {
                Reference< XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement(), UNO_QUERY_THROW );
                Reference< XText > xText( xAnnotation->getTextRange() );
				if(xText.is() && xText->getString().getLength())
					GetTextParagraphExport()->collectTextAutoStyles( xText );
			}
        }
    }
    catch( Exception& )
    {
        DBG_ERROR("SdXMLExport::collectAnnotationAutoStyles(), exception caught during export of annotation auto styles");
    }
}

void SdXMLExport::exportAnnotations( const Reference<XDrawPage>& xDrawPage )
{
    // do not export in ODF 1.2 or older
    if( getDefaultVersion() <= SvtSaveOptions::ODFVER_012 )
        return;
        
    Reference< XAnnotationAccess > xAnnotationAccess( xDrawPage, UNO_QUERY );
    if( xAnnotationAccess.is() ) try
    {
        Reference< XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
        if( xAnnotationEnumeration.is() && xAnnotationEnumeration->hasMoreElements() )
        {
            OUStringBuffer sStringBuffer;
            do
            {
                Reference< XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement(), UNO_QUERY_THROW );

                RealPoint2D aPosition( xAnnotation->getPosition() );

               	GetMM100UnitConverter().convertMeasure(sStringBuffer, static_cast<sal_Int32>( aPosition.X * 100 ) );
            	AddAttribute(XML_NAMESPACE_SVG, XML_X, sStringBuffer.makeStringAndClear());

               	GetMM100UnitConverter().convertMeasure(sStringBuffer, static_cast<sal_Int32>( aPosition.Y * 100 ) );
            	AddAttribute(XML_NAMESPACE_SVG, XML_Y, sStringBuffer.makeStringAndClear());

                RealSize2D aSize( xAnnotation->getSize() );

                if( aSize.Width || aSize.Height )
                {
                   	GetMM100UnitConverter().convertMeasure(sStringBuffer, static_cast<sal_Int32>( aSize.Width * 100 ) );
                	AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, sStringBuffer.makeStringAndClear());
                   	GetMM100UnitConverter().convertMeasure(sStringBuffer, static_cast<sal_Int32>( aSize.Height * 100 ) );
                	AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, sStringBuffer.makeStringAndClear());
                }

                // annotation element + content
                SvXMLElementExport aElem(*this, XML_NAMESPACE_OFFICE_EXT, XML_ANNOTATION, sal_False, sal_True);

                // author
                OUString aAuthor( xAnnotation->getAuthor() );
                if( aAuthor.getLength() )
                {
	                SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, XML_CREATOR, sal_True, sal_False );
	                this->Characters(aAuthor);
                }

				{
					// date time
					DateTime aDate( xAnnotation->getDateTime() );
					GetMM100UnitConverter().convertDateTime(sStringBuffer, aDate, sal_True);
					SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC, XML_DATE, sal_True, sal_False );
					Characters(sStringBuffer.makeStringAndClear());
				}

                com::sun::star::uno::Reference < com::sun::star::text::XText > xText( xAnnotation->getTextRange() );
                if( xText.is() )
	                this->GetTextParagraphExport()->exportText( xText );
            }
            while( xAnnotationEnumeration->hasMoreElements() );
        }
    }
    catch( Exception& )
    {
        DBG_ERROR("SdXMLExport::exportAnnotations(), exception caught during export of annotations");
    }
}

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

#define SERVICE( classname, servicename, implementationname, draw, flags )\
uno::Sequence< OUString > SAL_CALL classname##_getSupportedServiceNames() throw()\
{\
	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( servicename ) );\
	const uno::Sequence< OUString > aSeq( &aServiceName, 1 );\
	return aSeq;\
}\
OUString SAL_CALL classname##_getImplementationName() throw()\
{\
	return OUString( RTL_CONSTASCII_USTRINGPARAM( implementationname ) );\
}\
uno::Reference< uno::XInterface > SAL_CALL classname##_createInstance(const uno::Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )\
{\
	return (cppu::OWeakObject*)new SdXMLExport( rSMgr, draw, flags );\
}

SERVICE( XMLImpressExportOasis, "com.sun.star.comp.Impress.XMLOasisExporter", "XMLImpressExportOasis", sal_False, EXPORT_OASIS|EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED );
SERVICE( XMLImpressStylesExportOasis, "com.sun.star.comp.Impress.XMLOasisStylesExporter", "XMLImpressStylesExportOasis", sal_False, EXPORT_OASIS|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES );
SERVICE( XMLImpressContentExportOasis, "com.sun.star.comp.Impress.XMLOasisContentExporter", "XMLImpressContentExportOasis", sal_False, EXPORT_OASIS|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS );
SERVICE( XMLImpressMetaExportOasis, "com.sun.star.comp.Impress.XMLOasisMetaExporter", "XMLImpressMetaExportOasis", sal_False, EXPORT_OASIS|EXPORT_META );
SERVICE( XMLImpressSettingsExportOasis, "com.sun.star.comp.Impress.XMLOasisSettingsExporter", "XMLImpressSettingsExportOasis", sal_False, EXPORT_OASIS|EXPORT_SETTINGS );

SERVICE( XMLImpressExportOOO, "com.sun.star.comp.Impress.XMLExporter", "XMLImpressExportOOO", sal_False, EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED );
SERVICE( XMLImpressStylesExportOOO, "com.sun.star.comp.Impress.XMLStylesExporter", "XMLImpressStylesExportOOO", sal_False, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES );
SERVICE( XMLImpressContentExportOOO, "com.sun.star.comp.Impress.XMLContentExporter", "XMLImpressContentExportOOO", sal_False, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS );
SERVICE( XMLImpressMetaExportOOO, "com.sun.star.comp.Impress.XMLMetaExporter", "XMLImpressMetaExportOOO", sal_False, EXPORT_META );
SERVICE( XMLImpressSettingsExportOOO, "com.sun.star.comp.Impress.XMLSettingsExporter", "XMLImpressSettingsExportOOO", sal_False, EXPORT_SETTINGS );

SERVICE( XMLDrawExportOasis, "com.sun.star.comp.Draw.XMLOasisExporter", "XMLDrawExportOasis", sal_True, EXPORT_OASIS|EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED );
SERVICE( XMLDrawStylesExportOasis, "com.sun.star.comp.Draw.XMLOasisStylesExporter", "XMLDrawStylesExportOasis", sal_True, EXPORT_OASIS|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES );
SERVICE( XMLDrawContentExportOasis, "com.sun.star.comp.Draw.XMLOasisContentExporter", "XMLDrawContentExportOasis", sal_True, EXPORT_OASIS|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS );
SERVICE( XMLDrawMetaExportOasis, "com.sun.star.comp.Draw.XMLOasisMetaExporter", "XMLDrawMetaExportOasis", sal_True, EXPORT_OASIS|EXPORT_META );
SERVICE( XMLDrawSettingsExportOasis, "com.sun.star.comp.Draw.XMLOasisSettingsExporter", "XMLDrawSettingsExportOasis", sal_True, EXPORT_OASIS|EXPORT_SETTINGS );

SERVICE( XMLDrawExportOOO, "com.sun.star.comp.Draw.XMLExporter", "XMLDrawExportOOO", sal_True, EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED );
SERVICE( XMLDrawStylesExportOOO, "com.sun.star.comp.Draw.XMLStylesExporter", "XMLDrawStylesExportOOO", sal_True, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES );
SERVICE( XMLDrawContentExportOOO, "com.sun.star.comp.Draw.XMLContentExporter", "XMLDrawContentExportOOO", sal_True, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS );
SERVICE( XMLDrawMetaExportOOO, "com.sun.star.comp.Draw.XMLMetaExporter", "XMLDrawMetaExportOOO", sal_True, EXPORT_META );
SERVICE( XMLDrawSettingsExportOOO, "com.sun.star.comp.Draw.XMLSettingsExporter", "XMLDrawSettingsExportOOO", sal_True, EXPORT_SETTINGS );

SERVICE( XMLDrawingLayerExport, "com.sun.star.comp.DrawingLayer.XMLExporter", "XMLDrawingLayerExport", sal_True, EXPORT_OASIS|EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_FONTDECLS|EXPORT_EMBEDDED );
SERVICE( XMLImpressClipboardExport, "com.sun.star.comp.Impress.XMLClipboardExporter", "XMLImpressClipboardExport", sal_False, EXPORT_OASIS|EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_FONTDECLS|EXPORT_EMBEDDED );

// XServiceInfo
OUString SAL_CALL SdXMLExport::getImplementationName() throw( uno::RuntimeException )
{
    if( IsDraw())
    {
        // Draw

        switch( getExportFlags())
        {
            case EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED:
                return XMLDrawExportOOO_getImplementationName();
            case EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES:
                return XMLDrawStylesExportOOO_getImplementationName();
            case EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS:
                return XMLDrawContentExportOOO_getImplementationName();
            case EXPORT_META:
                return XMLDrawMetaExportOOO_getImplementationName();
            case EXPORT_SETTINGS:
                return XMLDrawSettingsExportOOO_getImplementationName();

			case EXPORT_OASIS|EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED:
                return XMLDrawExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES:
                return XMLDrawStylesExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS:
                return XMLDrawContentExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_META:
                return XMLDrawMetaExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_SETTINGS:
                return XMLDrawSettingsExportOasis_getImplementationName();

			default:
                return XMLDrawExportOOO_getImplementationName();
        }
    }
    else
    {
        // Impress

        switch( getExportFlags())
        {
            case EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED:
                return XMLImpressExportOOO_getImplementationName();
            case EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES:
                return XMLImpressStylesExportOOO_getImplementationName();
            case EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS:
                return XMLImpressContentExportOOO_getImplementationName();
            case EXPORT_META:
                return XMLImpressMetaExportOOO_getImplementationName();
            case EXPORT_SETTINGS:
                return XMLImpressSettingsExportOOO_getImplementationName();
            case EXPORT_OASIS|EXPORT_META|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_SETTINGS|EXPORT_FONTDECLS|EXPORT_EMBEDDED:
                return XMLImpressExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES:
                return XMLImpressStylesExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS:
                return XMLImpressContentExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_META:
                return XMLImpressMetaExportOasis_getImplementationName();
            case EXPORT_OASIS|EXPORT_SETTINGS:
                return XMLImpressSettingsExportOasis_getImplementationName();
            
			default:
                return XMLImpressExportOOO_getImplementationName();
        }
    }
}
