/**************************************************************
 * 
 * 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 <memory>

#include "unointerfacetouniqueidentifiermapper.hxx"
#include <com/sun/star/presentation/ClickAction.hpp>
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
#include <com/sun/star/container/XIdentifierAccess.hpp>
#include <com/sun/star/drawing/GluePoint2.hpp>
#include <com/sun/star/drawing/Alignment.hpp>
#include <com/sun/star/drawing/EscapeDirection.hpp>
#include <com/sun/star/table/XColumnRowRange.hpp>
#include <xmloff/xmluconv.hxx>
#include "PropertySetMerger.hxx"

#include <xmloff/shapeexport.hxx>
#include "sdpropls.hxx"
#include "sdxmlexp_impl.hxx"
#include <xmloff/families.hxx>
#include <tools/debug.hxx>
#include <xmloff/contextid.hxx>
#include <xmloff/xmltoken.hxx>
#include <tools/string.hxx>
#include <sot/clsids.hxx>
#include <tools/globname.hxx>
#include <com/sun/star/beans/XPropertyState.hpp>

#include <comphelper/processfactory.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/drawing/XCustomShapeEngine.hpp>

#include "xmloff/xmlnmspe.hxx"

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

using namespace ::com::sun::star;
using namespace ::xmloff::token;

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

XMLShapeExport::XMLShapeExport(SvXMLExport& rExp,
								SvXMLExportPropertyMapper *pExtMapper )
:	mrExport( rExp ),
	mnNextUniqueShapeId(1),
    maShapesInfos(),
    maCurrentShapesIter(maShapesInfos.end()),
	mbExportLayer( sal_False ),
	// #88546# init to sal_False
	mbHandleProgressBar( sal_False ),
	msZIndex( RTL_CONSTASCII_USTRINGPARAM("ZOrder") ),
	msPrintable( RTL_CONSTASCII_USTRINGPARAM("Printable") ),
	msVisible( RTL_CONSTASCII_USTRINGPARAM("Visible") ),
	msEmptyPres( RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ),
	msModel( RTL_CONSTASCII_USTRINGPARAM("Model") ),
	msStartShape( RTL_CONSTASCII_USTRINGPARAM("StartShape") ),
	msEndShape( RTL_CONSTASCII_USTRINGPARAM("EndShape") ),
	msOnClick( RTL_CONSTASCII_USTRINGPARAM("OnClick") ),
#ifdef ISSUE66550_HLINK_FOR_SHAPES
	msOnAction( RTL_CONSTASCII_USTRINGPARAM("OnAction") ),
	msAction( RTL_CONSTASCII_USTRINGPARAM("Action") ),
	msURL( RTL_CONSTASCII_USTRINGPARAM("URL") ),
#endif
	msEventType( RTL_CONSTASCII_USTRINGPARAM("EventType") ),
	msPresentation( RTL_CONSTASCII_USTRINGPARAM("Presentation") ),
	msMacroName( RTL_CONSTASCII_USTRINGPARAM("MacroName") ),
	msScript( RTL_CONSTASCII_USTRINGPARAM("Script") ),
	msLibrary( RTL_CONSTASCII_USTRINGPARAM("Library") ),
	msClickAction( RTL_CONSTASCII_USTRINGPARAM("ClickAction") ),
	msBookmark( RTL_CONSTASCII_USTRINGPARAM("Bookmark") ),
	msEffect( RTL_CONSTASCII_USTRINGPARAM("Effect") ),
	msPlayFull( RTL_CONSTASCII_USTRINGPARAM("PlayFull") ),
	msVerb( RTL_CONSTASCII_USTRINGPARAM("Verb") ),
	msSoundURL( RTL_CONSTASCII_USTRINGPARAM("SoundURL") ),
	msSpeed( RTL_CONSTASCII_USTRINGPARAM("Speed") ),
	msStarBasic( RTL_CONSTASCII_USTRINGPARAM("StarBasic") )
{
	// construct PropertyHandlerFactory
	mxSdPropHdlFactory = new XMLSdPropHdlFactory( mrExport.GetModel(), rExp );
	// construct PropertySetMapper
	mxPropertySetMapper = CreateShapePropMapper( mrExport );
	if( pExtMapper )
	{
		UniReference < SvXMLExportPropertyMapper > xExtMapper( pExtMapper );
		mxPropertySetMapper->ChainExportMapper( xExtMapper );
	}

/*
	// chain text attributes
	xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp));
*/

	mrExport.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)));
	mrExport.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)));

	maCurrentInfo = maShapeInfos.end();

	// create table export helper and let him add his families in time
	GetShapeTableExport();
}

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

XMLShapeExport::~XMLShapeExport()
{
}

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

// sj: replacing CustomShapes with standard objects that are also supported in OpenOffice.org format
uno::Reference< drawing::XShape > XMLShapeExport::checkForCustomShapeReplacement( const uno::Reference< drawing::XShape >& xShape )
{
	uno::Reference< drawing::XShape > xCustomShapeReplacement;

	if( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 )
	{
		String aType( (OUString)xShape->getShapeType() );
        if( aType.EqualsAscii( (const sal_Char*)"com.sun.star.drawing.CustomShape" ) )
		{
			uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
			if( xSet.is() )
			{
				rtl::OUString aEngine;
				xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeEngine" ) ) ) >>= aEngine;
				if ( !aEngine.getLength() )
					aEngine = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) );

				uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
		/*
				uno::Reference< drawing::XShape > aXShape = GetXShapeForSdrObject( (SdrObjCustomShape*)pCustomShape );
				if ( !aXShape.is() )
					aXShape = new SvxCustomShape( (SdrObjCustomShape*)pCustomShape );
		*/
				if ( aEngine.getLength() && xFactory.is() )
				{
					uno::Sequence< uno::Any > aArgument( 1 );
					uno::Sequence< beans::PropertyValue > aPropValues( 2 );
					aPropValues[ 0 ].Name = rtl::OUString::createFromAscii( "CustomShape" );
					aPropValues[ 0 ].Value <<= xShape;
					sal_Bool bForceGroupWithText = sal_True;
					aPropValues[ 1 ].Name = rtl::OUString::createFromAscii( "ForceGroupWithText" );
					aPropValues[ 1 ].Value <<= bForceGroupWithText;
					aArgument[ 0 ] <<= aPropValues;
					uno::Reference< uno::XInterface > xInterface( xFactory->createInstanceWithArguments( aEngine, aArgument ) );
					if ( xInterface.is() )
					{
						uno::Reference< drawing::XCustomShapeEngine > xCustomShapeEngine(
							uno::Reference< drawing::XCustomShapeEngine >( xInterface, uno::UNO_QUERY ) );
						if ( xCustomShapeEngine.is() )
							xCustomShapeReplacement = xCustomShapeEngine->render();
					}
				}
			}
		}
	}
	return xCustomShapeReplacement;
}

// This method collects all automatic styles for the given XShape
void XMLShapeExport::collectShapeAutoStyles(const uno::Reference< drawing::XShape >& xShape )
{
	if( maCurrentShapesIter == maShapesInfos.end() )
	{
		DBG_ERROR( "XMLShapeExport::collectShapeAutoStyles(): no call to seekShapes()!" );
		return;
	}
	sal_Int32 nZIndex = 0;
	uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
	if( xSet.is() )
		xSet->getPropertyValue(msZIndex) >>= nZIndex;

	ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;

	if( (sal_Int32)aShapeInfoVector.size() <= nZIndex )
	{
		DBG_ERROR( "XMLShapeExport::collectShapeAutoStyles(): no shape info allocated for a given shape" );
		return;
	}

	ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];

	uno::Reference< drawing::XShape > xCustomShapeReplacement = checkForCustomShapeReplacement( xShape );
	if ( xCustomShapeReplacement.is() )
		aShapeInfo.xCustomShapeReplacement = xCustomShapeReplacement;

	// -----------------------------
	// first compute the shapes type
	// -----------------------------
	ImpCalcShapeType(xShape, aShapeInfo.meShapeType);

    // #i118485# enabled XmlShapeTypeDrawChartShape and XmlShapeTypeDrawOLE2Shape
    // to have text
	const bool bObjSupportsText =
//		aShapeInfo.meShapeType != XmlShapeTypeDrawControlShape &&
		aShapeInfo.meShapeType != XmlShapeTypePresChartShape &&
		aShapeInfo.meShapeType != XmlShapeTypePresOLE2Shape &&
		aShapeInfo.meShapeType != XmlShapeTypeDrawSheetShape &&
		aShapeInfo.meShapeType != XmlShapeTypePresSheetShape &&
		aShapeInfo.meShapeType != XmlShapeTypeDraw3DSceneObject &&
		aShapeInfo.meShapeType != XmlShapeTypeDraw3DCubeObject &&
		aShapeInfo.meShapeType != XmlShapeTypeDraw3DSphereObject &&
		aShapeInfo.meShapeType != XmlShapeTypeDraw3DLatheObject &&
		aShapeInfo.meShapeType != XmlShapeTypeDraw3DExtrudeObject &&
		aShapeInfo.meShapeType != XmlShapeTypeDrawPageShape &&
		aShapeInfo.meShapeType != XmlShapeTypePresPageShape &&
		aShapeInfo.meShapeType != XmlShapeTypeDrawGroupShape;

	const bool bObjSupportsStyle =
		aShapeInfo.meShapeType != XmlShapeTypeDrawGroupShape;

	sal_Bool bIsEmptyPresObj = sal_False;

	uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if ( aShapeInfo.xCustomShapeReplacement.is() )
		xPropSet.clear();

	// ----------------
	// prep text styles
	// ----------------
	if( xPropSet.is() && bObjSupportsText )
	{
		uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
		if(xText.is() && xText->getString().getLength())
		{
			uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );

			if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(msEmptyPres) )
			{
				uno::Any aAny = xPropSet->getPropertyValue(msEmptyPres);
				aAny >>= bIsEmptyPresObj;
			}

			if(!bIsEmptyPresObj)
			{
				GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText );
			}
		}
	}

	// ------------------------------
	// compute the shape parent style
	// ------------------------------
	if( xPropSet.is() )
	{
		uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( xPropSet->getPropertySetInfo() );

		OUString aParentName;
		uno::Reference< style::XStyle > xStyle;

		if( bObjSupportsStyle )
		{
			if( xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName( OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))) )
				xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))) >>= xStyle;

			if(xStyle.is())
			{
				// get family ID
				uno::Reference< beans::XPropertySet > xStylePropSet(xStyle, uno::UNO_QUERY);
				DBG_ASSERT( xStylePropSet.is(), "style without a XPropertySet?" );
                try
                {
				    if(xStylePropSet.is())
				    {
					    OUString aFamilyName;
    					xStylePropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Family"))) >>= aFamilyName;
	    				if(aFamilyName.getLength() && !aFamilyName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("graphics"))))
		    				aShapeInfo.mnFamily = XML_STYLE_FAMILY_SD_PRESENTATION_ID;
			    	}
                }
                catch(beans::UnknownPropertyException aException)
                {
                    // Ignored.
                    DBG_ASSERT(false,
                        "XMLShapeExport::collectShapeAutoStyles: style has no 'Family' property");
                }

				// get parent-style name
				if(XML_STYLE_FAMILY_SD_PRESENTATION_ID == aShapeInfo.mnFamily)
				{
					aParentName = msPresentationStylePrefix;
				}

				aParentName += xStyle->getName();
			}
		}

		// filter propset
		std::vector< XMLPropertyState > xPropStates;

		sal_Int32 nCount = 0;
		if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape)) )
		{
			xPropStates = GetPropertySetMapper()->Filter( xPropSet );

			if (XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType)
			{
				// for control shapes, we additionally need the number format style (if any)
				uno::Reference< drawing::XControlShape > xControl(xShape, uno::UNO_QUERY);
				DBG_ASSERT(xControl.is(), "XMLShapeExport::collectShapeAutoStyles: ShapeType control, but no XControlShape!");
				if (xControl.is())
				{
					uno::Reference< beans::XPropertySet > xControlModel(xControl->getControl(), uno::UNO_QUERY);
					DBG_ASSERT(xControlModel.is(), "XMLShapeExport::collectShapeAutoStyles: no control model on the control shape!");

					::rtl::OUString sNumberStyle = mrExport.GetFormExport()->getControlNumberStyle(xControlModel);
					if (0 != sNumberStyle.getLength())
					{
						sal_Int32 nIndex = GetPropertySetMapper()->getPropertySetMapper()->FindEntryIndex(CTF_SD_CONTROL_SHAPE_DATA_STYLE);
							// TODO : this retrieval of the index could be moved into the ctor, holding the index
							//			as member, thus saving time.
						DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");

						XMLPropertyState aNewState(nIndex, uno::makeAny(sNumberStyle));
						xPropStates.push_back(aNewState);
					}
				}
			}

			std::vector< XMLPropertyState >::iterator aIter = xPropStates.begin();
			std::vector< XMLPropertyState >::iterator aEnd = xPropStates.end();
			while( aIter != aEnd )
			{
				if( aIter->mnIndex != -1 )
					nCount++;
				aIter++;
			}
		}

		if(nCount == 0)
		{
			// no hard attributes, use parent style name for export
			aShapeInfo.msStyleName = aParentName;
		}
		else
		{
			// there are filtered properties -> hard attributes
			// try to find this style in AutoStylePool
			aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Find(aShapeInfo.mnFamily, aParentName, xPropStates);

			if(!aShapeInfo.msStyleName.getLength())
			{
				// Style did not exist, add it to AutoStalePool
				aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Add(aShapeInfo.mnFamily, aParentName, xPropStates);
			}
		}

		// optionaly generate auto style for text attributes
		if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape)) && bObjSupportsText )
		{
			xPropStates = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter( xPropSet );

			// ----------------------------------------------------------------------
			// yet more additionally, we need to care for the ParaAdjust property
			if ( XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType )
			{
				uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
				uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
                if ( xPropSetInfo.is() && xPropState.is() )
                {
				    // this is because:
				    // * if controls shapes have a ParaAdjust property, then this is the Align property of the control model
				    // * control models are allowed to have an Align of "void"
				    // * the Default for control model's Align is TextAlign_LEFT
				    // * defaults for style properties are not written, but we need to write the "left",
				    //   because we need to distiguish this "left" from the case where not align attribute
				    //   is present which means "void"
				    // 102407 - 2002-11-01 - fs@openoffice.org
				    static const ::rtl::OUString s_sParaAdjustPropertyName( RTL_CONSTASCII_USTRINGPARAM( "ParaAdjust" ) );
				    if  (   xPropSetInfo->hasPropertyByName( s_sParaAdjustPropertyName )
                        &&  ( beans::PropertyState_DEFAULT_VALUE == xPropState->getPropertyState( s_sParaAdjustPropertyName ) )
                        )
					{
						sal_Int32 nIndex = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->getPropertySetMapper()->FindEntryIndex( CTF_SD_SHAPE_PARA_ADJUST );
							// TODO : this retrieval of the index should be moved into the ctor, holding the index
							//			as member, thus saving time.
						DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for the ParaAdjust context id!");

						uno::Any aParaAdjustValue = xPropSet->getPropertyValue( s_sParaAdjustPropertyName );
						XMLPropertyState aAlignDefaultState( nIndex, aParaAdjustValue );

						xPropStates.push_back( aAlignDefaultState );
					}
                }
			}
			// ----------------------------------------------------------------------

			nCount = 0;
			std::vector< XMLPropertyState >::iterator aIter = xPropStates.begin();
			std::vector< XMLPropertyState >::iterator aEnd = xPropStates.end();
			while( aIter != aEnd )
			{
				if( aIter->mnIndex != -1 )
					nCount++;
				aIter++;
			}

			if( nCount )
			{
				const OUString aEmpty;
				aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, aEmpty, xPropStates );
				if(!aShapeInfo.msTextStyleName.getLength())
				{
					// Style did not exist, add it to AutoStalePool
					aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TEXT_PARAGRAPH, aEmpty, xPropStates);
				}
			}
		}
	}

	// ----------------------------------------
	// prepare animation informations if needed
	// ----------------------------------------
	if( mxAnimationsExporter.is() )
		mxAnimationsExporter->prepare( xShape, mrExport );

	// check for special shapes

	switch( aShapeInfo.meShapeType )
	{
		case XmlShapeTypeDrawConnectorShape:
		{
			uno::Reference< uno::XInterface > xConnection;

			// create shape ids for export later
			xPropSet->getPropertyValue( msStartShape ) >>= xConnection;
			if( xConnection.is() )
				mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );

			xPropSet->getPropertyValue( msEndShape ) >>= xConnection;
			if( xConnection.is() )
				mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );
			break;
		}
		case XmlShapeTypePresTableShape:
		case XmlShapeTypeDrawTableShape:
		{
			try
			{
				uno::Reference< table::XColumnRowRange > xRange( xSet->getPropertyValue( msModel ), uno::UNO_QUERY_THROW );
				GetShapeTableExport()->collectTableAutoStyles( xRange );
			}
			catch( uno::Exception& )
			{
				DBG_ERROR( "XMLShapeExport::collectShapeAutoStyles(): exception caught while collection auto styles for a table!" );
			}
			break;
		}
		default:
			break;
	}

	maShapeInfos.push_back( aShapeInfo );
	maCurrentInfo = maShapeInfos.begin();

	// -----------------------------------------------------
	// check for shape collections (group shape or 3d scene)
	// and collect contained shapes style infos
	// -----------------------------------------------------
	const uno::Reference< drawing::XShape >& xCollection = aShapeInfo.xCustomShapeReplacement.is()
												? aShapeInfo.xCustomShapeReplacement : xShape;
	{
		uno::Reference< drawing::XShapes > xShapes( xCollection, uno::UNO_QUERY );
		if( xShapes.is() )
		{
			collectShapesAutoStyles( xShapes );
		}
	}
}

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

// --> OD 2008-05-08 #refactorlists#
namespace
{
    class NewTextListsHelper
    {
        public:
            NewTextListsHelper( SvXMLExport& rExp )
                : mrExport( rExp )
            {
                mrExport.GetTextParagraphExport()->PushNewTextListsHelper();
            }

            ~NewTextListsHelper()
            {
                mrExport.GetTextParagraphExport()->PopTextListsHelper();
            }

        private:
            SvXMLExport& mrExport;
    };
}
// This method exports the given XShape
void XMLShapeExport::exportShape(const uno::Reference< drawing::XShape >& xShape,
								 sal_Int32 nFeatures /* = SEF_DEFAULT */,
								 com::sun::star::awt::Point* pRefPoint /* = NULL */,
                                 SvXMLAttributeList* pAttrList /* = NULL */ )
{
    if( maCurrentShapesIter == maShapesInfos.end() )
	{
		DBG_ERROR( "XMLShapeExport::exportShape(): no auto styles where collected before export" );
		return;
	}
	sal_Int32 nZIndex = 0;
	uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );


	::std::auto_ptr< SvXMLElementExport >  mpHyperlinkElement;

	// export hyperlinks with <a><shape/></a>. Currently only in draw since draw
	// does not support document events
	if( xSet.is() && (GetExport().GetModelType() == SvtModuleOptions::E_DRAW) ) try
	{
		presentation::ClickAction eAction = presentation::ClickAction_NONE;
		xSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("OnClick"))) >>= eAction;

		if( (eAction == presentation::ClickAction_DOCUMENT) ||
			(eAction == presentation::ClickAction_BOOKMARK) )
		{
			OUString sURL;
			xSet->getPropertyValue(msBookmark) >>= sURL;

			if( sURL.getLength() )
			{
				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );
				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
				mpHyperlinkElement.reset( new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_A, sal_True, sal_True) );
			}
		}
	}
	catch( uno::Exception& )
	{
		DBG_ERROR("XMLShapeExport::exportShape(): exception during hyperlink export");
	}


	if( xSet.is() )
		xSet->getPropertyValue(msZIndex) >>= nZIndex;

	ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;

	if( (sal_Int32)aShapeInfoVector.size() <= nZIndex )
	{
		DBG_ERROR( "XMLShapeExport::exportShape(): no shape info collected for a given shape" );
		return;
	}

    // --> OD 2008-05-08 #refactorlists#
    NewTextListsHelper aNewTextListsHelper( mrExport );
    // <--

	const ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];


#ifdef DBG_UTIL
	// ---------------------------------------
	// check if this is the correct ShapesInfo
	// ---------------------------------------
	uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY );
	if( xChild.is() )
	{
		uno::Reference< drawing::XShapes > xParent( xChild->getParent(), uno::UNO_QUERY );
		DBG_ASSERT( xParent.is() && xParent.get() == (*maCurrentShapesIter).first.get(), "XMLShapeExport::exportShape(): Wrong call to XMLShapeExport::seekShapes()" );
	}

	// -----------------------------
	// first compute the shapes type
	// -----------------------------
	{
		XmlShapeType eShapeType(XmlShapeTypeNotYetSet);
		ImpCalcShapeType(xShape, eShapeType);

		DBG_ASSERT( eShapeType == aShapeInfo.meShapeType, "exportShape callings do not correspond to collectShapeAutoStyles calls!" );
	}
#endif

	// ----------------------------------------
	// collect animation informations if needed
	// ----------------------------------------
	if( mxAnimationsExporter.is() )
		mxAnimationsExporter->collect( xShape, mrExport );

	// -------------------------------
	// export shapes name if he has one
    // --> OD 2006-03-13 #i51726#
    // Export of the shape name for text documents only if the OpenDocument
    // file format is written - exceptions are group shapes.
    // Note: Writer documents in OpenOffice.org file format doesn't contain
    //       any names for shapes, except for group shapes.
	// -------------------------------
	{
        // --> OD 2006-03-10 #i51726#
        if ( ( GetExport().GetModelType() != SvtModuleOptions::E_WRITER &&
               GetExport().GetModelType() != SvtModuleOptions::E_WRITERWEB &&
               GetExport().GetModelType() != SvtModuleOptions::E_WRITERGLOBAL ) ||
             ( GetExport().getExportFlags() & EXPORT_OASIS ) != 0 ||
             aShapeInfo.meShapeType == XmlShapeTypeDrawGroupShape ||
             ( aShapeInfo.meShapeType == XmlShapeTypeDrawCustomShape &&
               aShapeInfo.xCustomShapeReplacement.is() ) )
        {
            uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
            if( xNamed.is() )
            {
                const OUString aName( xNamed->getName() );
                if( aName.getLength() )
                    mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, aName );
            }
        }
        // <--
	}

	// ------------------
	// export style name
	// ------------------
	if( aShapeInfo.msStyleName.getLength() != 0 )
	{
		if(XML_STYLE_FAMILY_SD_GRAPHICS_ID == aShapeInfo.mnFamily)
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
		else
			mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
	}

	// ------------------
	// export text style name
	// ------------------
	if( aShapeInfo.msTextStyleName.getLength() != 0 )
	{
		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TEXT_STYLE_NAME, aShapeInfo.msTextStyleName );
	}

	// --------------------------
	// export shapes id if needed
	// --------------------------
	{
		uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
		const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRef );
		if( rShapeId.getLength() )
        {
            mrExport.AddAttributeIdLegacy(XML_NAMESPACE_DRAW, rShapeId);
        }
	}

	// --------------------------
	// export layer information
	// --------------------------
	if( IsLayerExportEnabled() )
	{
		// check for group or scene shape and not export layer if this is one
		uno::Reference< drawing::XShapes > xShapes( xShape, uno::UNO_QUERY );
		if( !xShapes.is() )
		{
			try
			{
				uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
				OUString aLayerName;
				xProps->getPropertyValue( OUString::createFromAscii( "LayerName" ) ) >>= aLayerName;
				mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LAYER, aLayerName );

			}
			catch( uno::Exception e )
			{
				DBG_ERROR( "could not export layer name for shape!" );
			}
		}
	}

	// export draw:display (do not export in ODF 1.2 or older)
	if( xSet.is() && ( mrExport.getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) )
	{
		if( aShapeInfo.meShapeType != XmlShapeTypeDrawPageShape && aShapeInfo.meShapeType != XmlShapeTypePresPageShape &&
			aShapeInfo.meShapeType != XmlShapeTypeHandoutShape && aShapeInfo.meShapeType != XmlShapeTypeDrawChartShape )
			
		try
		{
			sal_Bool bVisible = sal_True;
			sal_Bool bPrintable = sal_True;

			xSet->getPropertyValue(msVisible) >>= bVisible;
			xSet->getPropertyValue(msPrintable) >>= bPrintable;

			XMLTokenEnum eDisplayToken = XML_TOKEN_INVALID;
			const unsigned short nDisplay = (bVisible ? 2 : 0) | (bPrintable ? 1 : 0);
			switch( nDisplay )
			{
			case 0: eDisplayToken = XML_NONE; break;
			case 1: eDisplayToken = XML_PRINTER; break;
			case 2: eDisplayToken = XML_SCREEN; break;
			// case 3: eDisplayToken = XML_ALWAYS break; this is the default
			}

			if( eDisplayToken != XML_TOKEN_INVALID )
				mrExport.AddAttribute(XML_NAMESPACE_DRAW_EXT, XML_DISPLAY, eDisplayToken );
		}
		catch( uno::Exception& )
		{
			DBG_ERROR( "XMLShapeExport::exportShape(), exception caught!" );
		}
	}

	// #82003# test export count
	// #91587# ALWAYS increment since now ALL to be exported shapes are counted.
	if(mrExport.GetShapeExport()->IsHandleProgressBarEnabled())
	{
		mrExport.GetProgressBarHelper()->Increment();
	}

	onExport( xShape );

	// --------------------
	// export shape element
	// --------------------
	switch(aShapeInfo.meShapeType)
	{
		case XmlShapeTypeDrawRectangleShape:
		{
			ImpExportRectangleShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}
		case XmlShapeTypeDrawEllipseShape:
		{
			ImpExportEllipseShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}
		case XmlShapeTypeDrawLineShape:
		{
			ImpExportLineShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}
		case XmlShapeTypeDrawPolyPolygonShape:	// closed PolyPolygon
		case XmlShapeTypeDrawPolyLineShape:		// open PolyPolygon
		case XmlShapeTypeDrawClosedBezierShape:	// closed PolyPolygon containing curves
		case XmlShapeTypeDrawOpenBezierShape:	// open PolyPolygon containing curves
		{
			ImpExportPolygonShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawTextShape:
		case XmlShapeTypePresTitleTextShape:
		case XmlShapeTypePresOutlinerShape:
		case XmlShapeTypePresSubtitleShape:
		case XmlShapeTypePresNotesShape:
		case XmlShapeTypePresHeaderShape:
		case XmlShapeTypePresFooterShape:
		case XmlShapeTypePresSlideNumberShape:
		case XmlShapeTypePresDateTimeShape:
		{
			ImpExportTextBoxShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawGraphicObjectShape:
		case XmlShapeTypePresGraphicObjectShape:
		{
			ImpExportGraphicObjectShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawChartShape:
		case XmlShapeTypePresChartShape:
		{
			ImpExportChartShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint, pAttrList );
			break;
		}

		case XmlShapeTypeDrawControlShape:
		{
			ImpExportControlShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawConnectorShape:
		{
			ImpExportConnectorShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawMeasureShape:
		{
			ImpExportMeasureShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawOLE2Shape:
		case XmlShapeTypePresOLE2Shape:
		case XmlShapeTypeDrawSheetShape:
		case XmlShapeTypePresSheetShape:
		{
			ImpExportOLE2Shape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypePresTableShape:
		case XmlShapeTypeDrawTableShape:
		{
			ImpExportTableShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawPageShape:
		case XmlShapeTypePresPageShape:
		case XmlShapeTypeHandoutShape:
		{
			ImpExportPageShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawCaptionShape:
		{
			ImpExportCaptionShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDraw3DCubeObject:
		case XmlShapeTypeDraw3DSphereObject:
		case XmlShapeTypeDraw3DLatheObject:
		case XmlShapeTypeDraw3DExtrudeObject:
		{
			ImpExport3DShape(xShape, aShapeInfo.meShapeType);
			break;
		}

		case XmlShapeTypeDraw3DSceneObject:
		{
			ImpExport3DSceneShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawGroupShape:
		{
			// empty group
			ImpExportGroupShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawFrameShape:
		{
			ImpExportFrameShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawAppletShape:
		{
			ImpExportAppletShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawPluginShape:
		{
			ImpExportPluginShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypeDrawCustomShape:
		{
			if ( aShapeInfo.xCustomShapeReplacement.is() )
				ImpExportGroupShape( aShapeInfo.xCustomShapeReplacement, XmlShapeTypeDrawGroupShape, nFeatures, pRefPoint );
			else
				ImpExportCustomShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypePresMediaShape:
		case XmlShapeTypeDrawMediaShape:
		{
			ImpExportMediaShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
			break;
		}

		case XmlShapeTypePresOrgChartShape:
		case XmlShapeTypeUnknown:
		case XmlShapeTypeNotYetSet:
		default:
		{
			// this should never happen and is an error
			DBG_ERROR("XMLEXP: WriteShape: unknown or unexpected type of shape in export!");
			break;
		}
	}

	mpHyperlinkElement.reset();

	// #97489# #97111#
	// if there was an error and no element for the shape was exported
	// we need to clear the attribute list or the attributes will be
	// set on the next exported element, which can result in corrupt
	// xml files due to duplicate attributes

	mrExport.CheckAttrList();	// asserts in non pro if we have attributes left
	mrExport.ClearAttrList();	// clears the attributes
}

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

// This method collects all automatic styles for the shapes inside the given XShapes collection
void XMLShapeExport::collectShapesAutoStyles( const uno::Reference < drawing::XShapes >& xShapes )
{
	ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
	seekShapes( xShapes );

	uno::Reference< drawing::XShape > xShape;
	const sal_Int32 nShapeCount(xShapes->getCount());
	for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
	{
		xShapes->getByIndex(nShapeId) >>= xShape;
		DBG_ASSERT( xShape.is(), "Shape without a XShape?" );
		if(!xShape.is())
			continue;

		collectShapeAutoStyles( xShape );
	}

	maCurrentShapesIter = aOldCurrentShapesIter;
}

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

// This method exports all XShape inside the given XShapes collection
void XMLShapeExport::exportShapes( const uno::Reference < drawing::XShapes >& xShapes, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */ )
{
	ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
	seekShapes( xShapes );

	uno::Reference< drawing::XShape > xShape;
	const sal_Int32 nShapeCount(xShapes->getCount());
	for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
	{
		xShapes->getByIndex(nShapeId) >>= xShape;
		DBG_ASSERT( xShape.is(), "Shape without a XShape?" );
		if(!xShape.is())
			continue;

		exportShape( xShape, nFeatures, pRefPoint );
	}

	maCurrentShapesIter = aOldCurrentShapesIter;
}

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

void XMLShapeExport::seekShapes( const uno::Reference< drawing::XShapes >& xShapes ) throw()
{
	if( xShapes.is() )
	{
		maCurrentShapesIter = maShapesInfos.find( xShapes );
		if( maCurrentShapesIter == maShapesInfos.end() )
		{
			ImplXMLShapeExportInfoVector aNewInfoVector;
			aNewInfoVector.resize( (ShapesInfos::size_type) xShapes->getCount() );
			maShapesInfos[ xShapes ] = aNewInfoVector;

			maCurrentShapesIter = maShapesInfos.find( xShapes );

			DBG_ASSERT( maCurrentShapesIter != maShapesInfos.end(), "XMLShapeExport::seekShapes(): insert into stl::map failed" );
		}

		DBG_ASSERT( (*maCurrentShapesIter).second.size() == (ShapesInfos::size_type)xShapes->getCount(), "XMLShapeExport::seekShapes(): XShapes size varied between calls" );

	}
	else
	{
		maCurrentShapesIter = maShapesInfos.end();
	}
}

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

void XMLShapeExport::exportAutoStyles()
{
	// export all autostyle infos

	// ...for graphic
//	if(IsFamilyGraphicUsed())
	{
		GetExport().GetAutoStylePool()->exportXML(
			XML_STYLE_FAMILY_SD_GRAPHICS_ID
            , GetExport().GetDocHandler(),
			GetExport().GetMM100UnitConverter(),
			GetExport().GetNamespaceMap()
            );
	}

	// ...for presentation
//	if(IsFamilyPresentationUsed())
	{
		GetExport().GetAutoStylePool()->exportXML(
			XML_STYLE_FAMILY_SD_PRESENTATION_ID
            , GetExport().GetDocHandler(),
			GetExport().GetMM100UnitConverter(),
			GetExport().GetNamespaceMap()
            );
	}

	if( mxShapeTableExport.is() )
		mxShapeTableExport->exportAutoStyles();
}

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

/// returns the export property mapper for external chaining
SvXMLExportPropertyMapper* XMLShapeExport::CreateShapePropMapper(
	SvXMLExport& rExport )
{
	UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rExport.GetModel(), rExport );
	UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory );
	SvXMLExportPropertyMapper* pResult =
		new XMLShapeExportPropertyMapper( xMapper,
										  (XMLTextListAutoStylePool*)&rExport.GetTextParagraphExport()->GetListAutoStylePool(),
										  rExport );
	// chain text attributes
	return pResult;
}

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

void XMLShapeExport::ImpCalcShapeType(const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType& eShapeType)
{
	// set in every case, so init here
	eShapeType = XmlShapeTypeUnknown;

	uno::Reference< drawing::XShapeDescriptor > xShapeDescriptor(xShape, uno::UNO_QUERY);
	if(xShapeDescriptor.is())
	{
		String aType((OUString)xShapeDescriptor->getShapeType());

		if(aType.EqualsAscii((const sal_Char*)"com.sun.star.", 0, 13))
		{
			if(aType.EqualsAscii("drawing.", 13, 8))
			{
				// drawing shapes
				if     (aType.EqualsAscii("Rectangle", 21, 9)) { eShapeType = XmlShapeTypeDrawRectangleShape; }

				// #i72177# Note: Correcting CustomShape, CustomShape->Custom, len from 9 (was wrong anyways) to 6.
				// As can be seen at the other compares, the appendix "Shape" is left out of the comparison.
				else if(aType.EqualsAscii("Custom", 21, 6)) { eShapeType = XmlShapeTypeDrawCustomShape; }

				else if(aType.EqualsAscii("Ellipse", 21, 7)) { eShapeType = XmlShapeTypeDrawEllipseShape; }
				else if(aType.EqualsAscii("Control", 21, 7)) { eShapeType = XmlShapeTypeDrawControlShape; }
				else if(aType.EqualsAscii("Connector", 21, 9)) { eShapeType = XmlShapeTypeDrawConnectorShape; }
				else if(aType.EqualsAscii("Measure", 21, 7)) { eShapeType = XmlShapeTypeDrawMeasureShape; }
				else if(aType.EqualsAscii("Line", 21, 4)) { eShapeType = XmlShapeTypeDrawLineShape; }

				// #i72177# Note: This covers two types by purpose, PolyPolygonShape and PolyPolygonPathShape
				else if(aType.EqualsAscii("PolyPolygon", 21, 11)) { eShapeType = XmlShapeTypeDrawPolyPolygonShape; }

				// #i72177# Note: This covers two types by purpose, PolyLineShape and PolyLinePathShape
				else if(aType.EqualsAscii("PolyLine", 21, 8)) { eShapeType = XmlShapeTypeDrawPolyLineShape; }

				else if(aType.EqualsAscii("OpenBezier", 21, 10)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
				else if(aType.EqualsAscii("ClosedBezier", 21, 12)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }

				// #i72177# FreeHand (opened and closed) now supports the types OpenFreeHandShape and
				// ClosedFreeHandShape respectively. Represent them as bezier shapes
				else if(aType.EqualsAscii("OpenFreeHand", 21, 12)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
				else if(aType.EqualsAscii("ClosedFreeHand", 21, 14)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }

				else if(aType.EqualsAscii("GraphicObject", 21, 13)) { eShapeType = XmlShapeTypeDrawGraphicObjectShape; }
				else if(aType.EqualsAscii("Group", 21, 5)) { eShapeType = XmlShapeTypeDrawGroupShape; }
				else if(aType.EqualsAscii("Text", 21, 4)) { eShapeType = XmlShapeTypeDrawTextShape; }
				else if(aType.EqualsAscii("OLE2", 21, 4))
				{
					eShapeType = XmlShapeTypeDrawOLE2Shape;

					// get info about presentation shape
					uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);

					if(xPropSet.is())
					{
						rtl::OUString sCLSID;
						if(xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID"))) >>= sCLSID)
						{
							if (sCLSID.equals(mrExport.GetChartExport()->getChartCLSID()))
							{
								eShapeType = XmlShapeTypeDrawChartShape;
							}
							else if (
								sCLSID.equals(rtl::OUString( SvGlobalName( SO3_SC_CLASSID ).GetHexName()))
								// #110680#
								// same reaction for binfilter
								|| sCLSID.equals(rtl::OUString( SvGlobalName( BF_SO3_SC_CLASSID ).GetHexName()))
								)
							{
								eShapeType = XmlShapeTypeDrawSheetShape;
							}
							else
							{
								// general OLE2 Object
							}
						}
					}
				}
				else if(aType.EqualsAscii("Page", 21, 4)) { eShapeType = XmlShapeTypeDrawPageShape; }
				else if(aType.EqualsAscii("Frame", 21, 5)) { eShapeType = XmlShapeTypeDrawFrameShape; }
				else if(aType.EqualsAscii("Caption", 21, 7)) { eShapeType = XmlShapeTypeDrawCaptionShape; }
				else if(aType.EqualsAscii("Plugin", 21, 6)) { eShapeType = XmlShapeTypeDrawPluginShape; }
				else if(aType.EqualsAscii("Applet", 21, 6)) { eShapeType = XmlShapeTypeDrawAppletShape; }
				else if(aType.EqualsAscii("MediaShape", 21, 10)) { eShapeType = XmlShapeTypeDrawMediaShape; }
				else if(aType.EqualsAscii("TableShape", 21, 10)) { eShapeType = XmlShapeTypeDrawTableShape; }

				// 3D shapes
				else if(aType.EqualsAscii("Scene", 21 + 7, 5)) { eShapeType = XmlShapeTypeDraw3DSceneObject; }
				else if(aType.EqualsAscii("Cube", 21 + 7, 4)) { eShapeType = XmlShapeTypeDraw3DCubeObject; }
				else if(aType.EqualsAscii("Sphere", 21 + 7, 6)) { eShapeType = XmlShapeTypeDraw3DSphereObject; }
				else if(aType.EqualsAscii("Lathe", 21 + 7, 5)) { eShapeType = XmlShapeTypeDraw3DLatheObject; }
				else if(aType.EqualsAscii("Extrude", 21 + 7, 7)) { eShapeType = XmlShapeTypeDraw3DExtrudeObject; }
			}
			else if(aType.EqualsAscii("presentation.", 13, 13))
			{
				// presentation shapes
				if     (aType.EqualsAscii("TitleText", 26, 9)) { eShapeType = XmlShapeTypePresTitleTextShape; }
				else if(aType.EqualsAscii("Outliner", 26, 8)) { eShapeType = XmlShapeTypePresOutlinerShape;  }
				else if(aType.EqualsAscii("Subtitle", 26, 8)) { eShapeType = XmlShapeTypePresSubtitleShape;  }
				else if(aType.EqualsAscii("GraphicObject", 26, 13)) { eShapeType = XmlShapeTypePresGraphicObjectShape;  }
				else if(aType.EqualsAscii("Page", 26, 4)) { eShapeType = XmlShapeTypePresPageShape;  }
				else if(aType.EqualsAscii("OLE2", 26, 4))
				{
					eShapeType = XmlShapeTypePresOLE2Shape;

					// get info about presentation shape
					uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);

					if(xPropSet.is()) try
					{
						rtl::OUString sCLSID;
						if(xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID"))) >>= sCLSID)
						{
							if( sCLSID.equals(rtl::OUString( SvGlobalName( SO3_SC_CLASSID ).GetHexName())) ||
								sCLSID.equals(rtl::OUString( SvGlobalName( BF_SO3_SC_CLASSID ).GetHexName())) )
							{
								eShapeType = XmlShapeTypePresSheetShape;
							}
						}
					}
					catch( uno::Exception& )
					{
						DBG_ERROR( "XMLShapeExport::ImpCalcShapeType(), expected ole shape to have the CLSID property?" );
					}
				}
				else if(aType.EqualsAscii("Chart", 26, 5)) { eShapeType = XmlShapeTypePresChartShape;  }
				else if(aType.EqualsAscii("OrgChart", 26, 8)) { eShapeType = XmlShapeTypePresOrgChartShape;  }
				else if(aType.EqualsAscii("CalcShape", 26, 9)) { eShapeType = XmlShapeTypePresSheetShape; }
				else if(aType.EqualsAscii("TableShape", 26, 10)) { eShapeType = XmlShapeTypePresTableShape; }
				else if(aType.EqualsAscii("Notes", 26, 5)) { eShapeType = XmlShapeTypePresNotesShape;  }
				else if(aType.EqualsAscii("HandoutShape", 26, 12)) { eShapeType = XmlShapeTypeHandoutShape; }
				else if(aType.EqualsAscii("HeaderShape", 26, 11)) { eShapeType = XmlShapeTypePresHeaderShape; }
				else if(aType.EqualsAscii("FooterShape", 26, 11)) { eShapeType = XmlShapeTypePresFooterShape; }
				else if(aType.EqualsAscii("SlideNumberShape", 26, 16)) { eShapeType = XmlShapeTypePresSlideNumberShape; }
				else if(aType.EqualsAscii("DateTimeShape", 26, 13)) { eShapeType = XmlShapeTypePresDateTimeShape; }
				else if(aType.EqualsAscii("MediaShape", 26, 10)) { eShapeType = XmlShapeTypePresMediaShape; }
			}
		}
	}
}

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

extern SvXMLEnumMapEntry aXML_GlueAlignment_EnumMap[];
extern SvXMLEnumMapEntry aXML_GlueEscapeDirection_EnumMap[];

/** exports all user defined glue points */
void XMLShapeExport::ImpExportGluePoints( const uno::Reference< drawing::XShape >& xShape )
{
	uno::Reference< drawing::XGluePointsSupplier > xSupplier( xShape, uno::UNO_QUERY );
	if( !xSupplier.is() )
		return;

	uno::Reference< container::XIdentifierAccess > xGluePoints( xSupplier->getGluePoints(), uno::UNO_QUERY );
	if( !xGluePoints.is() )
		return;

	drawing::GluePoint2 aGluePoint;

	uno::Sequence< sal_Int32 > aIdSequence( xGluePoints->getIdentifiers() );

	const sal_Int32 nCount = aIdSequence.getLength();
	for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
	{
		const sal_Int32 nIdentifier = aIdSequence[nIndex];
		if( (xGluePoints->getByIdentifier( nIdentifier ) >>= aGluePoint) && aGluePoint.IsUserDefined )
		{
			// export only user defined glue points

			const OUString sId( OUString::valueOf( nIdentifier ) );
			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_ID, sId );

			mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aGluePoint.Position.X);
			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, msBuffer.makeStringAndClear());

			mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aGluePoint.Position.Y);
			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, msBuffer.makeStringAndClear());

			if( !aGluePoint.IsRelative )
			{
				SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.PositionAlignment, aXML_GlueAlignment_EnumMap );
				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ALIGN, msBuffer.makeStringAndClear() );
			}

			if( aGluePoint.Escape != drawing::EscapeDirection_SMART )
			{
				SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.Escape, aXML_GlueEscapeDirection_EnumMap );
				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ESCAPE_DIRECTION, msBuffer.makeStringAndClear() );
			}

			SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_DRAW, XML_GLUE_POINT, sal_True, sal_True);
		}
	}
}

void XMLShapeExport::ExportGraphicDefaults()
{
	XMLStyleExport aStEx(mrExport, OUString(), mrExport.GetAutoStylePool().get());

	// construct PropertySetMapper
	UniReference< SvXMLExportPropertyMapper > xPropertySetMapper( CreateShapePropMapper( mrExport ) );
	((XMLShapeExportPropertyMapper*)xPropertySetMapper.get())->SetAutoStyles( sal_False );

	// chain text attributes
	xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(mrExport));

	// chain special Writer/text frame default attributes
    xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaDefaultExtPropMapper(mrExport));

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

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

void XMLShapeExport::onExport( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& )
{
}

const rtl::Reference< XMLTableExport >& XMLShapeExport::GetShapeTableExport()
{
	if( !mxShapeTableExport.is() )
	{
		rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrExport.GetModel(), mrExport ) );
        UniReference < XMLPropertySetMapper > xMapper( new XMLShapePropertySetMapper( xFactory.get() ) );
		rtl::Reference< SvXMLExportPropertyMapper > xPropertySetMapper( new XMLShapeExportPropertyMapper( xMapper, (XMLTextListAutoStylePool*)&mrExport.GetTextParagraphExport()->GetListAutoStylePool(), mrExport ) );
		mxShapeTableExport = new XMLTableExport( mrExport, xPropertySetMapper, xFactory );
	}

	return mxShapeTableExport;
}
