/**************************************************************
 * 
 * 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 <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/io/XSeekableInputStream.hpp>
#include <com/sun/star/drawing/HomogenMatrix.hpp>
#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
#include <com/sun/star/drawing/ProjectionMode.hpp>
#include <com/sun/star/drawing/ShadeMode.hpp>
#include <com/sun/star/drawing/Direction3D.hpp>
#include <com/sun/star/drawing/Position3D.hpp>
#include <com/sun/star/drawing/CameraGeometry.hpp>
#include <com/sun/star/drawing/DoubleSequence.hpp>

#include <com/sun/star/table/XColumnRowRange.hpp>

#ifndef _XMLOFF_SHAPEEXPORT_HXX
#include <xmloff/shapeexport.hxx>
#endif
#include "sdpropls.hxx"
#include <tools/debug.hxx>
#include <rtl/ustrbuf.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmluconv.hxx>
#include "xexptran.hxx"
#include <xmloff/xmltoken.hxx>
#include "EnhancedCustomShapeToken.hxx"
#include <com/sun/star/container/XIdentifierContainer.hpp>
#include <com/sun/star/drawing/ShadeMode.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
#ifndef _COM_SUN_STAR_DRAWING_ENHANCEDCUSTOMSHAPEPARAMETERPARI_HPP_
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
#endif
#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
#include <com/sun/star/beans/PropertyValues.hpp>
#include <rtl/math.hxx>
#include <tools/string.hxx>
#include <basegfx/vector/b3dvector.hxx>

#include "xmloff/xmlnmspe.hxx"
#include "XMLBase64Export.hxx"

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

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

using ::com::sun::star::embed::XStorage;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;

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

void ExportParameter( rtl::OUStringBuffer& rStrBuffer, const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter )
{
	if ( rStrBuffer.getLength() )
		rStrBuffer.append( (sal_Unicode)' ' );
	if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
	{
		double fNumber = 0.0;
		rParameter.Value >>= fNumber;
		::rtl::math::doubleToUStringBuffer( rStrBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', sal_True );
	}
	else
	{
		sal_Int32 nValue = 0;
		rParameter.Value >>= nValue;

		switch( rParameter.Type )
		{
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
			{
				rStrBuffer.append( (sal_Unicode)'?' );
				rStrBuffer.append( (sal_Unicode)'f' );
				rStrBuffer.append( rtl::OUString::valueOf( nValue ) );
			}
			break;

			case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
			{
				rStrBuffer.append( (sal_Unicode)'$' );
				rStrBuffer.append( rtl::OUString::valueOf( nValue ) );
			}
			break;
			
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM :
				rStrBuffer.append( GetXMLToken( XML_BOTTOM ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT :
				rStrBuffer.append( GetXMLToken( XML_RIGHT ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP :
				rStrBuffer.append( GetXMLToken( XML_TOP ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT :
				rStrBuffer.append( GetXMLToken( XML_LEFT ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::XSTRETCH :
				rStrBuffer.append( GetXMLToken( XML_XSTRETCH ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::YSTRETCH :
				rStrBuffer.append( GetXMLToken( XML_YSTRETCH ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::HASSTROKE :
				rStrBuffer.append( GetXMLToken( XML_HASSTROKE ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::HASFILL :
				rStrBuffer.append( GetXMLToken( XML_HASFILL ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::WIDTH :
				rStrBuffer.append( GetXMLToken( XML_WIDTH ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::HEIGHT :
				rStrBuffer.append( GetXMLToken( XML_HEIGHT ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGWIDTH :
				rStrBuffer.append( GetXMLToken( XML_LOGWIDTH ) ); break;
			case com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT :
				rStrBuffer.append( GetXMLToken( XML_LOGHEIGHT ) ); break;
			default :
				rStrBuffer.append( rtl::OUString::valueOf( nValue ) );
		}
	}
}

void ImpExportEquations( SvXMLExport& rExport, const uno::Sequence< rtl::OUString >& rEquations )
{
	sal_Int32 i;
	for ( i = 0; i < rEquations.getLength(); i++ )
	{
		rtl::OUString aStr( String( 'f' ) );
		aStr += rtl::OUString::valueOf( i );
		rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aStr );

		aStr = rEquations[ i ];
		sal_Int32 nIndex = 0;
		do
		{
			nIndex = aStr.indexOf( (sal_Unicode)'?', nIndex );
			if ( nIndex != -1 )
			{
				rtl::OUString aNew( aStr.copy( 0, nIndex + 1 ) );
				aNew += String( 'f' );
				aNew += aStr.copy( nIndex + 1, ( aStr.getLength() - nIndex ) - 1 );
				aStr = aNew;
				nIndex++;
			}
		} while( nIndex != -1 );
		rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FORMULA, aStr );
		SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_EQUATION, sal_True, sal_True );
	}
}

void ImpExportHandles( SvXMLExport& rExport, const uno::Sequence< beans::PropertyValues >& rHandles )
{
	sal_uInt32 i, j, nElements = rHandles.getLength();
	if ( nElements )
	{
		rtl::OUString		aStr;
		rtl::OUStringBuffer aStrBuffer;

		for ( i = 0; i < nElements; i++ )
		{
			sal_Bool bPosition = sal_False;
			const uno::Sequence< beans::PropertyValue >& rPropSeq = rHandles[ i ];
			for ( j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
			{
				const beans::PropertyValue& rPropVal = rPropSeq[ j ];
				switch( EASGet( rPropVal.Name ) )
				{
					case EAS_Position :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
						if ( rPropVal.Value >>= aPosition )
						{
							ExportParameter( aStrBuffer, aPosition.First );
							ExportParameter( aStrBuffer, aPosition.Second );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POSITION, aStr );
							bPosition = sal_True;
						}
					}
					break;
					case EAS_MirroredX :
					{
						sal_Bool bMirroredX = sal_Bool();
						if ( rPropVal.Value >>= bMirroredX )
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_HORIZONTAL,
								bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
					}
					break;
					case EAS_MirroredY :
					{
						sal_Bool bMirroredY = sal_Bool();
						if ( rPropVal.Value >>= bMirroredY )
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_VERTICAL,
								bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
					}
					break;
					case EAS_Switched :
					{
						sal_Bool bSwitched = sal_Bool();
						if ( rPropVal.Value >>= bSwitched )
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_SWITCHED,
								bSwitched ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
					}
					break;
					case EAS_Polar :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar;
						if ( rPropVal.Value >>= aPolar )
						{
							ExportParameter( aStrBuffer, aPolar.First );
							ExportParameter( aStrBuffer, aPolar.Second );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POLAR, aStr );
						}
					}
					break;
					case EAS_RadiusRangeMinimum :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
						if ( rPropVal.Value >>= aRadiusRangeMinimum )
						{
							ExportParameter( aStrBuffer, aRadiusRangeMinimum );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MINIMUM, aStr );
						}
					}
					break;
					case EAS_RadiusRangeMaximum :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
						if ( rPropVal.Value >>= aRadiusRangeMaximum )
						{
							ExportParameter( aStrBuffer, aRadiusRangeMaximum );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MAXIMUM, aStr );
						}
					}
					break;
					case EAS_RangeXMinimum :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
						if ( rPropVal.Value >>= aXRangeMinimum )
						{
							ExportParameter( aStrBuffer, aXRangeMinimum );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MINIMUM, aStr );
						}
					}
					break;
					case EAS_RangeXMaximum :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
						if ( rPropVal.Value >>= aXRangeMaximum )
						{
							ExportParameter( aStrBuffer, aXRangeMaximum );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MAXIMUM, aStr );
						}
					}
					break;
					case EAS_RangeYMinimum :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
						if ( rPropVal.Value >>= aYRangeMinimum )
						{
							ExportParameter( aStrBuffer, aYRangeMinimum );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MINIMUM, aStr );
						}
					}
					break;
					case EAS_RangeYMaximum :
					{
						com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
						if ( rPropVal.Value >>= aYRangeMaximum )
						{
							ExportParameter( aStrBuffer, aYRangeMaximum );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MAXIMUM, aStr );
						}
					}
					break;
					default:
						break;
				}
			}
			if ( bPosition )
				SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_HANDLE, sal_True, sal_True );
			else
				rExport.ClearAttrList();
		}
	}
}

void ImpExportEnhancedPath( SvXMLExport& rExport,
	const uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rCoordinates,
		const uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments )
{

	rtl::OUString		aStr;
	rtl::OUStringBuffer aStrBuffer;

	sal_Int32 i, j, k, l;

	sal_Int32 nCoords = rCoordinates.getLength();
	sal_Int32 nSegments = rSegments.getLength();
	sal_Bool bSimpleSegments = nSegments == 0;
	if ( bSimpleSegments )
		nSegments = 4;
	for ( j = i = 0; j < nSegments; j++ )
	{
		com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
		if ( bSimpleSegments )
		{
			// if there are not enough segments we will default them
			switch( j )
			{
				case 0 :
				{
					aSegment.Count = 1;
					aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
				}
				break;
				case 1 :
				{
					aSegment.Count = (sal_Int16)Min( nCoords - 1, (sal_Int32)32767 );
					aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
				}
				break;
				case 2 :
				{
					aSegment.Count = 1;
					aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
				}
				break;
				case 3 :
				{
					aSegment.Count = 1;
					aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
				}
				break;
			}
		}
		else
			aSegment = rSegments[ j ];

		if ( aStrBuffer.getLength() )
			aStrBuffer.append( (sal_Unicode)' ' );

		sal_Int32 nParameter = 0;
		switch( aSegment.Command )
		{
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
				aStrBuffer.append( (sal_Unicode)'Z' ); break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
				aStrBuffer.append( (sal_Unicode)'N' ); break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
				aStrBuffer.append( (sal_Unicode)'F' ); break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
				aStrBuffer.append( (sal_Unicode)'S' ); break;

			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
				aStrBuffer.append( (sal_Unicode)'M' ); nParameter = 1; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO :
				aStrBuffer.append( (sal_Unicode)'L' ); nParameter = 1; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
				aStrBuffer.append( (sal_Unicode)'C' ); nParameter = 3; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
				aStrBuffer.append( (sal_Unicode)'T' ); nParameter = 3; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
				aStrBuffer.append( (sal_Unicode)'U' ); nParameter = 3; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
				aStrBuffer.append( (sal_Unicode)'A' ); nParameter = 4; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC :
				aStrBuffer.append( (sal_Unicode)'B' ); nParameter = 4; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
				aStrBuffer.append( (sal_Unicode)'W' ); nParameter = 4; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
				aStrBuffer.append( (sal_Unicode)'V' ); nParameter = 4; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
				aStrBuffer.append( (sal_Unicode)'X' ); nParameter = 1; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
				aStrBuffer.append( (sal_Unicode)'Y' ); nParameter = 1; break;
			case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
				aStrBuffer.append( (sal_Unicode)'Q' ); nParameter = 2; break;

			default : // ups, seems to be something wrong
			{
				aSegment.Count = 1;
				aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
			}
			break;
		}
		if ( nParameter )
		{
			for ( k = 0; k < aSegment.Count; k++ )
			{
				if ( ( i + nParameter ) <= nCoords )
				{
					for ( l = 0; l < nParameter; l++ )
					{
						ExportParameter( aStrBuffer, rCoordinates[ i ].First );
						ExportParameter( aStrBuffer, rCoordinates[ i++ ].Second );
					}
				}
				else
				{
					j = nSegments;	// error -> exiting
					break;
				}
			}
		}
	}
	aStr = aStrBuffer.makeStringAndClear();
	rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ENHANCED_PATH, aStr );
}

void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Reference< beans::XPropertySet >& xPropSet )
{
	sal_Bool bEquations = sal_False;
	uno::Sequence< rtl::OUString > aEquations;

	sal_Bool bHandles = sal_False;
	uno::Sequence< beans::PropertyValues > aHandles;

	sal_Bool bCoordinates = sal_False;
	uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
	uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;

	uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues;

	rtl::OUString		aStr;
	rtl::OUStringBuffer aStrBuffer;
	SvXMLUnitConverter& rUnitConverter = rExport.GetMM100UnitConverter();

	uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );

	// geometry
	const rtl::OUString	sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) );
	if ( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( sCustomShapeGeometry ) )
	{
		uno::Any aGeoPropSet( xPropSet->getPropertyValue( sCustomShapeGeometry ) );
		uno::Sequence< beans::PropertyValue > aGeoPropSeq;

		if ( aGeoPropSet >>= aGeoPropSeq )
		{
			const rtl::OUString	sCustomShapeType( RTL_CONSTASCII_USTRINGPARAM( "non-primitive" ) );
			rtl::OUString aCustomShapeType( sCustomShapeType );

			sal_Int32 j, nGeoPropCount = aGeoPropSeq.getLength();
			for ( j = 0; j < nGeoPropCount; j++ )
			{
				const beans::PropertyValue& rGeoProp = aGeoPropSeq[ j ];
				switch( EASGet( rGeoProp.Name ) )
				{
					case EAS_Type :
					{
						rGeoProp.Value >>= aCustomShapeType;
					}
					break;
					case EAS_MirroredX :
					{
						sal_Bool bMirroredX = sal_Bool();
						if ( rGeoProp.Value >>= bMirroredX )
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_HORIZONTAL,
								bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
					}
					break;
					case EAS_MirroredY :
					{
						sal_Bool bMirroredY = sal_Bool();
						if ( rGeoProp.Value >>= bMirroredY )
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_VERTICAL,
								bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
					}
					break;
					case EAS_ViewBox :
					{
						awt::Rectangle aRect;
						if ( rGeoProp.Value >>= aRect )
						{
							SdXMLImExViewBox aViewBox( aRect.X, aRect.Y, aRect.Width, aRect.Height );
							rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() );
						}
					}
					break;
					case EAS_TextRotateAngle :
					{
						double fTextRotateAngle = 0;
						if ( rGeoProp.Value >>= fTextRotateAngle )
						{
							rUnitConverter.convertDouble( aStrBuffer, fTextRotateAngle );
							aStr = aStrBuffer.makeStringAndClear();
							rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_ROTATE_ANGLE, aStr );
						}
					}
					break;
					case EAS_Extrusion :
					{
						uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
						if ( rGeoProp.Value >>= aExtrusionPropSeq )
						{
							sal_Int32 i, nCount = aExtrusionPropSeq.getLength();
							for ( i = 0; i < nCount; i++ )
							{
								const beans::PropertyValue& rProp = aExtrusionPropSeq[ i ];
								switch( EASGet( rProp.Name ) )
								{
									case EAS_Extrusion :
									{
										sal_Bool bExtrusionOn = sal_Bool();
										if ( rProp.Value >>= bExtrusionOn )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION,
												bExtrusionOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_Brightness :
									{
										double fExtrusionBrightness = 0;
										if ( rProp.Value >>= fExtrusionBrightness )
										{
											rUnitConverter.convertDouble( aStrBuffer, fExtrusionBrightness, sal_False, MAP_RELATIVE, MAP_RELATIVE );
											aStrBuffer.append( (sal_Unicode)'%' );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_BRIGHTNESS, aStr );
										}
									}
									break;
									case EAS_Depth :
									{
										com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
										if ( rProp.Value >>= aDepthParaPair )
										{
											double fDepth = 0;
											if ( aDepthParaPair.First.Value >>= fDepth )
											{
												rExport.GetMM100UnitConverter().convertDouble( aStrBuffer, fDepth, sal_True );
												ExportParameter( aStrBuffer, aDepthParaPair.Second );
												aStr = aStrBuffer.makeStringAndClear();
												rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DEPTH, aStr );
											}
										}
									}
									break;
									case EAS_Diffusion :
									{
										double fExtrusionDiffusion = 0;
										if ( rProp.Value >>= fExtrusionDiffusion )
										{
											rUnitConverter.convertDouble( aStrBuffer, fExtrusionDiffusion, sal_False, MAP_RELATIVE, MAP_RELATIVE );
											aStrBuffer.append( (sal_Unicode)'%' );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DIFFUSION, aStr );
										}
									}
									break;
									case EAS_NumberOfLineSegments :
									{
										sal_Int32 nExtrusionNumberOfLineSegments = 0;
										if ( rProp.Value >>= nExtrusionNumberOfLineSegments )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS, rtl::OUString::valueOf( nExtrusionNumberOfLineSegments ) );
									}
									break;
									case EAS_LightFace :
									{
										sal_Bool bExtrusionLightFace = sal_Bool();
										if ( rProp.Value >>= bExtrusionLightFace )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_LIGHT_FACE,
												bExtrusionLightFace ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_FirstLightHarsh :
									{
										sal_Bool bExtrusionFirstLightHarsh = sal_Bool();
										if ( rProp.Value >>= bExtrusionFirstLightHarsh )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_HARSH,
												bExtrusionFirstLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_SecondLightHarsh :
									{
										sal_Bool bExtrusionSecondLightHarsh = sal_Bool();
										if ( rProp.Value >>= bExtrusionSecondLightHarsh )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_HARSH,
												bExtrusionSecondLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_FirstLightLevel :
									{
										double fExtrusionFirstLightLevel = 0;
										if ( rProp.Value >>= fExtrusionFirstLightLevel )
										{
											rUnitConverter.convertDouble( aStrBuffer, fExtrusionFirstLightLevel, sal_False, MAP_RELATIVE, MAP_RELATIVE );
											aStrBuffer.append( (sal_Unicode)'%' );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_LEVEL, aStr );
										}
									}
									break;
									case EAS_SecondLightLevel :
									{
										double fExtrusionSecondLightLevel = 0;
										if ( rProp.Value >>= fExtrusionSecondLightLevel )
										{
											rUnitConverter.convertDouble( aStrBuffer, fExtrusionSecondLightLevel, sal_False, MAP_RELATIVE, MAP_RELATIVE );
											aStrBuffer.append( (sal_Unicode)'%' );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_LEVEL, aStr );
										}
									}
									break;
									case EAS_FirstLightDirection :
									{
										drawing::Direction3D aExtrusionFirstLightDirection;
										if ( rProp.Value >>= aExtrusionFirstLightDirection )
										{
											::basegfx::B3DVector aVec3D( aExtrusionFirstLightDirection.DirectionX, aExtrusionFirstLightDirection.DirectionY,
												aExtrusionFirstLightDirection.DirectionZ );
											rUnitConverter.convertB3DVector( aStrBuffer, aVec3D );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_DIRECTION, aStr );
										}
									}
									break;
									case EAS_SecondLightDirection :
									{
										drawing::Direction3D aExtrusionSecondLightDirection;
										if ( rProp.Value >>= aExtrusionSecondLightDirection )
										{
											::basegfx::B3DVector aVec3D( aExtrusionSecondLightDirection.DirectionX, aExtrusionSecondLightDirection.DirectionY,
												aExtrusionSecondLightDirection.DirectionZ );
											rUnitConverter.convertB3DVector( aStrBuffer, aVec3D );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_DIRECTION, aStr );
										}
									}
									break;
									case EAS_Metal :
									{
										sal_Bool bExtrusionMetal = sal_Bool();
										if ( rProp.Value >>= bExtrusionMetal )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_METAL,
												bExtrusionMetal ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_ShadeMode :
									{
										// shadeMode
										drawing::ShadeMode eShadeMode;
										if( rProp.Value >>= eShadeMode )
										{
											if( eShadeMode == drawing::ShadeMode_FLAT )
												aStr = GetXMLToken( XML_FLAT );
											else if( eShadeMode == drawing::ShadeMode_PHONG )
												aStr = GetXMLToken( XML_PHONG );
											else if( eShadeMode == drawing::ShadeMode_SMOOTH )
												aStr = GetXMLToken( XML_GOURAUD );
											else
												aStr = GetXMLToken( XML_DRAFT );
										}
										else
										{
											// ShadeMode enum not there, write default
											aStr = GetXMLToken( XML_FLAT);
										}
										rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr );
									}
									break;
									case EAS_RotateAngle :
									{
										com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair;
										if ( rProp.Value >>= aRotateAngleParaPair )
										{
											ExportParameter( aStrBuffer, aRotateAngleParaPair.First );
											ExportParameter( aStrBuffer, aRotateAngleParaPair.Second );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_ANGLE, aStr );
										}
									}
									break;
									case EAS_RotationCenter :
									{
										drawing::Direction3D aExtrusionRotationCenter;
										if ( rProp.Value >>= aExtrusionRotationCenter )
										{
											::basegfx::B3DVector aVec3D( aExtrusionRotationCenter.DirectionX, aExtrusionRotationCenter.DirectionY,
												aExtrusionRotationCenter.DirectionZ );
											rUnitConverter.convertB3DVector( aStrBuffer, aVec3D );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_CENTER, aStr );
										}
									}
									break;
									case EAS_Shininess :
									{
										double fExtrusionShininess = 0;
										if ( rProp.Value >>= fExtrusionShininess )
										{
											rUnitConverter.convertDouble( aStrBuffer, fExtrusionShininess, sal_False, MAP_RELATIVE, MAP_RELATIVE );
											aStrBuffer.append( (sal_Unicode)'%' );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SHININESS, aStr );
										}
									}
									break;
									case EAS_Skew :
									{
										com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
										if ( rProp.Value >>= aSkewParaPair )
										{
											ExportParameter( aStrBuffer, aSkewParaPair.First );
											ExportParameter( aStrBuffer, aSkewParaPair.Second );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SKEW, aStr );
										}
									}
									break;
									case EAS_Specularity :
									{
										double fExtrusionSpecularity = 0;
										if ( rProp.Value >>= fExtrusionSpecularity )
										{
											rUnitConverter.convertDouble( aStrBuffer, fExtrusionSpecularity, sal_False, MAP_RELATIVE, MAP_RELATIVE );
											aStrBuffer.append( (sal_Unicode)'%' );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SPECULARITY, aStr );
										}
									}
									break;
									case EAS_ProjectionMode :
									{
										drawing::ProjectionMode eProjectionMode;
										if ( rProp.Value >>= eProjectionMode )
											rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_PROJECTION,
												eProjectionMode == drawing::ProjectionMode_PARALLEL ? GetXMLToken( XML_PARALLEL ) : GetXMLToken( XML_PERSPECTIVE ) );
									}
									break;
									case EAS_ViewPoint :
									{
										drawing::Position3D aExtrusionViewPoint;
										if ( rProp.Value >>= aExtrusionViewPoint )
										{
											rUnitConverter.convertPosition3D( aStrBuffer, aExtrusionViewPoint );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_VIEWPOINT, aStr );
										}
									}
									break;
									case EAS_Origin :
									{
										com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginParaPair;
										if ( rProp.Value >>= aOriginParaPair )
										{
											ExportParameter( aStrBuffer, aOriginParaPair.First );
											ExportParameter( aStrBuffer, aOriginParaPair.Second );
											aStr = aStrBuffer.makeStringAndClear();
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ORIGIN, aStr );
										}
									}
									break;
									case EAS_Color :
									{
										sal_Bool bExtrusionColor = sal_Bool();
										if ( rProp.Value >>= bExtrusionColor )
										{
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_COLOR,
												bExtrusionColor ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
										}
									}
									break;
									default:
										break;
								}
							}
						}
					}
					break;
					case EAS_TextPath :
					{
						uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
						if ( rGeoProp.Value >>= aTextPathPropSeq )
						{
							sal_Int32 i, nCount = aTextPathPropSeq.getLength();
							for ( i = 0; i < nCount; i++ )
							{
								const beans::PropertyValue& rProp = aTextPathPropSeq[ i ];
								switch( EASGet( rProp.Name ) )
								{
									case EAS_TextPath :
									{
										sal_Bool bTextPathOn = sal_Bool();
										if ( rProp.Value >>= bTextPathOn )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH,
												bTextPathOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_TextPathMode :
									{
										com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
										if ( rProp.Value >>= eTextPathMode )
										{
											switch ( eTextPathMode )
											{
												case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL: aStr = GetXMLToken( XML_NORMAL ); break;
												case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH	: aStr = GetXMLToken( XML_PATH );   break;
												case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE : aStr = GetXMLToken( XML_SHAPE );  break;
												default:
													break;
											}
											if ( aStr.getLength() )
												rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_MODE, aStr );
										}
									}
									break;
									case EAS_ScaleX :
									{
										sal_Bool bScaleX = sal_Bool();
										if ( rProp.Value >>= bScaleX )
										{
											aStr = bScaleX ? GetXMLToken( XML_SHAPE ) : GetXMLToken( XML_PATH );
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SCALE, aStr );
										}
									}
									break;
									case EAS_SameLetterHeights :
									{
										sal_Bool bSameLetterHeights = sal_Bool();
										if ( rProp.Value >>= bSameLetterHeights )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SAME_LETTER_HEIGHTS,
												bSameLetterHeights ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									default:
										break;
								}
							}
						}
					}
					break;
					case EAS_Path :
					{
						uno::Sequence< beans::PropertyValue > aPathPropSeq;
						if ( rGeoProp.Value >>= aPathPropSeq )
						{
							sal_Int32 i, nCount = aPathPropSeq.getLength();
							for ( i = 0; i < nCount; i++ )
							{
								const beans::PropertyValue& rProp = aPathPropSeq[ i ];
								switch( EASGet( rProp.Name ) )
								{
									case EAS_ExtrusionAllowed :
									{
										sal_Bool bExtrusionAllowed = sal_Bool();
										if ( rProp.Value >>= bExtrusionAllowed )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ALLOWED,
												bExtrusionAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_ConcentricGradientFillAllowed :
									{
										sal_Bool bConcentricGradientFillAllowed = sal_Bool();
										if ( rProp.Value >>= bConcentricGradientFillAllowed )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONCENTRIC_GRADIENT_FILL_ALLOWED,
												bConcentricGradientFillAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_TextPathAllowed  :
									{
										sal_Bool bTextPathAllowed = sal_Bool();
										if ( rProp.Value >>= bTextPathAllowed )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_ALLOWED,
												bTextPathAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
									}
									break;
									case EAS_GluePoints :
									{
										com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
										if ( rProp.Value >>= aGluePoints )
										{
											sal_Int32 k, nElements = aGluePoints.getLength();
											if ( nElements )
											{
												for( k = 0; k < nElements; k++ )
												{
													ExportParameter( aStrBuffer, aGluePoints[ k ].First );
													ExportParameter( aStrBuffer, aGluePoints[ k ].Second );
												}
												aStr = aStrBuffer.makeStringAndClear();
											}
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINTS, aStr );
										}
									}
									break;
									case EAS_GluePointType :
									{
										sal_Int16 nGluePointType = sal_Int16();
										if ( rProp.Value >>= nGluePointType )
										{
											switch ( nGluePointType )
											{
												case com::sun::star::drawing::EnhancedCustomShapeGluePointType::NONE     : aStr = GetXMLToken( XML_NONE );    break;
												case com::sun::star::drawing::EnhancedCustomShapeGluePointType::SEGMENTS : aStr = GetXMLToken( XML_SEGMENTS ); break;
												case com::sun::star::drawing::EnhancedCustomShapeGluePointType::RECT     : aStr = GetXMLToken( XML_RECTANGLE ); break;
											}
											if ( aStr.getLength() )
												rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINT_TYPE, aStr );
										}
									}
									break;
									case EAS_Coordinates :
									{
										bCoordinates = ( rProp.Value >>= aCoordinates );
									}
									break;
									case EAS_Segments :
									{
										rProp.Value >>= aSegments;
									}
									break;
									case EAS_StretchX :
									{
										sal_Int32 nStretchPoint = 0;
										if ( rProp.Value >>= nStretchPoint )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_X, rtl::OUString::valueOf( nStretchPoint ) );
									}
									break;
									case EAS_StretchY :
									{
										sal_Int32 nStretchPoint = 0;
										if ( rProp.Value >>= nStretchPoint )
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_Y, rtl::OUString::valueOf( nStretchPoint ) );
									}
									break;
									case EAS_TextFrames :
									{
										com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
										if ( rProp.Value >>= aPathTextFrames )
										{
											if ( (sal_uInt16)aPathTextFrames.getLength() )
											{
												sal_uInt16 k, nElements = (sal_uInt16)aPathTextFrames.getLength();
												for ( k = 0; k < nElements; k++ )
												{
													ExportParameter( aStrBuffer, aPathTextFrames[ k ].TopLeft.First );
													ExportParameter( aStrBuffer, aPathTextFrames[ k ].TopLeft.Second );
													ExportParameter( aStrBuffer, aPathTextFrames[ k ].BottomRight.First );
													ExportParameter( aStrBuffer, aPathTextFrames[ k ].BottomRight.Second );
												}
												aStr = aStrBuffer.makeStringAndClear();
											}
											rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_AREAS, aStr );
										}
									}
									break;
									default:
										break;
								}
							}
						}
					}
					break;
					case EAS_Equations :
					{
						bEquations = ( rGeoProp.Value >>= aEquations );
					}
					break;
					case EAS_Handles :
					{
						bHandles = ( rGeoProp.Value >>= aHandles );
					}
					break;
					case EAS_AdjustmentValues :
					{
						rGeoProp.Value >>= aAdjustmentValues;
					}
					break;
					default:
						break;
				}
			}	// for
			rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TYPE, aCustomShapeType );

			// adjustments
			sal_Int32 nAdjustmentValues = aAdjustmentValues.getLength();
			if ( nAdjustmentValues )
			{
				sal_Int32 i, nValue = 0;
				for ( i = 0; i < nAdjustmentValues; i++ )
				{
					if ( i )
						aStrBuffer.append( (sal_Unicode)' ' );

					const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue& rAdj = aAdjustmentValues[ i ];
					if ( rAdj.State == beans::PropertyState_DIRECT_VALUE )
					{
						if ( rAdj.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
						{
							double fValue = 0.0;
							rAdj.Value >>= fValue;
							rUnitConverter.convertDouble( aStrBuffer, fValue );
						}
						else
						{
							rAdj.Value >>= nValue;
							rUnitConverter.convertNumber( aStrBuffer, nValue );
						}
					}
					else
						rUnitConverter.convertNumber( aStrBuffer, 0 );			// this should not be, but better than setting nothing
				}
				aStr = aStrBuffer.makeStringAndClear();
				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MODIFIERS, aStr );
			}
			if ( bCoordinates )
				ImpExportEnhancedPath( rExport, aCoordinates, aSegments );
		}
	}
	SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_ENHANCED_GEOMETRY, sal_True, sal_True );
	if ( bEquations )
		ImpExportEquations( rExport, aEquations );
	if ( bHandles )
		ImpExportHandles( rExport, aHandles );
}

void XMLShapeExport::ImpExportCustomShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint )
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if ( xPropSet.is() )
	{
		rtl::OUString aStr;
		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );

		// Transformation
		ImpExportNewTrans( xPropSet, nFeatures, pRefPoint );

		if ( xPropSetInfo.is() )
		{
			const rtl::OUString	sCustomShapeEngine( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeEngine" ) );
			if ( xPropSetInfo->hasPropertyByName( sCustomShapeEngine ) )
			{
				uno::Any aEngine( xPropSet->getPropertyValue( sCustomShapeEngine ) );
				if ( ( aEngine >>= aStr ) && aStr.getLength() )
					mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ENGINE, aStr );
			}
			const rtl::OUString	sCustomShapeData( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeData" ) );
			if ( xPropSetInfo->hasPropertyByName( sCustomShapeData ) )
			{
				uno::Any aData( xPropSet->getPropertyValue( sCustomShapeData ) );
				if ( ( aData >>= aStr ) && aStr.getLength() )
					mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DATA, aStr );
			}
		}
		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
		SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, bCreateNewline, sal_True );
		ImpExportDescription( xShape ); // #i68101#
		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );
		ImpExportText( xShape );
		ImpExportEnhancedGeometry( mrExport, xPropSet );
	}
}

void XMLShapeExport::ImpExportTableShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint )
{
	uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);

	DBG_ASSERT( xPropSet.is() && xNamed.is(), "xmloff::XMLShapeExport::ImpExportTableShape(), tabe shape is not implementing needed interfaces");
	if(xPropSet.is() && xNamed.is()) try
	{
		// Transformation
		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

		sal_Bool bIsEmptyPresObj = sal_False;

		// presentation settings
		if(eShapeType == XmlShapeTypePresTableShape)
			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_TABLE) );

		const bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 );
		const bool bExportEmbedded(0 != (mrExport.getExportFlags() & EXPORT_EMBEDDED));

		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW, XML_FRAME, bCreateNewline, sal_True );

		// do not export in ODF 1.1 or older
		if( mrExport.getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
		{
			if( !bIsEmptyPresObj )
			{
				uno::Reference< container::XNamed > xTemplate( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TableTemplate" ) ) ), uno::UNO_QUERY );
				if( xTemplate.is() )
				{
					const OUString sTemplate( xTemplate->getName() );
					if( sTemplate.getLength() )
					{
						mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TEMPLATE_NAME, sTemplate );

						for( const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0]; pEntry->msApiName; pEntry++ )
						{
							try
							{
								sal_Bool bBool = sal_False;
								const OUString sAPIPropertyName( OUString(pEntry->msApiName, pEntry->nApiNameLength, RTL_TEXTENCODING_ASCII_US ) );

								xPropSet->getPropertyValue( sAPIPropertyName ) >>= bBool;
								if( bBool )
									mrExport.AddAttribute(pEntry->mnNameSpace, pEntry->meXMLName, XML_TRUE );
							}
							catch( uno::Exception& )
							{
								DBG_ERROR("XMLShapeExport::ImpExportTableShape(), exception caught!");
							}
						}
					}
				}


				uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( msModel ), uno::UNO_QUERY_THROW );
				GetShapeTableExport()->exportTable( xRange );
			}
		}

		if( !bIsEmptyPresObj )
		{
			uno::Reference< graphic::XGraphic > xGraphic( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ReplacementGraphic" ) ) ), uno::UNO_QUERY );
			if( xGraphic.is() ) try
			{	
				Reference< lang::XMultiServiceFactory > xSM( GetExport().getServiceFactory(), UNO_QUERY_THROW );

				uno::Reference< embed::XStorage > xPictureStorage;
				uno::Reference< embed::XStorage > xStorage;
				uno::Reference< io::XStream > xPictureStream;

				OUString sPictureName;
				if( bExportEmbedded )
				{
					xPictureStream.set( xSM->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.MemoryStream" ) ) ), UNO_QUERY_THROW );					
				}
				else
				{
					xStorage.set( GetExport().GetTargetStorage(), UNO_QUERY_THROW );

					xPictureStorage.set( xStorage->openStorageElement( OUString( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ), ::embed::ElementModes::READWRITE ), uno::UNO_QUERY_THROW );
					const OUString sPrefix( RTL_CONSTASCII_USTRINGPARAM("TablePreview") );
					const OUString sSuffix( RTL_CONSTASCII_USTRINGPARAM(".svm") );

					sal_Int32 nIndex = 0;
					do
					{
						sPictureName = sPrefix;
						sPictureName += OUString::valueOf( ++nIndex );
						sPictureName += sSuffix;
					}
					while( xPictureStorage->hasByName( sPictureName ) );

					xPictureStream.set( xPictureStorage->openStreamElement( sPictureName, ::embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
				}

				Reference< graphic::XGraphicProvider > xProvider( xSM->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW );
				Sequence< beans::PropertyValue > aArgs( 2 );
				aArgs[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) );
				aArgs[ 0 ].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "image/x-vclgraphic" ) );
				aArgs[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
				aArgs[ 1 ].Value <<= xPictureStream->getOutputStream();
				xProvider->storeGraphic( xGraphic, aArgs );

				if( xPictureStorage.is() )
				{
					Reference< embed::XTransactedObject > xTrans( xPictureStorage, UNO_QUERY );
					if( xTrans.is() )
						xTrans->commit();
				}

				if( !bExportEmbedded )
				{
					OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "Pictures/" ) );
					sURL += sPictureName;
					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 );
					mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
				}

				SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, sal_False, sal_True );

				if( bExportEmbedded )
				{
					Reference< XSeekableInputStream > xSeekable( xPictureStream, UNO_QUERY_THROW );
					xSeekable->seek(0);

					XMLBase64Export aBase64Exp( GetExport() );
					aBase64Exp.exportOfficeBinaryDataElement( Reference < XInputStream >( xPictureStream, UNO_QUERY_THROW ) );
				}
			}
			catch( uno::Exception& )
			{
				DBG_ERROR("xmloff::XMLShapeExport::ImpExportTableShape(), exception caught!");
			}
		}

		ImpExportEvents( xShape );
		ImpExportGluePoints( xShape );
		ImpExportDescription( xShape ); // #i68101#
	}
	catch( uno::Exception& )
	{
		DBG_ERROR( "xmloff::XMLShapeExport::ImpExportTableShape(), exception caught!" );
	}
}
